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 }