00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "RangeChecker.h"
00010 #include "Scope.h"
00011 #include "Stencil.h"
00012 #include "TypeCheck.h"
00013 #include "comma/ast/AstRewriter.h"
00014 #include "comma/ast/AttribExpr.h"
00015 #include "comma/ast/ExceptionRef.h"
00016 #include "comma/ast/Expr.h"
00017 #include "comma/ast/Decl.h"
00018 #include "comma/ast/DSTDefinition.h"
00019 #include "comma/ast/KeywordSelector.h"
00020 #include "comma/ast/Pragma.h"
00021 #include "comma/ast/RangeAttrib.h"
00022 #include "comma/ast/Stmt.h"
00023 #include "comma/ast/TypeRef.h"
00024 
00025 #include "llvm/ADT/DenseMap.h"
00026 #include "llvm/ADT/STLExtras.h"
00027 
00028 #include <algorithm>
00029 #include <cstring>
00030 
00031 using namespace comma;
00032 using llvm::dyn_cast;
00033 using llvm::dyn_cast_or_null;
00034 using llvm::cast;
00035 using llvm::isa;
00036 
00037 TypeCheck::TypeCheck(Diagnostic      &diag,
00038                      AstResource     &resource,
00039                      CompilationUnit *cunit)
00040     : diagnostic(diag),
00041       resource(resource),
00042       compUnit(cunit)
00043 {
00044     populateInitialEnvironment();
00045 }
00046 
00047 TypeCheck::~TypeCheck() { }
00048 
00049 
00050 
00051 void TypeCheck::populateInitialEnvironment()
00052 {
00053     EnumerationDecl *theBoolDecl = resource.getTheBooleanDecl();
00054     scope.addDirectDecl(theBoolDecl);
00055     introduceImplicitDecls(theBoolDecl);
00056 
00057     
00058     
00059     IntegerDecl *theRootIntegerDecl = resource.getTheRootIntegerDecl();
00060     introduceImplicitDecls(theRootIntegerDecl);
00061 
00062     IntegerDecl *theIntegerDecl = resource.getTheIntegerDecl();
00063     scope.addDirectDecl(theIntegerDecl);
00064     introduceImplicitDecls(theIntegerDecl);
00065 
00066     
00067     
00068     IntegerDecl *thePositiveDecl = resource.getThePositiveDecl();
00069     scope.addDirectDecl(thePositiveDecl);
00070     IntegerDecl *theNaturalDecl = resource.getTheNaturalDecl();
00071     scope.addDirectDecl(theNaturalDecl);
00072 
00073     EnumerationDecl *theCharacterDecl = resource.getTheCharacterDecl();
00074     scope.addDirectDecl(theCharacterDecl);
00075     introduceImplicitDecls(theCharacterDecl);
00076 
00077     ArrayDecl *theStringDecl = resource.getTheStringDecl();
00078     scope.addDirectDecl(theStringDecl);
00079 
00080     
00081     scope.addDirectDecl(resource.getTheProgramError());
00082     scope.addDirectDecl(resource.getTheConstraintError());
00083     scope.addDirectDecl(resource.getTheAssertionError());
00084 }
00085 
00086 void TypeCheck::deleteNode(Node &node)
00087 {
00088     Ast *ast = lift_node<Ast>(node);
00089     if (ast && ast->isDeletable())
00090         delete ast;
00091     node.release();
00092 }
00093 
00094 Sigoid *TypeCheck::getCurrentSigoid() const
00095 {
00096     return dyn_cast<Sigoid>(getCurrentModel());
00097 }
00098 
00099 SignatureDecl *TypeCheck::getCurrentSignature() const
00100 {
00101     return dyn_cast<SignatureDecl>(getCurrentModel());
00102 }
00103 
00104 VarietyDecl *TypeCheck::getCurrentVariety() const
00105 {
00106     return dyn_cast<VarietyDecl>(getCurrentModel());
00107 }
00108 
00109 Domoid *TypeCheck::getCurrentDomoid() const
00110 {
00111     return dyn_cast<Domoid>(getCurrentModel());
00112 }
00113 
00114 DomainDecl *TypeCheck::getCurrentDomain() const
00115 {
00116     return dyn_cast<DomainDecl>(getCurrentModel());
00117 }
00118 
00119 FunctorDecl *TypeCheck::getCurrentFunctor() const
00120 {
00121     return dyn_cast<FunctorDecl>(getCurrentModel());
00122 }
00123 
00124 SubroutineDecl *TypeCheck::getCurrentSubroutine() const
00125 {
00126     DeclRegion     *region = currentDeclarativeRegion();
00127     SubroutineDecl *routine;
00128 
00129     while (region) {
00130         if ((routine = dyn_cast<SubroutineDecl>(region)))
00131             return routine;
00132         region = region->getParent();
00133     }
00134     return 0;
00135 }
00136 
00137 ProcedureDecl *TypeCheck::getCurrentProcedure() const
00138 {
00139     return dyn_cast_or_null<ProcedureDecl>(getCurrentSubroutine());
00140 }
00141 
00142 FunctionDecl *TypeCheck::getCurrentFunction() const
00143 {
00144     return dyn_cast_or_null<FunctionDecl>(getCurrentSubroutine());
00145 }
00146 
00147 PercentDecl *TypeCheck::getCurrentPercent() const
00148 {
00149     if (ModelDecl *model = getCurrentModel())
00150         return model->getPercent();
00151     return 0;
00152 }
00153 
00154 DomainType *TypeCheck::getCurrentPercentType() const
00155 {
00156     if (ModelDecl *model = getCurrentModel())
00157         return model->getPercentType();
00158     return 0;
00159 }
00160 
00161 Node TypeCheck::acceptPercent(Location loc)
00162 {
00163     TypeRef *ref = 0;
00164 
00165     
00166     
00167     
00168     
00169     if (ModelDecl *model = getCurrentModel())
00170         ref = new TypeRef(loc, model->getPercent());
00171     else {
00172         
00173         AbstractDomainDecl *decl = cast<AbstractDomainDecl>(declarativeRegion);
00174         ref = new TypeRef(loc, decl);
00175     }
00176     return getNode(ref);
00177 }
00178 
00179 
00180 
00181 
00182 
00183 bool TypeCheck::denotesDomainPercent(const Decl *decl)
00184 {
00185     if (checkingDomain()) {
00186         DomainDecl *domain = getCurrentDomain();
00187         const DomainDecl *candidate = dyn_cast<DomainDecl>(decl);
00188         if (candidate && domain)
00189             return domain == candidate;
00190     }
00191     return false;
00192 }
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 bool TypeCheck::denotesFunctorPercent(const FunctorDecl *functor,
00208                                       DomainTypeDecl **args, unsigned numArgs)
00209 {
00210     assert(functor->getArity() == numArgs);
00211 
00212     if (checkingFunctor()) {
00213         FunctorDecl *currentFunctor = getCurrentFunctor();
00214         if (currentFunctor != functor)
00215             return false;
00216         for (unsigned i = 0; i < numArgs; ++i) {
00217             DomainType *formal = currentFunctor->getFormalType(i);
00218             if (formal != args[i]->getType())
00219                 return false;
00220         }
00221         return true;
00222     }
00223     return false;
00224 }
00225 
00226 bool TypeCheck::ensureNonRecursiveInstance(
00227     FunctorDecl *decl, DomainTypeDecl **args, unsigned numArgs, Location loc)
00228 {
00229     if (!checkingFunctor() || (decl != getCurrentFunctor()))
00230         return true;
00231     for (unsigned i = 0; i < numArgs; ++i) {
00232         
00233         DomainType *argTy = args[i]->getType();
00234         if (argTy->involvesPercent()) {
00235             report(loc, diag::SELF_RECURSIVE_INSTANCE);
00236             return false;
00237         }
00238     }
00239     return true;
00240 }
00241 
00249 SigInstanceDecl *
00250 TypeCheck::resolveFormalSignature(ModelDecl *parameterizedModel,
00251                                   Type **arguments, unsigned numArguments)
00252 {
00253     assert(parameterizedModel->isParameterized());
00254     assert(numArguments < parameterizedModel->getArity());
00255 
00256     AstRewriter rewriter(resource);
00257 
00258     
00259     
00260     for (unsigned i = 0; i < numArguments; ++i) {
00261         Type *formal = parameterizedModel->getFormalType(i);
00262         Type *actual = arguments[i];
00263         rewriter.addTypeRewrite(formal, actual);
00264     }
00265 
00266     SigInstanceDecl *target = parameterizedModel->getFormalSignature(numArguments);
00267     return rewriter.rewriteSigInstance(target);
00268 }
00269 
00270 
00271 
00272 
00273 
00274 DomainTypeDecl *TypeCheck::ensureValidModelParam(TypeRef *ref)
00275 {
00276     TypeDecl *arg = ref->getTypeDecl();
00277     DomainTypeDecl *dom = dyn_cast_or_null<DomainTypeDecl>(arg);
00278     if (!dom) {
00279         Location loc = ref->getLocation();
00280         report(loc, diag::INVALID_TYPE_PARAM) << ref->getIdInfo();
00281     }
00282     return dom;
00283 }
00284 
00285 TypeRef *
00286 TypeCheck::acceptTypeApplication(TypeRef *ref,
00287                                  SVImpl<TypeRef*>::Type &posArgs,
00288                                  SVImpl<KeywordSelector*>::Type &keyedArgs)
00289 {
00290     Location loc = ref->getLocation();
00291     IdentifierInfo *name = ref->getIdInfo();
00292 
00293     
00294     if (ref->isComplete()) {
00295         report(loc, diag::WRONG_NUM_ARGS_FOR_TYPE) << name;
00296         return 0;
00297     }
00298 
00299     ModelDecl *model = ref->getModelDecl();
00300     unsigned numPositional = posArgs.size();
00301     unsigned numKeyed = keyedArgs.size();
00302     unsigned numArgs = numPositional + numKeyed;
00303 
00304     if (model->getArity() != numArgs) {
00305         report(loc, diag::WRONG_NUM_ARGS_FOR_TYPE) << name;
00306         return 0;
00307     }
00308 
00309     
00310     if (!checkModelKeywordArgs(model, numPositional, keyedArgs))
00311         return 0;
00312 
00313     
00314     
00315     
00316     llvm::SmallVector<DomainTypeDecl *, 8> args(numArgs);
00317     llvm::SmallVector<Location, 8> argLocs(numArgs);
00318 
00319     
00320     for (unsigned i = 0; i < numPositional; ++i) {
00321         DomainTypeDecl *dom = ensureValidModelParam(posArgs[i]);
00322         if (!dom)
00323             return 0;
00324         args[i] = dom;
00325         argLocs[i] = posArgs[i]->getLocation();
00326     }
00327 
00328     
00329     
00330     
00331     for (unsigned i = 0; i < numKeyed; ++i) {
00332         KeywordSelector *selector = keyedArgs[i];
00333         TypeRef *argRef = keyedArgs[i]->getTypeRef();
00334         DomainTypeDecl *dom = ensureValidModelParam(argRef);
00335 
00336         if (!dom)
00337             return 0;
00338 
00339         IdentifierInfo *key = selector->getKeyword();
00340         unsigned index = unsigned(model->getKeywordIndex(key));
00341         args[index] = dom;
00342         argLocs[index] = argRef->getLocation();
00343     }
00344 
00345     
00346     
00347     if (!checkModelArgs(model, args, argLocs))
00348         return 0;
00349 
00350 
00351     
00352     TypeRef *instanceRef = 0;
00353     if (VarietyDecl *V = dyn_cast<VarietyDecl>(model)) {
00354         SigInstanceDecl *instance = V->getInstance(&args[0], numArgs);
00355         instanceRef = new TypeRef(loc, instance);
00356     }
00357     else {
00358         FunctorDecl *F = cast<FunctorDecl>(model);
00359 
00360         
00361         if (!ensureNonRecursiveInstance(F, &args[0], numArgs, loc))
00362             return false;
00363 
00364         
00365         
00366         if (denotesFunctorPercent(F, &args[0], numArgs)) {
00367             report(loc, diag::PERCENT_EQUIVALENT);
00368             instanceRef = new TypeRef(loc, getCurrentPercent());
00369         }
00370         else {
00371             DomainInstanceDecl *instance;
00372             instance = F->getInstance(&args[0], numArgs);
00373             instanceRef = new TypeRef(loc, instance);
00374         }
00375     }
00376     return instanceRef;
00377 }
00378 
00379 bool TypeCheck::checkModelArgs(ModelDecl *model,
00380                                SVImpl<DomainTypeDecl*>::Type &args,
00381                                SVImpl<Location>::Type &argLocs)
00382 {
00383     AstRewriter rewrites(resource);
00384     unsigned numArgs = args.size();
00385     for (unsigned i = 0; i < numArgs; ++i) {
00386         DomainType *argTy = args[i]->getType();
00387         Location argLoc = argLocs[i];
00388         AbstractDomainDecl *target = model->getFormalDecl(i);
00389 
00390         
00391         
00392         rewrites.addTypeRewrite(target->getType(), argTy);
00393 
00394         
00395         if (!checkSignatureProfile(rewrites, argTy, target, argLoc))
00396             return false;
00397     }
00398 
00399     return true;
00400 }
00401 
00402 bool TypeCheck::checkModelKeywordArgs(ModelDecl *model, unsigned numPositional,
00403                                       SVImpl<KeywordSelector*>::Type &keyedArgs)
00404 {
00405     unsigned numKeys = keyedArgs.size();
00406     for (unsigned i = 0; i < numKeys; ++i) {
00407         KeywordSelector *selector = keyedArgs[i];
00408         IdentifierInfo *keyword = selector->getKeyword();
00409         Location keywordLoc = selector->getLocation();
00410         int keywordIdx = model->getKeywordIndex(keyword);
00411 
00412         
00413         if (keywordIdx < 0) {
00414             report(keywordLoc, diag::TYPE_HAS_NO_SUCH_KEYWORD)
00415                 << keyword << model->getIdInfo();
00416             return false;
00417         }
00418 
00419         
00420         
00421         
00422         if ((unsigned)keywordIdx < numPositional) {
00423             report(keywordLoc, diag::PARAM_PROVIDED_POSITIONALLY) << keyword;
00424             return false;
00425         }
00426 
00427         
00428         
00429         for (unsigned j = 0; j < i; ++j) {
00430             if (keyedArgs[j]->getKeyword() == keyword) {
00431                 report(keywordLoc, diag::DUPLICATE_KEYWORD) << keyword;
00432                 return false;
00433             }
00434         }
00435     }
00436     return true;
00437 }
00438 
00439 TypeDecl *TypeCheck::ensureCompleteTypeDecl(Decl *decl, Location loc,
00440                                             bool report)
00441 {
00442     if (TypeDecl *tyDecl = ensureTypeDecl(decl, loc, report)) {
00443         IncompleteTypeDecl *ITD = dyn_cast<IncompleteTypeDecl>(tyDecl);
00444         if (ITD) {
00445             if (ITD->completionIsVisibleIn(currentDeclarativeRegion()))
00446                 return ITD->getCompletion();
00447             else {
00448                 this->report(loc, diag::INVALID_CONTEXT_FOR_INCOMPLETE_TYPE);
00449                 return 0;
00450             }
00451         }
00452         return tyDecl;
00453     }
00454     return 0;
00455 }
00456 
00457 TypeDecl *TypeCheck::ensureCompleteTypeDecl(Node node, bool report)
00458 {
00459     if (TypeRef *ref = lift_node<TypeRef>(node)) {
00460         return ensureCompleteTypeDecl(ref->getDecl(), ref->getLocation(),
00461                                       report);
00462     }
00463     else if (report) {
00464         this->report(getNodeLoc(node), diag::NOT_A_TYPE);
00465     }
00466     return 0;
00467 }
00468 
00469 TypeDecl *TypeCheck::ensureTypeDecl(Decl *decl, Location loc, bool report)
00470 {
00471     if (TypeDecl *tyDecl = dyn_cast<TypeDecl>(decl))
00472         return tyDecl;
00473     if (report)
00474         this->report(loc, diag::NOT_A_TYPE);
00475     return 0;
00476 }
00477 
00478 TypeDecl *TypeCheck::ensureTypeDecl(Node node, bool report)
00479 {
00480     if (TypeRef *ref = lift_node<TypeRef>(node)) {
00481         return ensureTypeDecl(ref->getDecl(), ref->getLocation(), report);
00482     }
00483     else if (report) {
00484         this->report(getNodeLoc(node), diag::NOT_A_TYPE);
00485     }
00486     return 0;
00487 }
00488 
00489 Type *TypeCheck::resolveType(Type *type) const
00490 {
00491     
00492     
00493     if (IncompleteType *opaqueTy = dyn_cast<IncompleteType>(type)) {
00494         IncompleteTypeDecl *ITD = opaqueTy->getDefiningDecl();
00495         if (ITD->completionIsVisibleIn(currentDeclarativeRegion()))
00496             type = ITD->getCompletion()->getType();
00497     }
00498     return type;
00499 }
00500 
00501 bool TypeCheck::ensureStaticIntegerExpr(Expr *expr, llvm::APInt &result)
00502 {
00503     if (isa<IntegerType>(expr->getType()) &&
00504         expr->staticDiscreteValue(result))
00505         return true;
00506 
00507     report(expr->getLocation(), diag::NON_STATIC_EXPRESSION);
00508     return false;
00509 }
00510 
00511 bool TypeCheck::ensureStaticIntegerExpr(Expr *expr)
00512 {
00513     if (isa<IntegerType>(expr->getType()) &&
00514         expr->isStaticDiscreteExpr())
00515         return true;
00516 
00517     report(expr->getLocation(), diag::NON_STATIC_EXPRESSION);
00518     return false;
00519 }
00520 
00521 ArrayType *TypeCheck::getConstrainedArraySubtype(ArrayType *arrTy, Expr *init)
00522 {
00523     
00524     
00525     assert(!arrTy->isConstrained() && "Array type already constrained!");
00526     assert(arrTy->getRank() == 1 && "Multidimensional arrays not supported!");
00527 
00528     if (StringLiteral *strLit = dyn_cast<StringLiteral>(init)) {
00529         unsigned length = strLit->length();
00530         DiscreteType *idxTy = cast<DiscreteType>(arrTy->getIndexType(0));
00531 
00532         
00533         assert(length != 0 && "Null string literals not yet supported!");
00534 
00535         
00536         
00537         llvm::APInt lower;
00538         llvm::APInt upper;
00539 
00540         if (const Range *range = idxTy->getConstraint()) {
00541             assert(range->isStatic() && "FIXME: Support dynamic indices.");
00542             lower = range->getStaticLowerBound();
00543             upper = range->getStaticUpperBound();
00544         }
00545         else {
00546             
00547             idxTy->getLowerLimit(lower);
00548             idxTy->getUpperLimit(upper);
00549         }
00550 
00551         
00552         
00553         
00554         uint64_t cardinality = (upper - lower).getZExtValue();
00555 
00556         
00557         
00558         --length;
00559 
00560         if (length > cardinality) {
00561             report(init->getLocation(), diag::TOO_MANY_ELEMENTS_FOR_TYPE)
00562                 << arrTy->getIdInfo();
00563             return 0;
00564         }
00565 
00566         
00567         upper = length;
00568         upper += lower;
00569 
00570         
00571         
00572         
00573         
00574         IntegerType *intTy = cast<IntegerType>(idxTy);
00575         Expr *lowerExpr = new IntegerLiteral(lower, intTy, 0);
00576         Expr *upperExpr = new IntegerLiteral(upper, intTy, 0);
00577         idxTy = resource.createIntegerSubtype(intTy, lowerExpr, upperExpr);
00578         return resource.createArraySubtype(0, arrTy, &idxTy);
00579     }
00580 
00581     ArrayType *exprTy = cast<ArrayType>(init->getType());
00582 
00583     
00584     if (exprTy->getRootType() != arrTy->getRootType()) {
00585         report(init->getLocation(), diag::INCOMPATIBLE_TYPES);
00586         return 0;
00587     }
00588 
00589     
00590     
00591     if (exprTy->isStaticallyConstrained())
00592         return exprTy;
00593     return arrTy;
00594 }
00595 
00596 ObjectDecl *TypeCheck::acceptArrayObjectDeclaration(Location loc,
00597                                                     IdentifierInfo *name,
00598                                                     ArrayDecl *arrDecl,
00599                                                     Expr *init)
00600 {
00601     ArrayType *arrTy = arrDecl->getType();
00602 
00603     if (!arrTy->isConstrained() && (init == 0)) {
00604         report(loc, diag::UNCONSTRAINED_ARRAY_OBJECT_REQUIRES_INIT);
00605         return 0;
00606     }
00607 
00608     if (init && !(init = checkExprInContext(init, arrTy)))
00609         return 0;
00610 
00611     
00612     
00613     if (!arrTy->isConstrained())
00614         arrTy = cast<ArrayType>(init->getType());
00615 
00616     return new ObjectDecl(name, arrTy, loc, init);
00617 }
00618 
00619 bool TypeCheck::acceptObjectDeclaration(Location loc, IdentifierInfo *name,
00620                                         Node refNode, Node initializerNode)
00621 {
00622     Expr *init = 0;
00623     ObjectDecl *decl = 0;
00624     TypeDecl *tyDecl = ensureCompleteTypeDecl(refNode);
00625 
00626     if (!tyDecl) return false;
00627 
00628     if (!initializerNode.isNull())
00629         init = ensureExpr(initializerNode);
00630 
00631     if (ArrayDecl *arrDecl = dyn_cast<ArrayDecl>(tyDecl)) {
00632         decl = acceptArrayObjectDeclaration(loc, name, arrDecl, init);
00633         if (decl == 0)
00634             return false;
00635     }
00636     else {
00637         Type *objTy = tyDecl->getType();
00638         if (init) {
00639             init = checkExprInContext(init, objTy);
00640             if (!init)
00641                 return false;
00642         }
00643         decl = new ObjectDecl(name, objTy, loc, init);
00644     }
00645 
00646     initializerNode.release();
00647     refNode.release();
00648 
00649     if (Decl *conflict = scope.addDirectDecl(decl)) {
00650         SourceLocation sloc = getSourceLoc(conflict->getLocation());
00651         report(loc, diag::DECLARATION_CONFLICTS) << name << sloc;
00652         return false;
00653     }
00654     currentDeclarativeRegion()->addDecl(decl);
00655     return true;
00656 }
00657 
00658 bool TypeCheck::acceptRenamedObjectDeclaration(Location loc,
00659                                                IdentifierInfo *name,
00660                                                Node refNode, Node targetNode)
00661 {
00662     Expr *target;
00663     TypeDecl *tyDecl;;
00664 
00665     if (!(tyDecl = ensureCompleteTypeDecl(refNode)) ||
00666         !(target = ensureExpr(targetNode)))
00667         return false;
00668 
00669     if (!(target = checkExprInContext(target, tyDecl->getType())))
00670         return false;
00671 
00672     RenamedObjectDecl *decl;
00673     refNode.release();
00674     targetNode.release();
00675     decl = new RenamedObjectDecl(name, tyDecl->getType(), loc, target);
00676 
00677     if (Decl *conflict = scope.addDirectDecl(decl)) {
00678         SourceLocation sloc = getSourceLoc(conflict->getLocation());
00679         report(loc, diag::DECLARATION_CONFLICTS) << name << sloc;
00680         return false;
00681     }
00682 
00683     currentDeclarativeRegion()->addDecl(decl);
00684     return true;
00685 }
00686 
00687 bool TypeCheck::acceptImportDeclaration(Node importedNode)
00688 {
00689     TypeRef *ref = lift_node<TypeRef>(importedNode);
00690     if (!ref) {
00691         report(getNodeLoc(importedNode), diag::IMPORT_FROM_NON_DOMAIN);
00692         return false;
00693     }
00694 
00695     Decl *decl = ref->getDecl();
00696     Location loc = ref->getLocation();
00697     DomainType *domain = 0;
00698 
00699     if (CarrierDecl *carrier = dyn_cast<CarrierDecl>(decl))
00700         domain = dyn_cast<DomainType>(carrier->getType());
00701     else if (DomainTypeDecl *DTD = dyn_cast<DomainTypeDecl>(decl))
00702         domain = DTD->getType();
00703 
00704     if (!domain) {
00705         report(loc, diag::IMPORT_FROM_NON_DOMAIN);
00706         return false;
00707     }
00708 
00709     scope.addImport(domain);
00710 
00711     
00712     
00713     new ImportDecl(domain, loc);
00714     return true;
00715 }
00716 
00717 void TypeCheck::beginEnumeration(IdentifierInfo *name, Location loc)
00718 {
00719     enumStencil.init(name, loc);
00720 }
00721 
00722 void TypeCheck::acceptEnumerationIdentifier(IdentifierInfo *name, Location loc)
00723 {
00724     acceptEnumerationLiteral(name, loc);
00725 }
00726 
00727 void TypeCheck::acceptEnumerationCharacter(IdentifierInfo *name, Location loc)
00728 {
00729     if (acceptEnumerationLiteral(name, loc))
00730         enumStencil.markAsCharacterType();
00731 }
00732 
00733 bool TypeCheck::acceptEnumerationLiteral(IdentifierInfo *name, Location loc)
00734 {
00735     
00736     
00737     
00738     EnumDeclStencil::elem_iterator I = enumStencil.begin_elems();
00739     EnumDeclStencil::elem_iterator E = enumStencil.end_elems();
00740     for ( ; I != E; ++I) {
00741         if (I->first == name) {
00742             enumStencil.markInvalid();
00743             report(loc, diag::MULTIPLE_ENUMERATION_LITERALS) << name;
00744             return false;
00745         }
00746     }
00747 
00748     
00749     
00750     if (name == enumStencil.getIdInfo()) {
00751         report(loc, diag::CONFLICTING_DECLARATION)
00752             << name << getSourceLoc(enumStencil.getLocation());
00753         return false;
00754     }
00755 
00756     enumStencil.addElement(name, loc);
00757     return true;
00758 }
00759 
00760 void TypeCheck::endEnumeration()
00761 {
00762     IdentifierInfo *name = enumStencil.getIdInfo();
00763     Location loc = enumStencil.getLocation();
00764     DeclRegion *region = currentDeclarativeRegion();
00765     EnumDeclStencil::IdLocPair *elems = enumStencil.getElements().data();
00766     unsigned numElems = enumStencil.numElements();
00767     EnumerationDecl *decl;
00768 
00769     ASTStencilReseter reseter(enumStencil);
00770 
00771     
00772     
00773     if (!numElems)
00774         return;
00775 
00776     decl = resource.createEnumDecl(name, loc, elems, numElems, region);
00777 
00778     
00779     
00780     if (enumStencil.isCharacterType())
00781         decl->markAsCharacterType();
00782 
00783     if (introduceTypeDeclaration(decl)) {
00784         decl->generateImplicitDeclarations(resource);
00785         introduceImplicitDecls(decl);
00786     }
00787 }
00788 
00789 void TypeCheck::acceptIntegerTypeDecl(IdentifierInfo *name, Location loc,
00790                                       Node lowNode, Node highNode)
00791 {
00792     DeclRegion *region = currentDeclarativeRegion();
00793     Expr *lower = cast_node<Expr>(lowNode);
00794     Expr *upper = cast_node<Expr>(highNode);
00795     RangeChecker rangeCheck(*this);
00796 
00797     if (!rangeCheck.checkDeclarationRange(lower, upper))
00798         return;
00799 
00800     
00801     
00802     
00803     lowNode.release();
00804     highNode.release();
00805     IntegerDecl *decl;
00806     decl = resource.createIntegerDecl(name, loc, lower, upper, region);
00807 
00808     if (introduceTypeDeclaration(decl)) {
00809         decl->generateImplicitDeclarations(resource);
00810         introduceImplicitDecls(decl);
00811     }
00812 }
00813 
00814 void TypeCheck::acceptRangedSubtypeDecl(IdentifierInfo *name, Location loc,
00815                                         Node subtypeNode,
00816                                         Node lowNode, Node highNode)
00817 {
00818     DeclRegion *region = currentDeclarativeRegion();
00819 
00820     TypeRef *tyRef = lift_node<TypeRef>(subtypeNode);
00821     if (!tyRef) {
00822         report(getNodeLoc(subtypeNode), diag::DOES_NOT_DENOTE_A_TYPE);
00823         return;
00824     }
00825 
00826     TypeDecl *tyDecl = tyRef->getTypeDecl();
00827     if (!tyDecl) {
00828         report(tyRef->getLocation(), diag::EXPECTED_DISCRETE_SUBTYPE);
00829         return;
00830     }
00831 
00832     DiscreteType *baseTy = dyn_cast<DiscreteType>(tyDecl->getType());
00833     if (!baseTy) {
00834         report(tyRef->getLocation(), diag::EXPECTED_DISCRETE_SUBTYPE);
00835         return;
00836     }
00837 
00838     
00839     
00840     Expr *lower = ensureExpr(lowNode);
00841     Expr *upper = ensureExpr(highNode);
00842 
00843     if (!(lower = checkExprInContext(lower, baseTy)) ||
00844         !(upper = checkExprInContext(upper, baseTy)))
00845         return;
00846 
00847     
00848     TypeDecl *decl;
00849 
00850     switch (baseTy->getKind()) {
00851     default:
00852         assert(false && "Unexpected discrete type!");
00853         decl = 0;
00854 
00855     case Ast::AST_IntegerType: {
00856         IntegerType *intTy = cast<IntegerType>(baseTy);
00857         decl = resource.createIntegerSubtypeDecl(
00858             name, loc, intTy, lower, upper, region);
00859         break;
00860     }
00861 
00862     case Ast::AST_EnumerationType: {
00863         EnumerationType *enumTy = cast<EnumerationType>(baseTy);
00864         decl = resource.createEnumSubtypeDecl(
00865             name, loc, enumTy, lower, upper, region);
00866         break;
00867     }
00868     }
00869 
00870     subtypeNode.release();
00871     lowNode.release();
00872     highNode.release();
00873     introduceTypeDeclaration(decl);
00874 }
00875 
00876 void TypeCheck::acceptSubtypeDecl(IdentifierInfo *name, Location loc,
00877                                   Node subtypeNode)
00878 {
00879     DeclRegion *region = currentDeclarativeRegion();
00880     TypeRef *subtype = lift_node<TypeRef>(subtypeNode);
00881 
00882     if (!subtype) {
00883         report(getNodeLoc(subtypeNode), diag::DOES_NOT_DENOTE_A_TYPE);
00884         return;
00885     }
00886 
00889     DiscreteType *baseTy = 0;
00890 
00891     if (TypeDecl *tyDecl = subtype->getTypeDecl()) {
00892         baseTy = dyn_cast<DiscreteType>(tyDecl->getType());
00893     }
00894 
00895     if (!baseTy) {
00896         report(subtype->getLocation(), diag::INVALID_SUBTYPE_INDICATION);
00897         return;
00898     }
00899 
00900     TypeDecl *decl = 0;
00901 
00902     switch (baseTy->getKind()) {
00903     default:
00904         assert(false && "Unexpected subtype indication!");
00905         break;
00906 
00907     case Ast::AST_IntegerType: {
00908         IntegerType *intTy = cast<IntegerType>(baseTy);
00909         decl = resource.createIntegerSubtypeDecl(name, loc, intTy, region);
00910         break;
00911     }
00912 
00913     case Ast::AST_EnumerationType : {
00914         EnumerationType *enumTy = cast<EnumerationType>(baseTy);
00915         decl = resource.createEnumSubtypeDecl(name, loc, enumTy, region);
00916         break;
00917     }
00918     }
00919 
00920     subtypeNode.release();
00921     introduceTypeDeclaration(decl);
00922 }
00923 
00924 void TypeCheck::acceptIncompleteTypeDecl(IdentifierInfo *name, Location loc)
00925 {
00926     DeclRegion *region = currentDeclarativeRegion();
00927     IncompleteTypeDecl *ITD;
00928 
00929     ITD = resource.createIncompleteTypeDecl(name, loc, region);
00930     introduceTypeDeclaration(ITD);
00931 }
00932 
00933 void TypeCheck::acceptArrayDecl(IdentifierInfo *name, Location loc,
00934                                 NodeVector indexNodes, Node componentNode)
00935 {
00936     assert(!indexNodes.empty() && "No type indices for array type decl!");
00937 
00938     
00939     
00940     typedef NodeCaster<DSTDefinition> Caster;
00941     typedef llvm::mapped_iterator<NodeVector::iterator, Caster> Mapper;
00942     typedef llvm::SmallVector<DSTDefinition*, 8> IndexVec;
00943     IndexVec indices(Mapper(indexNodes.begin(), Caster()),
00944                      Mapper(indexNodes.end(), Caster()));
00945 
00946     
00947     
00948     
00949     
00950     DSTDefinition::DSTTag tag = indices[0]->getTag();
00951     bool isConstrained = tag != DSTDefinition::Unconstrained_DST;
00952     bool allOK = true;
00953     for (IndexVec::iterator I = indices.begin(); I != indices.end(); ++I) {
00954         DSTDefinition *index = *I;
00955         DSTDefinition::DSTTag tag = index->getTag();
00956         if (tag == DSTDefinition::Unconstrained_DST && isConstrained) {
00957             report(index->getLocation(),
00958                    diag::EXPECTED_CONSTRAINED_ARRAY_INDEX);
00959             allOK = false;
00960         }
00961         else if (tag != DSTDefinition::Unconstrained_DST && !isConstrained) {
00962             report(index->getLocation(),
00963                    diag::EXPECTED_UNCONSTRAINED_ARRAY_INDEX);
00964             allOK = false;
00965         }
00966     }
00967 
00968     if (!allOK)
00969         return;
00970 
00971     
00972     
00973     PrimaryType *componentTy;
00974     if (TypeDecl *componentDecl = ensureCompleteTypeDecl(componentNode)) {
00975         componentTy = componentDecl->getType();
00976         if (componentTy->isIndefiniteType()) {
00977             report(getNodeLoc(componentNode), diag::INDEFINITE_COMPONENT_TYPE);
00978             return;
00979         }
00980     }
00981     else
00982         return;
00983 
00984     
00985     DeclRegion *region = currentDeclarativeRegion();
00986     ArrayDecl *array =
00987         resource.createArrayDecl(name, loc, indices.size(), &indices[0],
00988                                  componentTy, isConstrained, region);
00989 
00990     if (introduceTypeDeclaration(array))
00991         introduceImplicitDecls(array);
00992 }
00993 
00994 
00995 
00996 
00997 void TypeCheck::beginRecord(IdentifierInfo *name, Location loc)
00998 {
00999     DeclRegion *region = currentDeclarativeRegion();
01000     RecordDecl *record = resource.createRecordDecl(name, loc, region);
01001 
01002     scope.push(RECORD_SCOPE);
01003     pushDeclarativeRegion(record);
01004 }
01005 
01006 void TypeCheck::acceptRecordComponent(IdentifierInfo *name, Location loc,
01007                                       Node typeNode)
01008 {
01009     assert(scope.getKind() == RECORD_SCOPE);
01010     RecordDecl *record = cast<RecordDecl>(currentDeclarativeRegion());
01011     TypeDecl *tyDecl = ensureCompleteTypeDecl(typeNode);
01012 
01013     if (!tyDecl)
01014         return;
01015 
01016     Type *componentTy = tyDecl->getType();
01017 
01018     if (componentTy->isIndefiniteType()) {
01019         report(getNodeLoc(typeNode), diag::INDEFINITE_COMPONENT_TYPE);
01020         return;
01021     }
01022 
01023     ComponentDecl *component = record->addComponent(name, loc, componentTy);
01024     if (Decl *conflict = scope.addDirectDecl(component)) {
01025         SourceLocation sloc = getSourceLoc(conflict->getLocation());
01026         report(loc, diag::DECLARATION_CONFLICTS) << name << sloc;
01027     }
01028 }
01029 
01030 void TypeCheck::endRecord()
01031 {
01032     assert(scope.getKind() == RECORD_SCOPE);
01033     scope.pop();
01034 
01035     RecordDecl *record = cast<RecordDecl>(currentDeclarativeRegion());
01036     popDeclarativeRegion();
01037     introduceTypeDeclaration(record);
01038 }
01039 
01040 void TypeCheck::acceptAccessTypeDecl(IdentifierInfo *name, Location loc,
01041                                      Node subtypeNode)
01042 {
01043     TypeDecl *targetDecl = ensureTypeDecl(subtypeNode);
01044 
01045     if (!targetDecl)
01046         return;
01047 
01048     DeclRegion *region = currentDeclarativeRegion();
01049     AccessDecl *access;
01050     access = resource.createAccessDecl(name, loc, targetDecl->getType(), region);
01051     if (introduceTypeDeclaration(access)) {
01052         access->generateImplicitDeclarations(resource);
01053         introduceImplicitDecls(access);
01054     }
01055 }
01056 
01057 
01058 
01059 
01060 Node TypeCheck::acceptDSTDefinition(Node name, Node lowerNode, Node upperNode)
01061 {
01062     TypeRef *ref = lift_node<TypeRef>(name);
01063     DiscreteType *subtype = 0;
01064 
01065     if (ref) {
01066         if (TypeDecl *decl = ref->getTypeDecl()) {
01067             subtype = dyn_cast<DiscreteType>(decl->getType());
01068         }
01069     }
01070 
01071     if (!subtype) {
01072         report(getNodeLoc(name), diag::EXPECTED_DISCRETE_SUBTYPE_OR_RANGE);
01073         return getInvalidNode();
01074     }
01075 
01076     Expr *lower = ensureExpr(lowerNode);
01077     Expr *upper = ensureExpr(upperNode);
01078     if (!(lower && upper))
01079         return getInvalidNode();
01080 
01081     subtype = RangeChecker(*this).checkSubtypeRange(subtype, lower, upper);
01082     if (!subtype)
01083         return getInvalidNode();
01084 
01085     DSTDefinition::DSTTag tag = DSTDefinition::Constrained_DST;
01086     DSTDefinition *result = new DSTDefinition(ref->getLocation(), subtype, tag);
01087 
01088     name.release();
01089     lowerNode.release();
01090     upperNode.release();
01091     delete ref;
01092     return getNode(result);
01093 }
01094 
01095 Node TypeCheck::acceptDSTDefinition(Node nameOrAttribute, bool isUnconstrained)
01096 {
01097     DSTDefinition *result = 0;
01098 
01099     if (TypeRef *ref = lift_node<TypeRef>(nameOrAttribute)) {
01100         if (TypeDecl *decl = ref->getTypeDecl()) {
01101             if (DiscreteType *type = dyn_cast<DiscreteType>(decl->getType())) {
01102                 DSTDefinition::DSTTag tag = isUnconstrained ?
01103                     DSTDefinition::Unconstrained_DST : DSTDefinition::Type_DST;
01104                 result = new DSTDefinition(ref->getLocation(), type, tag);
01105                 delete ref;
01106             }
01107         }
01108     }
01109     else if (RangeAttrib *attrib = lift_node<RangeAttrib>(nameOrAttribute)) {
01110         DSTDefinition::DSTTag tag = DSTDefinition::Attribute_DST;
01111         result = new DSTDefinition(attrib->getLocation(), attrib, tag);
01112     }
01113 
01114     if (!result) {
01115         report(getNodeLoc(nameOrAttribute),
01116                diag::EXPECTED_DISCRETE_SUBTYPE_OR_RANGE);
01117         return getInvalidNode();
01118     }
01119 
01120     nameOrAttribute.release();
01121     return getNode(result);
01122 }
01123 
01124 Node TypeCheck::acceptDSTDefinition(Node lowerNode, Node upperNode)
01125 {
01126     Expr *lower = ensureExpr(lowerNode);
01127     Expr *upper = ensureExpr(upperNode);
01128     RangeChecker rangeCheck(*this);
01129     DiscreteType *subtype = 0;
01130 
01131     if (!(lower && upper))
01132         return getInvalidNode();
01133 
01134     if (!(subtype = rangeCheck.checkDSTRange(lower, upper)))
01135         return getInvalidNode();
01136 
01137     lowerNode.release();
01138     upperNode.release();
01139     DSTDefinition::DSTTag tag = DSTDefinition::Range_DST;
01140     return getNode(new DSTDefinition(lower->getLocation(), subtype, tag));
01141 }
01142 
01143 bool TypeCheck::checkSignatureProfile(const AstRewriter &rewrites,
01144                                       Type *source, AbstractDomainDecl *target,
01145                                       Location loc)
01146 {
01147     if (DomainType *domain = dyn_cast<DomainType>(source)) {
01148         if (!has(rewrites, domain, target)) {
01149             report(loc, diag::DOMAIN_PARAM_DOES_NOT_SATISFY)
01150                 << target->getString();
01151             return false;
01152         }
01153         return true;
01154     }
01155 
01156     
01157     
01158     report(loc, diag::NOT_A_DOMAIN);
01159     return false;
01160 }
01161 
01162 void TypeCheck::introduceImplicitDecls(DeclRegion *region)
01163 {
01164     typedef DeclRegion::DeclIter iterator;
01165     for (iterator I = region->beginDecls(); I != region->endDecls(); ++I) {
01166         Decl *decl = *I;
01167         if (Decl *conflict = scope.addDirectDecl(decl)) {
01168             report(decl->getLocation(), diag::CONFLICTING_DECLARATION)
01169                 << decl->getIdInfo() << getSourceLoc(conflict->getLocation());
01170         }
01171     }
01172 }
01173 
01174 bool TypeCheck::introduceTypeDeclaration(TypeDecl *decl)
01175 {
01176     Decl *conflict = scope.addDirectDecl(decl);
01177 
01178     if (conflict) {
01179         
01180         
01181         if (IncompleteTypeDecl *ITD = dyn_cast<IncompleteTypeDecl>(conflict)) {
01182             if (ITD->isCompatibleCompletion(decl)) {
01183                 ITD->setCompletion(decl);
01184 
01185                 
01186                 
01187                 if (ITD->getDeclRegion() != currentDeclarativeRegion())
01188                     currentDeclarativeRegion()->addDecl(decl);
01189 
01190                 return true;
01191             }
01192         }
01193 
01194         report(decl->getLocation(), diag::CONFLICTING_DECLARATION)
01195             << decl->getIdInfo() << getSourceLoc(conflict->getLocation());
01196         return false;
01197     }
01198 
01199     currentDeclarativeRegion()->addDecl(decl);
01200     return true;
01201 }
01202 
01203 Location TypeCheck::getNodeLoc(Node node)
01204 {
01205     assert(!node.isNull() && "Cannot get locations from null nodes!");
01206     assert(node.isValid() && "Cannot get locations from invalid nodes!");
01207 
01208     return cast_node<Ast>(node)->getLocation();
01209 }
01210 
01211 bool TypeCheck::covers(Type *A, Type *B)
01212 {
01213     
01214     if (A == B)
01215         return true;
01216 
01217     if (A->isUniversalTypeOf(B) || B->isUniversalTypeOf(A))
01218         return true;
01219 
01220     Type *rootTypeA = A;
01221     Type *rootTypeB = B;
01222 
01223     
01224     if (PrimaryType *primary = dyn_cast<PrimaryType>(A))
01225         rootTypeA = primary->getRootType();
01226     if (PrimaryType *primary = dyn_cast<PrimaryType>(B))
01227         rootTypeB = primary->getRootType();
01228 
01229     return rootTypeA == rootTypeB;
01230 }
01231 
01232 bool TypeCheck::conversionRequired(Type *sourceTy, Type *targetTy)
01233 {
01234     if (sourceTy == targetTy)
01235         return false;
01236 
01237     
01238     if (sourceTy->isUniversalIntegerType())
01239         return true;
01240 
01241     PrimaryType *source = dyn_cast<PrimaryType>(sourceTy);
01242     PrimaryType *target = dyn_cast<PrimaryType>(targetTy);
01243 
01244     
01245     
01246     if (IncompleteType *IT = dyn_cast_or_null<IncompleteType>(source)) {
01247         if (IT->hasCompletion())
01248             source = IT->getCompleteType();
01249     }
01250     if (IncompleteType *IT = dyn_cast_or_null<IncompleteType>(target)) {
01251         if (IT->hasCompletion())
01252             target = IT->getCompleteType();
01253     }
01254 
01255     if (!(source && target))
01256         return false;
01257 
01258     
01259     if (source->isSubtypeOf(target))
01260         return false;
01261 
01262     
01263     
01264     if ((source->getRootType() == target->getRootType()) &&
01265         !target->isConstrained())
01266         return false;
01267 
01268     return true;
01269 }
01270 
01271 Expr *TypeCheck::convertIfNeeded(Expr *expr, Type *target)
01272 {
01273     if (conversionRequired(expr->getType(), target))
01274         return new ConversionExpr(expr, target, expr->getLocation());
01275     return expr;
01276 }
01277 
01278 Type *TypeCheck::getCoveringDereference(Type *source, Type *target)
01279 {
01280     while (AccessType *access = dyn_cast<AccessType>(source)) {
01281         source = resolveType(access->getTargetType());
01282         if (covers(source, target))
01283             return source;
01284     }
01285     return 0;
01286 }
01287 
01288 Type *TypeCheck::getCoveringDereference(Type *source, Type::Classification ID)
01289 {
01290     while (AccessType *access = dyn_cast<AccessType>(source)) {
01291         source = resolveType(access->getTargetType());
01292         if (source->memberOf(ID))
01293             return source;
01294     }
01295     return 0;
01296 }
01297 
01298 Expr *TypeCheck::implicitlyDereference(Expr *expr, Type *target)
01299 {
01300     Type *source = resolveType(expr);
01301     while (isa<AccessType>(source)) {
01302         expr = new DereferenceExpr(expr, expr->getLocation(), true);
01303         source = resolveType(expr);
01304         if (covers(source, target))
01305             return expr;
01306     }
01307     assert(false && "Implicit dereferencing failed!");
01308     return expr;
01309 }
01310 
01311 Expr *TypeCheck::implicitlyDereference(Expr *expr, Type::Classification ID)
01312 {
01313     Type *source = resolveType(expr);
01314     while (isa<AccessType>(source)) {
01315         expr = new DereferenceExpr(expr, expr->getLocation(), true);
01316         source = resolveType(expr);
01317         if (source->memberOf(ID))
01318             return expr;
01319     }
01320     assert(false && "Implicit dereferencing failed!");
01321     return expr;
01322 }
01323 
01324 void TypeCheck::acceptPragmaImport(Location pragmaLoc,
01325                                    IdentifierInfo *convention,
01326                                    Location conventionLoc,
01327                                    IdentifierInfo *entity,
01328                                    Location entityLoc,
01329                                    Node externalNameNode)
01330 {
01331     llvm::StringRef conventionRef(convention->getString());
01332     PragmaImport::Convention ID = PragmaImport::getConventionID(conventionRef);
01333 
01334     if (ID == PragmaImport::UNKNOWN_CONVENTION) {
01335         report(conventionLoc, diag::UNKNOWN_CONVENTION) << convention;
01336         return;
01337     }
01338 
01339     Resolver &resolver = scope.getResolver();
01340     if (!resolver.resolve(entity) || !resolver.hasDirectOverloads()) {
01341         report(entityLoc, diag::NAME_NOT_VISIBLE) << entity;
01342         return;
01343     }
01344 
01345     
01346     if (resolver.numDirectOverloads() != 1) {
01347         report(entityLoc, diag::OVERLOADED_IMPORT_NOT_SUPPORTED);
01348         return;
01349     }
01350 
01351     
01352     Expr *name = cast_node<Expr>(externalNameNode);
01353     if (!(name = checkExprInContext(name, resource.getTheStringType())))
01354         return;
01355     if (!name->isStaticStringExpr()) {
01356         report(name->getLocation(), diag::NON_STATIC_EXPRESSION);
01357         return;
01358     }
01359 
01360     
01361     
01362     SubroutineDecl *srDecl =
01363         cast<SubroutineDecl>(resolver.getDirectOverload(0));
01364     if (srDecl->hasPragma(pragma::Import)) {
01365         report(entityLoc, diag::DUPLICATE_IMPORT_PRAGMAS) << entity;
01366         return;
01367     }
01368 
01369     
01370     
01371     
01372     
01373     
01374     externalNameNode.release();
01375     PragmaImport *pragma = new PragmaImport(pragmaLoc, ID, entity, name);
01376     srDecl->attachPragma(pragma);
01377 }
01378 
01379 PragmaAssert *TypeCheck::acceptPragmaAssert(Location loc, NodeVector &args)
01380 {
01381     
01382     
01383     Expr *pred = ensureExpr(args[0]);
01384     Expr *msg = 0;
01385 
01386     if (!(pred && checkExprInContext(pred, resource.getTheBooleanType())))
01387         return 0;
01388 
01389     if (args.size() == 2) {
01390         if (!(msg = ensureExpr(args[1])))
01391             return 0;
01392         if (!(msg = checkExprInContext(msg, resource.getTheStringType())))
01393             return 0;
01394     }
01395 
01396     return new PragmaAssert(loc, pred, msg);
01397 }
01398 
01399 Checker *Checker::create(Diagnostic      &diag,
01400                          AstResource     &resource,
01401                          CompilationUnit *cunit)
01402 {
01403     return new TypeCheck(diag, resource, cunit);
01404 }