00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00014 
00015 
00016 #include "RangeChecker.h"
00017 #include "TypeCheck.h"
00018 #include "comma/ast/AggExpr.h"
00019 #include "comma/ast/AttribDecl.h"
00020 #include "comma/ast/AttribExpr.h"
00021 #include "comma/ast/DiagPrint.h"
00022 
00023 #include "llvm/ADT/SetVector.h"
00024 #include "llvm/ADT/STLExtras.h"
00025 
00026 #include <algorithm>
00027 
00028 using namespace comma;
00029 using llvm::dyn_cast;
00030 using llvm::cast;
00031 using llvm::isa;
00032 
00033 namespace {
00034 
00035 
00036 
00037 
00042 class AggCheckerBase {
00043 
00044 protected:
00045     AggCheckerBase(TypeCheck &TC) : TC(TC) { }
00046 
00047     TypeCheck &TC;              
00048 
00050     DiagnosticStream &report(Location loc, diag::Kind kind);
00051 
00053     SourceLocation getSourceLoc(Location loc);
00054 };
00055 
00056 
00057 
00058 
00063 class ArrayAggChecker : private AggCheckerBase {
00064 
00065 public:
00066     ArrayAggChecker(TypeCheck &TC)
00067         : AggCheckerBase(TC), refinedIndexType(0) { }
00068 
00072     Expr *resolveAggregateExpr(AggregateExpr *agg, ArrayType *context);
00073 
00074 private:
00077     DiscreteType *refinedIndexType;
00078 
00083     std::vector<ComponentKey*> keyVec;
00084 
00087     bool ensureAggregateStructure(AggregateExpr *agg);
00088 
00091     bool convertAggregateIdentifiers(AggregateExpr *agg);
00092 
00095     Expr *resolvePositionalAggExpr(AggregateExpr *agg, ArrayType *context);
00096 
00099     Expr *resolveKeyedAggExpr(AggregateExpr *agg, ArrayType *context);
00100 
00113     bool checkArrayComponentKeys(ComponentKeyList *KL, DiscreteType *indexTy,
00114                                  Type *componentTy);
00115 
00120     bool checkSinglyKeyedAgg(AggregateExpr *agg, ArrayType *contextTy);
00121 
00126     bool checkMultiplyKeyedAgg(AggregateExpr *agg, ArrayType *contextTy);
00127 
00131     bool ensureStaticKeys(AggregateExpr *agg);
00132 
00147     bool ensureDistinctKeys(ArrayType *contextTy, bool hasOthers);
00148 
00156     bool ensureDistinctKeys(ComponentKey *X, ComponentKey *Y,
00157                             bool requireContinuity, bool isSigned);
00158 
00164     bool checkOthers(AggregateExpr *agg, ArrayType *context);
00165 };
00166 
00167 
00168 
00169 
00173 class RecordAggChecker : private AggCheckerBase {
00174 
00175 public:
00176     RecordAggChecker(TypeCheck &TC)
00177         : AggCheckerBase(TC), ContextTy(0) { }
00178 
00183     Expr *resolveAggregateExpr(AggregateExpr *agg, RecordType *context);
00184 
00185 private:
00186     RecordType *ContextTy;      
00187     RecordDecl *ContextDecl;    
00188 
00189     
00190     llvm::SetVector<ComponentDecl*> ComponentVec;
00191 
00194     bool checkAggregateSize(AggregateExpr *agg);
00195 
00204     bool ensureAggregateStructure(AggregateExpr *agg);
00205 
00210     bool checkPositionalComponents(AggregateExpr *agg);
00211 
00213     bool checkKeyedComponents(AggregateExpr *agg);
00214 
00216     bool checkOthersComponents(AggregateExpr *agg);
00217 
00223     bool checkKeyConsistency(AggregateExpr *agg);
00224 
00229     bool checkKeyTypes(AggregateExpr *expr);
00230 };
00231 
00234 void getVisibleEnumerations(Resolver &resolver,
00235                             llvm::SmallVectorImpl<EnumerationDecl*> &enums)
00236 {
00237     typedef llvm::SmallVector<SubroutineDecl*, 8> RoutineBuff;
00238     RoutineBuff routines;
00239 
00240     resolver.getVisibleSubroutines(routines);
00241 
00242     RoutineBuff::iterator I = routines.begin();
00243     RoutineBuff::iterator E = routines.end();
00244     for ( ; I != E; ++I) {
00245         EnumLiteral *lit = cast<EnumLiteral>(*I);
00246         enums.push_back(lit->getDeclRegion());
00247     }
00248 }
00249 
00252 void intersectComponentTypes(StringLiteral *string,
00253                              llvm::SmallVectorImpl<EnumerationDecl*> &enums)
00254 {
00255     typedef StringLiteral::component_iterator iterator;
00256     iterator I = string->begin_component_types();
00257     while (I != string->end_component_types()) {
00258         EnumerationDecl *decl = *I;
00259         ++I;
00260         if (std::find(enums.begin(), enums.end(), decl) == enums.end())
00261             string->removeComponentType(decl);
00262     }
00263 }
00264 
00265 } 
00266 
00267 
00268 
00269 
00270 DiagnosticStream &AggCheckerBase::report(Location loc, diag::Kind kind)
00271 {
00272     return TC.getDiagnostic().report(getSourceLoc(loc), kind);
00273 }
00274 
00275 SourceLocation AggCheckerBase::getSourceLoc(Location loc)
00276 {
00277     return TC.getAstResource().getTextProvider().getSourceLocation(loc);
00278 }
00279 
00280 
00281 
00282 
00283 bool ArrayAggChecker::ensureAggregateStructure(AggregateExpr *agg)
00284 {
00285     
00286     assert(!agg->empty() && "Unexpected empty aggregate expression!");
00287 
00288     
00289     
00290     if (agg->isPurelyPositional() || agg->isPurelyKeyed())
00291         return true;
00292 
00293     report(agg->getLocation(), diag::MIXED_ARRAY_AGGREGATE);
00294     return false;
00295 }
00296 
00297 bool ArrayAggChecker::convertAggregateIdentifiers(AggregateExpr *agg)
00298 {
00299     
00300     
00301     bool allOK = true;
00302     typedef AggregateExpr::key_iterator iterator;
00303     iterator I = agg->key_begin();
00304     iterator E = agg->key_end();
00305     for ( ; I != E; ++I) {
00306         ComponentKey *key = *I;
00307         if (!key->denotesIdentifier())
00308             continue;
00309 
00310         Identifier *id = key->getAsIdentifier();
00311         Ast *rep = TC.checkDirectName(id->getIdInfo(), id->getLocation(),
00312                                        false);
00313         if (!rep) {
00314             allOK = false;
00315             continue;
00316         }
00317 
00318         
00319         
00320         
00321         if (TypeRef *ref = dyn_cast<TypeRef>(rep)) {
00322             TypeDecl *decl = ref->getTypeDecl();
00323             if (!decl || !decl->getType()->isDiscreteType()) {
00324                 report(ref->getLocation(), diag::EXPECTED_DISCRETE_SUBTYPE);
00325                 allOK = false;
00326             }
00327             else
00328                 key->setKey(ref);
00329         }
00330         else if (Expr *expr = TC.ensureExpr(rep))
00331             key->setKey(expr);
00332         else
00333             allOK = false;
00334     }
00335     return allOK;
00336 }
00337 
00338 Expr *ArrayAggChecker::resolveAggregateExpr(AggregateExpr *agg,
00339                                             ArrayType *context)
00340 {
00341     
00342     
00343     if (agg->hasResolvedType()) {
00344         if (!TC.covers(agg->getType(), context)) {
00345             report(agg->getLocation(), diag::INCOMPATIBLE_TYPES);
00346             return 0;
00347         }
00348         else
00349             return agg;
00350     }
00351 
00352     
00353     if (!ensureAggregateStructure(agg))
00354         return 0;
00355 
00356     
00357     
00358     if (!convertAggregateIdentifiers(agg))
00359         return 0;
00360 
00361     
00362     
00363     assert(context->isVector() && "Multidimensional arrays not supported yet!");
00364 
00365     if (agg->isPurelyPositional())
00366         return resolvePositionalAggExpr(agg, context);
00367     if (agg->isPurelyKeyed())
00368         return resolveKeyedAggExpr(agg, context);
00369     assert(false && "Invalid aggregate composition!");
00370     return 0;
00371 }
00372 
00373 Expr *ArrayAggChecker::resolvePositionalAggExpr(AggregateExpr *agg,
00374                                                 ArrayType *context)
00375 {
00376     assert(agg->isPurelyPositional());
00377 
00378     Type *componentType = context->getComponentType();
00379 
00380     
00381     
00382     typedef AggregateExpr::pos_iterator iterator;
00383     iterator I = agg->pos_begin();
00384     iterator E = agg->pos_end();
00385     bool allOK = true;
00386     for ( ; I != E; ++I) {
00387         if (Expr *component = TC.checkExprInContext(*I, componentType))
00388             *I = component;
00389         else
00390             allOK = false;
00391     }
00392 
00393     if (!allOK || !checkOthers(agg, context))
00394         return 0;
00395 
00396     unsigned numComponents = agg->numComponents();
00397 
00398     
00399     
00400     if (context->isStaticallyConstrained()) {
00401         DiscreteType *idxTy = context->getIndexType(0);
00402         Range *range = idxTy->getConstraint();
00403         uint64_t length = range->length();
00404 
00405         if (length < numComponents) {
00406             report(agg->getLocation(), diag::TOO_MANY_ELEMENTS_FOR_TYPE)
00407                 << context->getIdInfo();
00408             return 0;
00409         }
00410 
00411         if (length > numComponents && !agg->hasOthers()) {
00412             report(agg->getLocation(), diag::TOO_FEW_ELEMENTS_FOR_TYPE)
00413                 << context->getIdInfo();
00414             return 0;
00415         }
00416 
00417         
00418         agg->setType(context);
00419         return agg;
00420     }
00421 
00422     
00423     
00424     if (context->isConstrained()) {
00425         ArrayType *unconstrainedTy;
00426         unconstrainedTy = TC.getAstResource().createArraySubtype(0, context);
00427         agg->setType(unconstrainedTy);
00428         return new ConversionExpr(agg, context);
00429     }
00430 
00431     
00432     
00433     
00434     DiscreteType *idxTy = context->getIndexType(0);
00435     ValAD *attrib = idxTy->getValAttribute();
00436 
00437     
00438     
00439     
00440     unsigned bits = 32 - llvm::CountLeadingZeros_32(numComponents) + 1;
00441     llvm::APInt L(bits, numComponents - 1);
00442     Expr *arg = new IntegerLiteral(L, 0);
00443 
00444     
00445     FunctionCallExpr *upper = new FunctionCallExpr(attrib, 0, &arg, 1, 0, 0);
00446 
00447     
00448     FirstAE *lower = new FirstAE(idxTy, 0);
00449 
00450     
00451     assert(TC.checkExprInContext(lower, idxTy) && "Invalid implicit expr!");
00452     assert(TC.checkExprInContext(upper, idxTy) && "Invalid implicit expr!");
00453 
00454     
00455     DiscreteType *newIdxTy = TC.getAstResource().createDiscreteSubtype
00456         (idxTy, lower, upper);
00457 
00458     
00459     ArrayType *newArrTy = TC.getAstResource().createArraySubtype
00460         (context->getIdInfo(), context, &newIdxTy);
00461 
00462     agg->setType(newArrTy);
00463     return agg;
00464 }
00465 
00466 bool ArrayAggChecker::checkSinglyKeyedAgg(AggregateExpr *agg,
00467                                           ArrayType *contextTy)
00468 {
00469     
00470     
00471     
00472     
00473     if (!contextTy->isConstrained()) {
00474         DiscreteType *indexTy = contextTy->getIndexType(0);
00475         AstResource &resource = TC.getAstResource();
00476         Expr *lower = (*agg->key_begin())->getLowerExpr();
00477         Expr *upper = (*agg->key_begin())->getUpperExpr();
00478         refinedIndexType = resource.createDiscreteSubtype(
00479             indexTy, lower, upper);
00480     }
00481     return true;
00482 }
00483 
00484 bool ArrayAggChecker::checkMultiplyKeyedAgg(AggregateExpr *agg,
00485                                             ArrayType *contextTy)
00486 {
00487     bool allOK;
00488 
00489     
00490     
00491     allOK = ensureStaticKeys(agg);
00492 
00493     
00494     allOK = allOK && ensureDistinctKeys(contextTy, agg->hasOthers());
00495 
00496     
00497     return checkOthers(agg, contextTy) && allOK;
00498 }
00499 
00500 Expr *ArrayAggChecker::resolveKeyedAggExpr(AggregateExpr *agg,
00501                                            ArrayType *context)
00502 {
00503     Type *componentTy = context->getComponentType();
00504     DiscreteType *indexTy = context->getIndexType(0);
00505 
00506     
00507     bool allOK = true;
00508     for (AggregateExpr::kl_iterator I = agg->kl_begin(), E = agg->kl_end();
00509          I != E; ++I)
00510         allOK = checkArrayComponentKeys(*I, indexTy, componentTy) && allOK;
00511     if (!allOK) return 0;
00512 
00513     
00514     unsigned numKeys = agg->numKeys();
00515 
00516     
00517     
00518     
00519     if (numKeys == 1 && !agg->hasOthers())
00520         allOK = checkSinglyKeyedAgg(agg, context);
00521     else
00522         allOK = checkMultiplyKeyedAgg(agg, context);
00523     if (!allOK) return 0;
00524 
00525     
00526     
00527     if (refinedIndexType) {
00528         AstResource &resource = TC.getAstResource();
00529         context = resource.createArraySubtype(context->getIdInfo(), context,
00530                                               &refinedIndexType);
00531     }
00532 
00533     
00534     agg->setType(context);
00535     return agg;
00536 }
00537 
00538 bool ArrayAggChecker::checkArrayComponentKeys(ComponentKeyList *KL,
00539                                               DiscreteType *indexTy,
00540                                               Type *componentTy)
00541 {
00542     typedef ComponentKeyList::iterator iterator;
00543     RangeChecker rangeCheck(TC);
00544 
00545     
00546     for (unsigned i = 0; i < KL->numKeys(); ++i) {
00547         if (Range *range = KL->resolveKey<Range>(i)) {
00548             if (!rangeCheck.resolveRange(range, indexTy))
00549                 return false;
00550         }
00551         else if (Expr *expr = KL->resolveKey<Expr>(i)) {
00552             if ((expr = TC.checkExprInContext(expr, indexTy)))
00553                 KL->setKey(i, expr);
00554             else
00555                 return false;
00556         }
00557         else {
00558             assert(false && "Key type not yet supported!");
00559             return false;
00560         }
00561     }
00562 
00563     
00564     if (Expr *expr = TC.checkExprInContext(KL->getExpr(), componentTy)) {
00565         KL->setExpr(expr);
00566         return true;
00567     }
00568     else
00569         return false;
00570 }
00571 
00572 bool ArrayAggChecker::ensureStaticKeys(AggregateExpr *agg)
00573 {
00574     
00575     
00576     typedef AggregateExpr::key_iterator iterator;
00577     iterator I = agg->key_begin();
00578     iterator E = agg->key_end();
00579     for ( ; I != E; ++I) {
00580         ComponentKey *key = *I;
00581         Location loc = key->getLocation();
00582         if (Range *range = key->getAsRange()) {
00583             if (!range->isStatic()) {
00584                 report(loc, diag::DYNAMIC_CHOICE_NOT_UNIQUE);
00585                 return false;
00586             }
00587             else if (range->isNull()) {
00588                 report(loc, diag::NULL_CHOICE_NOT_UNIQUE);
00589                 return false;
00590             }
00591         }
00592         else if (Expr *expr = key->getAsExpr()) {
00593             if (!expr->isStaticDiscreteExpr()) {
00594                 report(loc, diag::NON_STATIC_EXPRESSION);
00595                 return false;
00596             }
00597         }
00598         else {
00599             assert(false && "Key not yet supported!");
00600             return false;
00601         }
00602         keyVec.push_back(key);
00603     }
00604     return true;
00605 }
00606 
00607 bool ArrayAggChecker::ensureDistinctKeys(ComponentKey *X, ComponentKey *Y,
00608                                          bool requireContinuity, bool isSigned)
00609 {
00610     llvm::APInt xValue;
00611     llvm::APInt yValue;
00612     X->getUpperValue(xValue);
00613     Y->getLowerValue(yValue);
00614 
00615     bool overlapping;
00616     bool continuous;
00617     if (isSigned) {
00618         int64_t x = xValue.getSExtValue();
00619         int64_t y = yValue.getSExtValue();
00620         overlapping = y <= x;
00621         continuous = x == y - 1;
00622     }
00623     else {
00624         uint64_t x = xValue.getZExtValue();
00625         uint64_t y = yValue.getZExtValue();
00626         overlapping = y <= x;
00627         continuous = x == y - 1;
00628     }
00629 
00630     
00631     if (overlapping) {
00632         report(X->getLocation(), diag::DUPLICATED_AGGREGATE_COMPONENT)
00633             << getSourceLoc(Y->getLocation());
00634         return false;
00635     }
00636 
00637     
00638     if (requireContinuity && !continuous) {
00639         report(X->getLocation(), diag::DISCONTINUOUS_CHOICE)
00640             << getSourceLoc(Y->getLocation());
00641         return false;
00642     }
00643 
00644     return true;
00645 }
00646 
00647 bool ArrayAggChecker::ensureDistinctKeys(ArrayType *contextTy, bool hasOthers)
00648 {
00649     DiscreteType *indexTy = contextTy->getIndexType(0);
00650     bool isSigned = indexTy->isSigned();
00651     bool requireContinuity = !hasOthers;
00652 
00653     if (isSigned)
00654         std::sort(keyVec.begin(), keyVec.end(), ComponentKey::compareKeysS);
00655     else
00656         std::sort(keyVec.begin(), keyVec.end(), ComponentKey::compareKeysU);
00657 
00658     std::vector<ComponentKey*>::iterator I = keyVec.begin();
00659     std::vector<ComponentKey*>::iterator E = keyVec.end();
00660 
00661     if (I == E)
00662         return true;
00663 
00664     ComponentKey *prev = *I;
00665     while (++I != E) {
00666         ComponentKey *next = *I;
00667         if (!ensureDistinctKeys(prev, next, requireContinuity, isSigned))
00668             return false;
00669         prev = next;
00670     }
00671 
00672     
00673     
00674     
00675     
00676     
00677     if (!contextTy->isConstrained()) {
00678         AstResource &resource = TC.getAstResource();
00679         Expr *lower = keyVec.front()->getLowerExpr();
00680         Expr *upper = keyVec.back()->getUpperExpr();
00681         refinedIndexType = resource.createDiscreteSubtype(
00682             indexTy, lower, upper);
00683     }
00684     return true;
00685 }
00686 
00687 bool ArrayAggChecker::checkOthers(AggregateExpr *agg, ArrayType *context)
00688 {
00689     
00690     
00691     if (Expr *expr = agg->getOthersExpr()) {
00692         if (!(expr = TC.checkExprInContext(expr, context->getComponentType())))
00693             return false;
00694         else
00695             agg->setOthersExpr(expr);
00696     }
00697 
00698     
00699     
00700     if (!context->isConstrained() && agg->hasOthers()) {
00701         report(agg->getOthersLoc(), diag::OTHERS_IN_UNCONSTRAINED_CONTEXT);
00702         return false;
00703     }
00704 
00705     return true;
00706 }
00707 
00708 
00709 
00710 
00711 Expr *RecordAggChecker::resolveAggregateExpr(AggregateExpr *agg,
00712                                              RecordType *context)
00713 {
00714     ContextTy = context;
00715     ContextDecl = context->getDefiningDecl();
00716 
00717     
00718     
00719     if (agg->hasResolvedType()) {
00720         if (!TC.covers(agg->getType(), context)) {
00721             report(agg->getLocation(), diag::INCOMPATIBLE_TYPES);
00722             return 0;
00723         }
00724         else
00725             return agg;
00726     }
00727 
00728     
00729     if (!ensureAggregateStructure(agg))
00730         return 0;
00731 
00732     
00733     if (!checkAggregateSize(agg))
00734         return 0;
00735 
00736     
00737     if (!checkPositionalComponents(agg))
00738         return 0;
00739 
00740     
00741     if (!checkKeyedComponents(agg))
00742         return 0;
00743 
00744     
00745     if (!checkOthersComponents(agg))
00746         return 0;
00747 
00748     agg->setType(context);
00749     return agg;
00750 }
00751 
00752 bool RecordAggChecker::ensureAggregateStructure(AggregateExpr *agg)
00753 {
00754     
00755     
00756     typedef AggregateExpr::key_iterator iterator;
00757     iterator I = agg->key_begin();
00758     iterator E = agg->key_end();
00759     for ( ; I != E; ++I) {
00760         ComponentKey *key = *I;
00761         if (!key->denotesIdentifier()) {
00762             report(key->getLocation(), diag::INVALID_RECORD_SELECTOR)
00763                 << diag::PrintType(ContextTy);
00764             return false;
00765         }
00766     }
00767     return true;
00768 }
00769 
00770 bool RecordAggChecker::checkAggregateSize(AggregateExpr *agg)
00771 {
00772     
00773     
00774     
00775     
00776     unsigned numPositional = agg->numPositionalComponents();
00777     unsigned numKeys = agg->numKeys();
00778     unsigned numComponents = numPositional + numKeys;
00779     if (numComponents > ContextTy->numComponents()) {
00780         report(agg->getLocation(), diag::TOO_MANY_ELEMENTS_FOR_TYPE)
00781             << diag::PrintType(ContextTy);
00782         return false;
00783     }
00784     if (!agg->hasOthers() && numComponents < ContextTy->numComponents()) {
00785         report(agg->getLocation(), diag::TOO_FEW_ELEMENTS_FOR_TYPE)
00786             << diag::PrintType(ContextTy);
00787         return false;
00788     }
00789     return true;
00790 }
00791 
00792 bool RecordAggChecker::checkPositionalComponents(AggregateExpr *agg)
00793 {
00794     
00795     
00796     if (agg->numPositionalComponents() > ContextTy->numComponents()) {
00797         report(agg->getLocation(), diag::TOO_MANY_ELEMENTS_FOR_TYPE)
00798             << diag::PrintType(ContextTy);
00799         return false;
00800     }
00801 
00802     
00803     
00804     
00805     typedef AggregateExpr::pos_iterator iterator;
00806     iterator I = agg->pos_begin();
00807     iterator E = agg->pos_end();
00808     bool allOK = true;
00809     for (unsigned idx = 0; I != E; ++I, ++idx) {
00810         Expr *expr = *I;
00811         ComponentDecl *decl = ContextDecl->getComponent(idx);
00812         Type *expectedTy = decl->getType();
00813         if ((expr = TC.checkExprInContext(expr, expectedTy))) {
00814             *I = expr;
00815             ComponentVec.insert(decl);
00816         }
00817         else
00818             allOK = false;
00819     }
00820     return allOK;
00821 }
00822 
00823 bool RecordAggChecker::checkKeyConsistency(AggregateExpr *agg)
00824 {
00825     
00826     
00827     
00828     typedef AggregateExpr::key_iterator key_iterator;
00829     unsigned numPositional = agg->numPositionalComponents();
00830     key_iterator I = agg->key_begin();
00831     key_iterator E = agg->key_end();
00832     for (unsigned idx = numPositional; I != E; ++I, ++idx) {
00833         ComponentKey *key = *I;
00834         Location loc = key->getLocation();
00835         Identifier *id = key->getAsIdentifier();
00836         IdentifierInfo *name = id->getIdInfo();
00837         ComponentDecl *component = ContextDecl->getComponent(name);
00838 
00839         
00840         if (!component) {
00841             report(loc, diag::INVALID_RECORD_SELECTOR)
00842                 << diag::PrintType(ContextTy);
00843             return false;
00844         }
00845 
00846         
00847         
00848         if (!ComponentVec.insert(component)) {
00849             if (component->getIndex() < numPositional)
00850                 report(loc, diag::COMPONENT_COVERED_POSITIONALLY);
00851             else {
00852                 
00853                 
00854                 Location conflictLoc;
00855                 for (key_iterator P = agg->key_begin(); P != I; ++P) {
00856                     ComponentKey *conflict = *P;
00857                     if (conflict->getAsComponent() == component)
00858                         conflictLoc = conflict->getLocation();
00859                 }
00860                 assert(conflictLoc.isValid() && "Could not resolve conflict!");
00861                 report(loc, diag::DUPLICATED_AGGREGATE_COMPONENT)
00862                     << getSourceLoc(conflictLoc);
00863             }
00864             return false;
00865         }
00866 
00867         
00868         
00869         key->setKey(component);
00870         delete id;
00871     }
00872     return true;
00873 }
00874 
00875 bool RecordAggChecker::checkKeyTypes(AggregateExpr *agg)
00876 {
00877     
00878     
00879     typedef AggregateExpr::kl_iterator kl_iterator;
00880     kl_iterator I = agg->kl_begin();
00881     kl_iterator E = agg->kl_end();
00882     for ( ; I != E; ++I) {
00883         ComponentKeyList *KL = *I;
00884 
00885         
00886         
00887         Type *listType = KL->resolveKey<ComponentDecl>(0)->getType();
00888         for (unsigned i = 1; i < KL->numKeys(); ++i) {
00889             ComponentKey *nextKey = KL->getKey(i);
00890             Type *nextType = nextKey->getAsComponent()->getType();
00891             if (listType != nextType) {
00892                 report(nextKey->getLocation(),
00893                        diag::INCONSISTENT_RECORD_COMPONENT_SELECTORS);
00894                 return false;
00895             }
00896         }
00897 
00898         
00899         
00900         if (Expr *expr = TC.checkExprInContext(KL->getExpr(), listType))
00901             KL->setExpr(expr);
00902         else
00903             return false;
00904     }
00905     return true;
00906 }
00907 
00908 bool RecordAggChecker::checkOthersComponents(AggregateExpr *agg)
00909 {
00910     
00911     if (!agg->hasOthers())
00912         return true;
00913 
00914     
00915     typedef RecordDecl::DeclIter decl_iterator;
00916     std::vector<ComponentDecl*> neededDecls;
00917     decl_iterator I = ContextDecl->beginDecls();
00918     decl_iterator E = ContextDecl->endDecls();
00919     for ( ; I != E; ++I) {
00920         ComponentDecl *neededDecl = dyn_cast<ComponentDecl>(*I);
00921         if (!neededDecl)
00922             continue;
00923         if (!ComponentVec.count(neededDecl))
00924             neededDecls.push_back(neededDecl);
00925     }
00926 
00927     
00928     if (neededDecls.empty())
00929         return true;
00930 
00931     
00932     
00933     
00934     
00935     
00936     
00937     Type *neededType = neededDecls.front()->getType();
00938     for (unsigned i = 1; i < neededDecls.size(); ++i) {
00939         ComponentDecl *neededDecl = neededDecls[i];
00940         if (neededDecl->getType() != neededType) {
00941             report(agg->getOthersLoc(),
00942                    diag::INCONSISTENT_RECORD_COMPONENT_SELECTORS);
00943             return false;
00944         }
00945     }
00946     if (Expr *expr = agg->getOthersExpr()) {
00947         if (!(expr = TC.checkExprInContext(expr, neededType)))
00948             return false;
00949         agg->setOthersExpr(expr);
00950     }
00951     return true;
00952 }
00953 
00954 bool RecordAggChecker::checkKeyedComponents(AggregateExpr *agg)
00955 {
00956     return checkKeyConsistency(agg) && checkKeyTypes(agg);
00957 }
00958 
00959 
00960 
00961 
00962 
00963 
00964 
00965 
00966 
00967 
00968 Expr *TypeCheck::resolveAggregateExpr(AggregateExpr *agg, Type *context)
00969 {
00970     if (ArrayType *arrTy = dyn_cast<ArrayType>(context)) {
00971         ArrayAggChecker checker(*this);
00972         return checker.resolveAggregateExpr(agg, arrTy);
00973     }
00974     else if (RecordType *recTy = dyn_cast<RecordType>(context)) {
00975         RecordAggChecker checker(*this);
00976         return checker.resolveAggregateExpr(agg, recTy);
00977     }
00978     else {
00979         report(agg->getLocation(), diag::INVALID_CONTEXT_FOR_AGGREGATE);
00980         return 0;
00981     }
00982 }
00983 
00984 void TypeCheck::beginAggregate(Location loc)
00985 {
00986     aggregateStack.push(new AggregateExpr(loc));
00987 }
00988 
00989 void TypeCheck::acceptPositionalAggregateComponent(Node nodeComponent)
00990 {
00991     Expr *component = ensureExpr(nodeComponent);
00992     nodeComponent.release();
00993     aggregateStack.top()->addComponent(component);
00994 }
00995 
00996 Node TypeCheck::acceptAggregateKey(Node lowerNode, Node upperNode)
00997 {
00998     Expr *lower = ensureExpr(lowerNode);
00999     Expr *upper = ensureExpr(upperNode);
01000 
01001     if (!(lower && upper))
01002         return getInvalidNode();
01003 
01004     
01005     
01006     lowerNode.release();
01007     upperNode.release();
01008     return getNode(new ComponentKey(new Range(lower, upper)));
01009 }
01010 
01011 Node TypeCheck::acceptAggregateKey(IdentifierInfo *name, Location loc)
01012 {
01013     
01014     
01015     return getNode(new ComponentKey(new Identifier(name, loc)));
01016 }
01017 
01018 Node TypeCheck::acceptAggregateKey(Node keyNode)
01019 {
01020     
01021     
01022     
01023     
01024     if (TypeRef *ref = lift_node<TypeRef>(keyNode)) {
01025         
01026         
01027         
01028         TypeDecl *decl = ref->getTypeDecl();
01029         if (!decl || !decl->getType()->isDiscreteType()) {
01030             report(ref->getLocation(), diag::EXPECTED_DISCRETE_SUBTYPE);
01031             return getInvalidNode();
01032         }
01033         keyNode.release();
01034         return getNode(new ComponentKey(ref));
01035     }
01036 
01037     Expr *expr = ensureExpr(keyNode);
01038     if (!expr)
01039         return getInvalidNode();
01040 
01041     keyNode.release();
01042     return getNode(new ComponentKey(expr));
01043 }
01044 
01045 void TypeCheck::acceptKeyedAggregateComponent(NodeVector &keyNodes,
01046                                               Node exprNode, Location loc)
01047 {
01048     
01049     Expr *expr = 0;
01050     if (!exprNode.isNull()) {
01051         if (!(expr = ensureExpr(exprNode)))
01052             return;
01053     }
01054 
01055     
01056     
01057     
01058     if (keyNodes.empty())
01059         return;
01060 
01061     
01062     typedef NodeCaster<ComponentKey> Caster;
01063     typedef llvm::mapped_iterator<NodeVector::iterator, Caster> Mapper;
01064     typedef llvm::SmallVector<ComponentKey*, 8> KeyVec;
01065     KeyVec keys(Mapper(keyNodes.begin(), Caster()),
01066                 Mapper(keyNodes.end(), Caster()));
01067 
01068     
01069     
01070     keyNodes.release();
01071     exprNode.release();
01072     ComponentKeyList *KL;
01073     if (expr == 0)
01074         expr = new DiamondExpr(loc);
01075     KL = ComponentKeyList::create(&keys[0], keys.size(), expr);
01076     aggregateStack.top()->addComponent(KL);
01077 }
01078 
01079 void TypeCheck::acceptAggregateOthers(Location loc, Node nodeComponent)
01080 {
01081     AggregateExpr *agg = aggregateStack.top();
01082     Expr *component = 0;
01083 
01084     if (nodeComponent.isNull())
01085         component = new DiamondExpr(loc);
01086     else
01087         component = ensureExpr(nodeComponent);
01088 
01089     nodeComponent.release();
01090     agg->addOthersExpr(loc, component);
01091 }
01092 
01093 Node TypeCheck::endAggregate()
01094 {
01095     AggregateExpr *agg = aggregateStack.top();
01096     aggregateStack.pop();
01097 
01098     
01099     
01100     
01101     if (agg->empty()) {
01102         delete agg;
01103         return getInvalidNode();
01104     }
01105     return getNode(agg);
01106 }
01107 
01108 
01109 
01110 
01111 Node TypeCheck::acceptStringLiteral(const char *chars, unsigned len,
01112                                     Location loc)
01113 {
01114     
01115     
01116     
01117     assert(len >= 2 && chars[0] == '"' && chars[len - 1] == '"' &&
01118            "Unexpected string format!");
01119 
01120     const char *I = chars + 1;
01121     const char *E = chars + len - 1;
01122     StringLiteral *string = new StringLiteral(I, E, loc);
01123 
01124     char buff[3] = { '\'', 0, '\'' };
01125     typedef llvm::SmallVector<EnumerationDecl*, 8> LitVec;
01126 
01127     while (I != E) {
01128         buff[1] = *I;
01129         IdentifierInfo *id = resource.getIdentifierInfo(&buff[0], 3);
01130         Resolver &resolver = scope.getResolver();
01131         LitVec literals;
01132 
01133         ++I;
01134         resolver.resolve(id);
01135         getVisibleEnumerations(resolver, literals);
01136 
01137         
01138         
01139         
01140         
01141         
01142         assert(!literals.empty() && "Failed to resolve character literal!");
01143 
01144         
01145         
01146         if (string->zeroComponentTypes()) {
01147             string->addComponentTypes(literals.begin(), literals.end());
01148             continue;
01149         }
01150 
01151         
01152         
01153         intersectComponentTypes(string, literals);
01154 
01155         
01156         
01157         
01158         assert(!string->zeroComponentTypes() && "Disjoint character types!");
01159     }
01160 
01161     return getNode(string);
01162 }
01163 
01164 Expr *TypeCheck::resolveStringLiteral(StringLiteral *strLit, Type *context)
01165 {
01166     
01167     ArrayType *arrTy = dyn_cast<ArrayType>(context);
01168     if (!arrTy || !arrTy->isStringType()) {
01169         report(strLit->getLocation(), diag::INCOMPATIBLE_TYPES);
01170         return 0;
01171     }
01172 
01173     
01174     
01175     
01176     if (!arrTy->isConstrained() &&
01177         !(arrTy = getConstrainedArraySubtype(arrTy, strLit)))
01178         return 0;
01179 
01180     
01181     
01182     
01183     
01184     
01185     
01186     EnumerationType *enumTy;
01187     enumTy = cast<EnumerationType>(arrTy->getComponentType());
01188     if (!strLit->containsComponentType(enumTy)) {
01189         report(strLit->getLocation(), diag::STRING_COMPONENTS_DO_NOT_SATISFY)
01190             << enumTy->getIdInfo();
01191         return 0;
01192     }
01193 
01194     
01195     
01196     
01197     uint64_t arrLength = arrTy->length();
01198     uint64_t strLength = strLit->length();
01199 
01200     if (arrLength < strLength) {
01201         report(strLit->getLocation(), diag::TOO_MANY_ELEMENTS_FOR_TYPE)
01202             << arrTy->getIdInfo();
01203         return 0;
01204     }
01205     if (arrLength > strLength) {
01206         report(strLit->getLocation(), diag::TOO_FEW_ELEMENTS_FOR_TYPE)
01207             << arrTy->getIdInfo();
01208         return 0;
01209     }
01210 
01213     strLit->resolveComponentType(enumTy);
01214     strLit->setType(arrTy);
01215     return strLit;
01216 }