00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00076
00077
00078 #include <stdint.h>
00079 #include <stdlib.h>
00080 #include <dirent.h>
00081 #include <fstream>
00082 #include <iostream>
00083 #include <string>
00084 #include <map>
00085 #include <sstream>
00086 #include <errno.h>
00087 #include "Version.hxx"
00088 #include "UocInfo.hxx"
00089 #include "AST.hxx"
00090 #include "Environment.hxx"
00091 #include "inter-pass.hxx"
00092 #include "backend.hxx"
00093
00094 using namespace std;
00095 using namespace boost;
00096 using namespace sherpa;
00097
00100 static shared_ptr<AST>
00101 getTypeAst(shared_ptr<AST> fld)
00102 {
00103 switch(fld->astType) {
00104 case at_field:
00105 case at_methdecl:
00106 return fld->child(1);
00107
00108 case at_fill:
00109 return fld->child(0);
00110
00111 default:
00112 assert(false);
00113 return GC_NULL;
00114 }
00115 }
00116
00121 static size_t
00122 bitOffset(shared_ptr<AST> leg, size_t n)
00123 {
00124 size_t off = 0;
00125 for (size_t c=1; c < n; c++) {
00126 shared_ptr<AST> fld = leg->child(c);
00127 shared_ptr<AST> fldType = getTypeAst(fld);
00128 if (fldType->astType == at_bitfieldType)
00129 off += fldType->field_bits;
00130 else
00131 off += fldType->symType->size();
00132 }
00133
00134 return off;
00135 }
00136
00142 static bool
00143 TypesAgree(shared_ptr<AST> fld1, shared_ptr<AST> fld2)
00144 {
00145 shared_ptr<AST> fT1 = getTypeAst(fld1);
00146 shared_ptr<AST> fT2 = getTypeAst(fld2);
00147
00148 if ((fT1->symType->strictlyEquals(fT2->symType)) &&
00149 (fT1->field_bits == fT2->field_bits))
00150 return true;
00151 else
00152 return false;
00153 }
00154
00156 bool
00157 reprCheck(std::ostream& errStream, shared_ptr<AST> ast)
00158 {
00159 bool errFree = true;
00160 switch(ast->astType) {
00161 case at_defrepr:
00162 case at_declrepr:
00163 case at_reprctrs:
00164 case at_reprctr:
00165 assert(false);
00166 break;
00167
00168 case at_defunion:
00169 {
00170 if ((ast->flags & UNION_IS_REPR) == 0)
00171 break;
00172
00173 shared_ptr<AST> ctrs = ast->child(4);
00174
00175
00176
00177 for (size_t c=0; c < ctrs->children.size(); c++) {
00178 shared_ptr<AST> ctrc = ctrs->child(c);
00179
00180 for (size_t i=1; i < ctrc->children.size(); i++) {
00181 shared_ptr<AST> fldi = ctrc->child(i);
00182
00183 if (fldi->astType == at_field)
00184 if (fldi->flags & FLD_IS_DISCM)
00185 if (!fldi->symType->isInteger()) {
00186 errStream << fldi->loc << ": "
00187 << " The discriminating field "
00188 << fldi->child(0)->s
00189 << " has a non-integer/bitfield type."
00190 << std::endl;
00191 errFree = false;
00192 }
00193 }
00194 }
00195
00196
00197
00198 for (size_t c=0; c < ctrs->children.size(); c++) {
00199 shared_ptr<AST> ctrc = ctrs->child(c);
00200
00201 for (size_t i=1; i < ctrc->children.size(); i++) {
00202 shared_ptr<AST> fldi = ctrc->child(i);
00203 if (fldi->astType != at_field)
00204 continue;
00205
00206 size_t offc = bitOffset(ctrc, i);
00207 for (size_t d=c+1; d < ctrs->children.size(); d++) {
00208 shared_ptr<AST> ctrd = ctrs->child(d);
00209
00210 for (size_t j=1; j < ctrd->children.size(); j++) {
00211 shared_ptr<AST> fldj = ctrd->child(j);
00212 if (fldj->astType != at_field)
00213 continue;
00214
00215 if (fldi->child(0)->s == fldj->child(0)->s) {
00216 if (offc != bitOffset(ctrd, j)) {
00217 errStream << ctrd->loc << ": "
00218 << " The constructors "
00219 << ctrc->child(0)->s << " and "
00220 << ctrd->child(0)->s
00221 << " don't agree on the bit-offset "
00222 << " for field " << fldi->child(0)->s
00223 << std::endl;
00224 errFree = false;
00225 }
00226
00227 if (!TypesAgree(fldi, fldj)) {
00228 errStream << ctrd->loc << ": "
00229 << " The constructors "
00230 << ctrc->child(0)->s << " and "
00231 << ctrd->child(0)->s
00232 << " don't agree on types "
00233 << " for field " << fldi->child(0)->s
00234 << std::endl;
00235 errFree = false;
00236 }
00237 }
00238 }
00239 }
00240 }
00241 }
00242
00243
00244 for (size_t c=0; c < ctrs->children.size(); c++) {
00245 shared_ptr<AST> ctrc = ctrs->child(c);
00246
00247 typedef map<string, size_t> WhenMap;
00248 WhenMap when;
00249
00250 for (size_t i=1; i < ctrc->children.size(); i++) {
00251 shared_ptr<AST> fldi = ctrc->child(i);
00252 if (fldi->flags & FLD_IS_DISCM) {
00253 assert(fldi->astType == at_field);
00254
00255 when[fldi->child(0)->s] = fldi->unin_discm;
00256 }
00257 }
00258
00259 for (size_t d=c+1; d < ctrs->children.size(); d++) {
00260 shared_ptr<AST> ctrd = ctrs->child(d);
00261 bool differ=false;
00262
00263 for (size_t j=1; (!differ) && (j < ctrd->children.size()); j++) {
00264 shared_ptr<AST> fldj = ctrd->child(j);
00265
00266 if (fldj->flags & FLD_IS_DISCM) {
00267 assert(fldj->astType == at_field);
00268
00269 WhenMap::iterator itr_k = when.find(fldj->child(0)->s);
00270 if (itr_k == when.end())
00271 continue;
00272
00273 if (itr_k->second != fldj->unin_discm) {
00274 differ=true;
00275 break;
00276 }
00277 }
00278 }
00279
00280 if (!differ) {
00281 errStream << ctrc->loc << ": "
00282 << "Ambiguous defrepr constructors: "
00283 << ctrc->child(0)->s << " and "
00284 << ctrd->child(0)->s << ". Ambiguous case is: "
00285 << std::endl;
00286
00287 for (WhenMap::iterator itr_k = when.begin();
00288 itr_k != when.end(); ++itr_k) {
00289 if (itr_k != when.begin())
00290 errStream << ", ";
00291 errStream << itr_k->first << " = " << itr_k->second;
00292 }
00293
00294 errStream << "." << std::endl;
00295 errFree = false;
00296 }
00297 }
00298 }
00299 }
00300
00301 default:
00302 {
00303
00304 for (size_t c=0; c < ast->children.size(); c++)
00305 CHKERR(errFree, reprCheck(errStream, ast->child(c)));
00306 break;
00307 }
00308 }
00309
00310 return errFree;
00311 }
00312
00313 bool
00314 UocInfo::fe_reprCheck(std::ostream& errStream,
00315 bool init, unsigned long flags)
00316 {
00317 bool errFree = reprCheck(errStream, uocAst);
00318 return errFree;
00319 }
00320