This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- typecheck/TypeCheck.cpp ------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 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 // Called when then type checker is constructed. Populates the top level scope 00050 // with an initial environment. 00051 void TypeCheck::populateInitialEnvironment() 00052 { 00053 EnumerationDecl *theBoolDecl = resource.getTheBooleanDecl(); 00054 scope.addDirectDecl(theBoolDecl); 00055 introduceImplicitDecls(theBoolDecl); 00056 00057 // We do not add root_integer into scope, since it is an anonymous language 00058 // defined type. 00059 IntegerDecl *theRootIntegerDecl = resource.getTheRootIntegerDecl(); 00060 introduceImplicitDecls(theRootIntegerDecl); 00061 00062 IntegerDecl *theIntegerDecl = resource.getTheIntegerDecl(); 00063 scope.addDirectDecl(theIntegerDecl); 00064 introduceImplicitDecls(theIntegerDecl); 00065 00066 // Positive and Natural are subtypes of Integer, and so do not export 00067 // any additional declarations. 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 // Add the standard exception objects into scope. 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 // We are either processing a model or a generic formal domain. 00166 // 00167 // When processing a model, return the associated percent decl. When 00168 // processing a generic formal domain, return the AbstractDomainDecl. 00169 if (ModelDecl *model = getCurrentModel()) 00170 ref = new TypeRef(loc, model->getPercent()); 00171 else { 00172 // FIXME: Use a cleaner interface when available. 00173 AbstractDomainDecl *decl = cast<AbstractDomainDecl>(declarativeRegion); 00174 ref = new TypeRef(loc, decl); 00175 } 00176 return getNode(ref); 00177 } 00178 00179 // Returns true if the given decl is equivalent to % in the context of the 00180 // current domain. 00181 // 00182 // FIXME: This does not work when processing a formal domain. 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 // Returns true if we are currently checking a functor, and if the given functor 00195 // declaration together with the provided arguments would denote an instance 00196 // which is equivalent to % in the current context. For example, given: 00197 // 00198 // domain F (X : T) with 00199 // procedure Foo (A : F(X)); 00200 // ... 00201 // 00202 // Then "F(X)" is equivalent to %. More generally, a functor F applied to its 00203 // formal arguments in the body of F is equivalent to %. 00204 // 00205 // This function assumes that the number and types of the supplied arguments are 00206 // compatible with the given functor. 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 // FIXME: DomainTypeDecls should provide the involvesPercent method. 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 // For each actual argument, establish a map from the formal parameter to 00259 // the actual. 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 // Ensures that the given TypeRef is of a sort compatible with the 00271 // parameterization of a variety or functor (e.g. the TypeRef resolves to a 00272 // DomainTypeDecl). Returns the resolved DomainTypeDecl on sucess. Otherwise 00273 // diagnostics are posted and null is returned. 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 // If the type reference is complete, we cannot apply any arguments. 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 // Check that the model accepts the given keywords. 00310 if (!checkModelKeywordArgs(model, numPositional, keyedArgs)) 00311 return 0; 00312 00313 // Build the a sorted vector of arguments, checking that each type reference 00314 // denotes a domain. Similarly build a vector of sorted locations for each 00315 // argument. 00316 llvm::SmallVector<DomainTypeDecl *, 8> args(numArgs); 00317 llvm::SmallVector<Location, 8> argLocs(numArgs); 00318 00319 // Process the positional parameters. 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 // Process the keyed parameters, placing them in their sorted positions 00329 // (checkModelKeywordArgs has already assured us this mapping will not 00330 // conflict). 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 // Check that the arguments satisfy the parameterization constraints of the 00346 // model. 00347 if (!checkModelArgs(model, args, argLocs)) 00348 return 0; 00349 00350 00351 // Obtain a memoized type node for this particular argument set. 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 // Ensure the requested instance is not self recursive. 00361 if (!ensureNonRecursiveInstance(F, &args[0], numArgs, loc)) 00362 return false; 00363 00364 // If this particular functor parameterization is equivalent to %, warn 00365 // and canonicalize to the unique percent node. 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 // Extend the rewriter mapping the formal argument type to the type of 00391 // the actual argument. 00392 rewrites.addTypeRewrite(target->getType(), argTy); 00393 00394 // Check the argument in the using the rewriter as context. 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 // Ensure the given keyword exists. 00413 if (keywordIdx < 0) { 00414 report(keywordLoc, diag::TYPE_HAS_NO_SUCH_KEYWORD) 00415 << keyword << model->getIdInfo(); 00416 return false; 00417 } 00418 00419 // The corresponding index of the keyword must be greater than the 00420 // number of supplied positional parameters (otherwise it would 00421 // `overlap' a positional parameter). 00422 if ((unsigned)keywordIdx < numPositional) { 00423 report(keywordLoc, diag::PARAM_PROVIDED_POSITIONALLY) << keyword; 00424 return false; 00425 } 00426 00427 // Ensure that this keyword is not a duplicate of any preceeding 00428 // keyword. 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 // If the given type is an incomplete type determine if it is appropriate to 00492 // resolve the type to its completion. 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 // FIXME: The following code assumes integer index types exclusively. 00524 // FIXME: Support multidimensional array types. 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 // FIXME: Support null string literals by generating a null index type. 00533 assert(length != 0 && "Null string literals not yet supported!"); 00534 00535 // Obtain the lower and upper limits for the index type and ensure that 00536 // the given literal is representable within those bounds. 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 // Use the representational limits. 00547 idxTy->getLowerLimit(lower); 00548 idxTy->getUpperLimit(upper); 00549 } 00550 00551 // The following subtraction is always valid provided we treat the 00552 // result as unsigned. Note that the value computed here is one less 00553 // than the actual cardinality -- this is to avoid overflow. 00554 uint64_t cardinality = (upper - lower).getZExtValue(); 00555 00556 // Reduce the non-zero length by one to fit the "zero based" cardinality 00557 // value. 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 // Adjust the upper bound to the length of the literal. 00567 upper = length; 00568 upper += lower; 00569 00570 // Generate expressions for the bounds. 00571 // 00572 // FIXME: Support enumeration types by generating Val attribute 00573 // expressions. 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 // Check that both root types are identical. 00584 if (exprTy->getRootType() != arrTy->getRootType()) { 00585 report(init->getLocation(), diag::INCOMPATIBLE_TYPES); 00586 return 0; 00587 } 00588 00589 // If the expression type is statically constrained, propogate the 00590 // expression's type. Otherwise, leave the type as unconstrained. 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 // If the array type is unconstrained, use the resolved type of the 00612 // initializer. 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 // FIXME: We need to stitch this import declaration into the current 00712 // context. 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 // Check that the given element name has yet to appear in the set of 00736 // elements. If it exists, mark the stencil as invalid and ignore the 00737 // element. 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 // Check that the element does not conflict with the name of the enumeration 00749 // decl itself. 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 // It is possible that the enumeration is empty due to previous errors. Do 00772 // not even bother constructing such malformed nodes. 00773 if (!numElems) 00774 return; 00775 00776 decl = resource.createEnumDecl(name, loc, elems, numElems, region); 00777 00778 // Mark the declaration as a character type if any character literals were 00779 // used to define it. 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 // Obtain an integer type to represent the base type of this declaration and 00801 // release the range expressions as they are now owned by this new 00802 // declaration. 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 // Convert each of the constraints to the expressions and evaluate them in 00839 // the context of the subtype indication. 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 // Construct the specific subtype declaration. 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 // Build a vector of the DSTDefinition's describing the indices of this 00939 // array declaration. 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 // Unfortunately the parser does not ensure that all index types are either 00947 // constrained or unconstrained. Determine the nature of this array 00948 // declaration by inspecting the first index, then check that every 00949 // subsequent index follows the rules. 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 // Ensure the component node is in fact a type and that it does not denote 00972 // an incomplete or indefinite type. 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 // Create the declaration node. 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 // Record type declaration callbacks. 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 // DSTDefinition callbacks. 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 // Otherwise, the source does not denote a domain, and so cannot satisfy the 01157 // signature constraint. 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 // If the conflict is an IncompleteTypeDecl check that the given 01180 // declaration can form its completion. 01181 if (IncompleteTypeDecl *ITD = dyn_cast<IncompleteTypeDecl>(conflict)) { 01182 if (ITD->isCompatibleCompletion(decl)) { 01183 ITD->setCompletion(decl); 01184 01185 // Only add the type declaration to the current declarative 01186 // region if the incomplete declaration was declared elsewhere. 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 // A type covers itself. 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 // If either A or B are primary, resolve their root types. 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 // If the source type is universal_integer convert. 01238 if (sourceTy->isUniversalIntegerType()) 01239 return true; 01240 01241 PrimaryType *source = dyn_cast<PrimaryType>(sourceTy); 01242 PrimaryType *target = dyn_cast<PrimaryType>(targetTy); 01243 01244 // If either of the types are incomplete, attempt to resolve to their 01245 // completions. 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 // If the source is a subtype of the target a conversion is not required. 01259 if (source->isSubtypeOf(target)) 01260 return false; 01261 01262 // If the target is an unconstrained subtype of a common base, a conversion 01263 // is not needed. 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 // We do not support importation of overloaded declarations (yet). 01346 if (resolver.numDirectOverloads() != 1) { 01347 report(entityLoc, diag::OVERLOADED_IMPORT_NOT_SUPPORTED); 01348 return; 01349 } 01350 01351 // Resolve the external name to a static string expression. 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 // Ensure the declaration does not already have a import pragma associated 01361 // with it. 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 // The pragma checks out. 01370 // 01371 // FIXME: We should also ensure that the declaration profile is conformant 01372 // with the convention (does not involve unconstrained array types, for 01373 // example). 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 // Assert pragmas take a required boolean valued predicate and an optional 01382 // string valued message. The parser is aware of this. 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 }