00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "Scope.h"
00010 #include "TypeCheck.h"
00011 #include "comma/ast/ExceptionRef.h"
00012 #include "comma/ast/Expr.h"
00013 #include "comma/ast/KeywordSelector.h"
00014 #include "comma/ast/Stmt.h"
00015 #include "comma/ast/TypeRef.h"
00016 #include "comma/basic/Attributes.h"
00017
00018 using namespace comma;
00019 using llvm::cast_or_null;
00020 using llvm::dyn_cast;
00021 using llvm::cast;
00022 using llvm::isa;
00023
00024 namespace {
00025
00028 SubroutineRef *buildSubroutineRef(Location loc, Resolver &resolver)
00029 {
00030 llvm::SmallVector<SubroutineDecl *, 8> routines;
00031 resolver.getVisibleSubroutines(routines);
00032
00033 if (routines.empty())
00034 return 0;
00035 return new SubroutineRef(loc, &routines[0], routines.size());
00036 }
00037
00038 }
00039
00040 Ast *TypeCheck::checkIndirectName(Location loc, Resolver &resolver)
00041 {
00042
00043 if (resolver.hasVisibleIndirectType()) {
00044 TypeDecl *tdecl = resolver.getIndirectType(0);
00045 return new TypeRef(loc, tdecl);
00046 }
00047
00048
00049 if (resolver.hasVisibleIndirectOverloads()) {
00050 if (SubroutineRef *ref = buildSubroutineRef(loc, resolver))
00051 return ref;
00052 else {
00053 report(ref->getLocation(), diag::NAME_NOT_VISIBLE)
00054 << resolver.getIdInfo();
00055 return 0;
00056 }
00057 }
00058
00059
00060 assert(!resolver.hasIndirectValues() &&
00061 "Indirect values are not implemented!");
00062
00063
00064
00065
00066
00067
00068 report(loc, diag::NAME_REQUIRES_QUAL) << resolver.getIdInfo();
00069 return 0;
00070 }
00071
00072 Node TypeCheck::acceptDirectName(IdentifierInfo *name, Location loc,
00073 bool forStatement)
00074 {
00075 if (Ast *result = checkDirectName(name, loc, forStatement))
00076 return getNode(result);
00077 else
00078 return getInvalidNode();
00079 }
00080
00081 Ast *TypeCheck::checkDirectName(IdentifierInfo *name, Location loc,
00082 bool forStatement)
00083 {
00084 Resolver &resolver = scope.getResolver();
00085
00086 if (!resolver.resolve(name)) {
00087 report(loc, diag::NAME_NOT_VISIBLE) << name;
00088 return 0;
00089 }
00090
00091
00092 if (resolver.hasDirectValue()) {
00093 ValueDecl *vdecl = resolver.getDirectValue();
00094 return new DeclRefExpr(vdecl, loc);
00095 }
00096
00097
00098
00099
00100 if (resolver.hasDirectType()) {
00101 TypeDecl *tdecl = resolver.getDirectType();
00102 return new TypeRef(loc, tdecl);
00103 }
00104
00105
00106 if (resolver.hasDirectException()) {
00107 ExceptionDecl *edecl = resolver.getDirectException();
00108 return new ExceptionRef(loc, edecl);
00109 }
00110
00111
00112
00113
00114
00115
00116 if (resolver.hasDirectCapsule()) {
00117 ModelDecl *mdecl = resolver.getDirectCapsule();
00118 return buildTypeRefForModel(loc, mdecl);
00119 }
00120
00121
00122
00123 if (forStatement)
00124 resolver.filterFunctionals();
00125 else
00126 resolver.filterProcedures();
00127
00128
00129
00130 if (resolver.hasDirectOverloads()) {
00131 if (SubroutineRef *ref = buildSubroutineRef(loc, resolver))
00132 return ref;
00133 else {
00134 report(loc, diag::NAME_NOT_VISIBLE) << name;
00135 return 0;
00136 }
00137 }
00138
00139
00140 return checkIndirectName(loc, resolver);
00141 }
00142
00143 TypeRef *TypeCheck::buildTypeRefForModel(Location loc, ModelDecl *mdecl)
00144 {
00145 TypeRef *ref = 0;
00146
00147 switch (mdecl->getKind()) {
00148
00149 default:
00150 assert(false && "Bad kind of model!");
00151 break;
00152
00153 case Ast::AST_DomainDecl: {
00154 DomainDecl *dom = cast<DomainDecl>(mdecl);
00155 ref = new TypeRef(loc, dom->getInstance());
00156 break;
00157 }
00158
00159 case Ast::AST_SignatureDecl: {
00160 SignatureDecl *sig = cast<SignatureDecl>(mdecl);
00161 ref = new TypeRef(loc, sig->getInstance());
00162 break;
00163 }
00164
00165 case Ast::AST_FunctorDecl:
00166 ref = new TypeRef(loc, cast<FunctorDecl>(mdecl));
00167 break;
00168
00169 case Ast::AST_VarietyDecl:
00170 ref = new TypeRef(loc, cast<VarietyDecl>(mdecl));
00171 break;
00172
00173 };
00174 return ref;
00175 }
00176
00177
00178 Node TypeCheck::acceptCharacterLiteral(IdentifierInfo *lit, Location loc)
00179 {
00180
00181 return acceptDirectName(lit, loc, false);
00182 }
00183
00184
00185 Ast *TypeCheck::processExpandedName(TypeRef *ref,
00186 IdentifierInfo *name, Location loc,
00187 bool forStatement)
00188 {
00189
00190 if (ref->referencesSigInstance()) {
00191 report(loc, diag::INVALID_PREFIX_FOR_COMPONENT) << name;
00192 return 0;
00193 }
00194
00195
00196 assert(ref->isComplete() && "Invalid prefix node!");
00197
00198
00199
00200 DeclRegion *region = ref->getDecl()->asDeclRegion();
00201 assert(region && "Prefix is not a DeclRegion!");
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 llvm::SmallVector<SubroutineDecl*, 8> overloads;
00215
00216 SCAN_AGAIN:
00217 for (DeclRegion::DeclIter I = region->beginDecls(), E = region->endDecls();
00218 I != E; ++I) {
00219 Decl *decl = *I;
00220
00221 if (decl->getIdInfo() == name) {
00222
00223
00224
00225 if (TypeDecl *tdecl = dyn_cast<TypeDecl>(decl)) {
00226 assert(overloads.empty() && "Inconsistent DeclRegion!");
00227 return new TypeRef(loc, tdecl);
00228 }
00229
00230
00231
00232 if (forStatement) {
00233 if (SubroutineDecl *routine = dyn_cast<SubroutineDecl>(decl))
00234 overloads.push_back(routine);
00235 }
00236 else {
00237 if (SubroutineDecl *routine = dyn_cast<FunctionDecl>(decl))
00238 overloads.push_back(routine);
00239 }
00240 }
00241 else if (EnumerationDecl *edecl = dyn_cast<EnumerationDecl>(*I)) {
00242 if (EnumLiteral *lit = edecl->findLiteral(name))
00243 overloads.push_back(lit);
00244 }
00245 }
00246
00247
00248
00249
00250
00251 if (PercentDecl *percent = dyn_cast<PercentDecl>(region)) {
00252 region = cast<Domoid>(percent->getDefinition())->getImplementation();
00253 goto SCAN_AGAIN;
00254 }
00255
00256 if (overloads.empty()) {
00257 report(loc, diag::NAME_NOT_VISIBLE) << name;
00258 return 0;
00259 }
00260
00261 return new SubroutineRef(loc, &overloads[0], overloads.size());
00262 }
00263
00264 Ast *TypeCheck::processSelectedComponent(Expr *expr,
00265 IdentifierInfo *name, Location loc,
00266 bool forStatement)
00267 {
00268
00269
00270 if (!expr->hasResolvedType())
00271 return new SelectedExpr(expr, name, loc);
00272
00273 RecordType *prefixTy;
00274 Type *exprTy = resolveType(expr->getType());
00275 bool requiresDereference = false;
00276
00277 if (!(prefixTy = dyn_cast<RecordType>(exprTy))) {
00278 exprTy = getCoveringDereference(exprTy, Type::CLASS_Record);
00279 prefixTy = cast_or_null<RecordType>(exprTy);
00280 requiresDereference = prefixTy != 0;
00281 }
00282
00283 if (!prefixTy) {
00284 report(expr->getLocation(), diag::INVALID_PREFIX_FOR_COMPONENT) << name;
00285 return 0;
00286 }
00287
00288
00289 RecordDecl *recordDecl = prefixTy->getDefiningDecl();
00290 ComponentDecl *component = recordDecl->getComponent(name);
00291 if (!component) {
00292 report(loc, diag::UNKNOWN_SELECTED_COMPONENT)
00293 << name << recordDecl->getIdInfo();
00294 return 0;
00295 }
00296
00297 if (requiresDereference)
00298 expr = implicitlyDereference(expr, prefixTy);
00299 return new SelectedExpr(expr, component, loc, component->getType());
00300 }
00301
00302 Node TypeCheck::acceptSelectedComponent(Node prefix,
00303 IdentifierInfo *name, Location loc,
00304 bool forStatement)
00305 {
00306 Ast *result = 0;
00307
00308 if (TypeRef *ref = lift_node<TypeRef>(prefix))
00309 result = processExpandedName(ref, name, loc, forStatement);
00310 else if (Expr *expr = lift_node<Expr>(prefix))
00311 result = processSelectedComponent(expr, name, loc, forStatement);
00312 else {
00313 report(loc, diag::INVALID_PREFIX_FOR_COMPONENT) << name;
00314 result = 0;
00315 }
00316
00317 if (result) {
00318 prefix.release();
00319 return getNode(result);
00320 }
00321 else
00322 return getInvalidNode();
00323 }
00324
00325 Node TypeCheck::acceptParameterAssociation(IdentifierInfo *key, Location loc,
00326 Node rhs)
00327 {
00328
00329 if (Expr *expr = lift_node<Expr>(rhs)) {
00330 KeywordSelector *selector = new KeywordSelector(key, loc, expr);
00331 rhs.release();
00332 return getNode(selector);
00333 }
00334
00335
00336 if (TypeRef *ref = lift_node<TypeRef>(rhs)) {
00337 KeywordSelector *selector = new KeywordSelector(key, loc, ref);
00338 rhs.release();
00339 assert(ref->isComplete() && "Invalid TypeRef!");
00340 return getNode(selector);
00341 }
00342
00343
00344 ProcedureCallStmt *call = cast_node<ProcedureCallStmt>(rhs);
00345 report(call->getLocation(), diag::INVALID_CONTEXT_FOR_PROCEDURE);
00346 return getInvalidNode();
00347 }
00348
00349 Node TypeCheck::acceptApplication(Node prefix, NodeVector &argNodes)
00350 {
00351
00352
00353
00354
00355
00356
00357
00358
00359 if (SubroutineRef *ref = lift_node<SubroutineRef>(prefix)) {
00360 if (Ast *call = acceptSubroutineApplication(ref, argNodes)) {
00361 prefix.release();
00362 argNodes.release();
00363 return getNode(call);
00364 }
00365 return getInvalidNode();
00366 }
00367
00368 if (TypeRef *ref = lift_node<TypeRef>(prefix)) {
00369 if (TypeRef *tyRef = acceptTypeApplication(ref, argNodes)) {
00370 prefix.release();
00371 argNodes.release();
00372 return getNode(tyRef);
00373 }
00374 return getInvalidNode();
00375 }
00376
00377 if (Expr *expr = lift_node<Expr>(prefix)) {
00378 if (IndexedArrayExpr *IAE = acceptIndexedArray(expr, argNodes)) {
00379 prefix.release();
00380 argNodes.release();
00381 return getNode(IAE);
00382 }
00383 return getInvalidNode();
00384 }
00385
00386 assert(false && "Bad prefix node!");
00387 return getInvalidNode();
00388 }
00389
00390 bool
00391 TypeCheck::checkSubroutineArgumentNodes(NodeVector &argNodes,
00392 SVImpl<Expr*>::Type &positional,
00393 SVImpl<KeywordSelector*>::Type &keyed)
00394 {
00395 NodeVector::iterator I = argNodes.begin();
00396 NodeVector::iterator E = argNodes.end();
00397
00398
00399 for ( ; I != E; ++I) {
00400 if (Expr *expr = lift_node<Expr>(*I))
00401 positional.push_back(expr);
00402 else
00403 break;
00404 }
00405
00406
00407 for ( ; I != E; ++I) {
00408 if (KeywordSelector *KS = lift_node<KeywordSelector>(*I))
00409 if (KS->isExprSelector()) {
00410 keyed.push_back(KS);
00411 continue;
00412 }
00413 break;
00414 }
00415
00416
00417
00418 if (I != E) {
00419 if (ProcedureCallStmt *call = lift_node<ProcedureCallStmt>(*I)) {
00420 report(call->getLocation(), diag::INVALID_CONTEXT_FOR_PROCEDURE);
00421 }
00422 else if (TypeRef *ref = lift_node<TypeRef>(*I)) {
00423 report(ref->getLocation(), diag::TYPE_CANNOT_DENOTE_VALUE);
00424 }
00425 else if (KeywordSelector *KS = lift_node<KeywordSelector>(*I)) {
00426 assert(KS->isTypeSelector());
00427 TypeRef *ref = KS->getTypeRef();
00428 report(ref->getLocation(), diag::TYPE_CANNOT_DENOTE_VALUE);
00429 }
00430 else if (ExceptionRef *ref = lift_node<ExceptionRef>(*I)) {
00431 report(ref->getLocation(), diag::EXCEPTION_CANNOT_DENOTE_VALUE);
00432 }
00433 else {
00434
00435 report(getNodeLoc(*I), diag::NOT_AN_EXPRESSION);
00436 }
00437 return false;
00438 }
00439 return true;
00440 }
00441
00442 Ast *TypeCheck::acceptSubroutineApplication(SubroutineRef *ref,
00443 NodeVector &argNodes)
00444 {
00445 IdentifierInfo *refName = ref->getIdInfo();
00446
00447 llvm::SmallVector<Expr *, 8> posArgs;
00448 llvm::SmallVector<KeywordSelector *, 8> keyedArgs;
00449 llvm::SmallVector<FunctionDecl*, 4> interps;
00450
00451 if (!checkSubroutineArgumentNodes(argNodes, posArgs, keyedArgs))
00452 return 0;
00453
00454 if (ref->referencesFunctions() && keyedArgs.empty()) {
00455
00456
00457
00458
00459 unsigned numArgs = posArgs.size();
00460 SubroutineRef::fun_iterator I = ref->begin_functions();
00461 SubroutineRef::fun_iterator E = ref->end_functions();
00462
00463 for ( ; I != E; ++I) {
00464 FunctionDecl *fdecl = *I;
00465 Type *retTy = fdecl->getReturnType();
00466 if (fdecl->getArity() != 0)
00467 continue;
00468 if (ArrayType *arrTy = dyn_cast<ArrayType>(retTy)) {
00469 if (arrTy->getRank() == numArgs)
00470 interps.push_back(fdecl);
00471 }
00472 }
00473
00474
00475 if (!ref->keepSubroutinesWithArity(argNodes.size())) {
00476
00477
00478
00479 if (interps.empty()) {
00480 report(ref->getLocation(), diag::WRONG_NUM_ARGS_FOR_SUBROUTINE)
00481 << refName;
00482 return 0;
00483 }
00484
00485
00486
00487 if (interps.size() == 1) {
00488 FunctionCallExpr *call;
00489 IndexedArrayExpr *iae;
00490 ref->addDeclaration(interps[0]);
00491 call = new FunctionCallExpr(ref);
00492 if (!(iae = acceptIndexedArray(call, posArgs)))
00493 delete call;
00494 return iae;
00495 }
00496
00497
00498
00499
00500 FunctionCallExpr *call;
00501 ref->addDeclarations(interps.begin(), interps.end());
00502 call = new FunctionCallExpr(ref);
00503 return new IndexedArrayExpr(call, posArgs.data(), posArgs.size());
00504 }
00505 }
00506 else {
00507
00508
00509 if (!ref->keepSubroutinesWithArity(argNodes.size())) {
00510 report(ref->getLocation(), diag::WRONG_NUM_ARGS_FOR_SUBROUTINE)
00511 << refName;
00512 return 0;
00513 }
00514 }
00515
00516 return acceptSubroutineCall(ref, posArgs, keyedArgs);
00517 }
00518
00519 bool TypeCheck::checkTypeArgumentNodes(NodeVector &argNodes,
00520 SVImpl<TypeRef*>::Type &positional,
00521 SVImpl<KeywordSelector*>::Type &keyed)
00522 {
00523 NodeVector::iterator I = argNodes.begin();
00524 NodeVector::iterator E = argNodes.end();
00525
00526
00527 for ( ; I != E; ++I) {
00528 if (TypeRef *ref = lift_node<TypeRef>(*I)) {
00529 assert(ref->isComplete() && "Incomplete TypeRef!");
00530 positional.push_back(ref);
00531 }
00532 else
00533 break;
00534 }
00535
00536
00537 for ( ; I != E; ++I) {
00538 if (KeywordSelector *KS = lift_node<KeywordSelector>(*I))
00539 if (KS->isTypeSelector()) {
00540 assert(KS->getTypeRef()->isComplete() && "Incomplete TypeRef!");
00541 keyed.push_back(KS);
00542 continue;
00543 }
00544 break;
00545 }
00546
00547
00548
00549 if (I != E) {
00550 if (ProcedureCallStmt *call = lift_node<ProcedureCallStmt>(*I)) {
00551 report(call->getLocation(), diag::INVALID_CONTEXT_FOR_PROCEDURE);
00552 return false;
00553 }
00554
00555 Expr *expr = lift_node<Expr>(*I);
00556 if (!expr) {
00557 KeywordSelector *KS = cast_node<KeywordSelector>(*I);
00558 assert(KS->isExprSelector());
00559 expr = KS->getExpression();
00560 }
00561 report(expr->getLocation(), diag::EXPRESSION_AS_TYPE_PARAM);
00562 return false;
00563 }
00564 return true;
00565 }
00566
00567 TypeRef *TypeCheck::acceptTypeApplication(TypeRef *ref, NodeVector &argNodes)
00568 {
00569
00570
00571 if (ref->isComplete()) {
00572 report(ref->getLocation(), diag::WRONG_NUM_ARGS_FOR_TYPE)
00573 << ref->getIdInfo();
00574 return 0;
00575 }
00576
00577 llvm::SmallVector<TypeRef*, 8> positionalArgs;
00578 llvm::SmallVector<KeywordSelector*, 8> keyedArgs;
00579 if (!checkTypeArgumentNodes(argNodes, positionalArgs, keyedArgs))
00580 return 0;
00581
00582 return acceptTypeApplication(ref, positionalArgs, keyedArgs);
00583 }
00584
00585 bool TypeCheck::checkArrayIndexNodes(NodeVector &argNodes,
00586 SVImpl<Expr*>::Type &indices)
00587 {
00588
00589
00590 NodeVector::iterator I = argNodes.begin();
00591 NodeVector::iterator E = argNodes.end();
00592 for ( ; I != E; ++I) {
00593 if (Expr *expr = lift_node<Expr>(*I)) {
00594 indices.push_back(expr);
00595 continue;
00596 }
00597
00598
00599 Location loc;
00600 if (KeywordSelector *KS = lift_node<KeywordSelector>(*I))
00601 loc = KS->getLocation();
00602 else {
00603 TypeRef *ref = cast_node<TypeRef>(*I);
00604 loc = ref->getLocation();
00605 }
00606 report(loc, diag::INVALID_ARRAY_INDEX);
00607 return false;
00608 }
00609 return true;
00610 }
00611
00612 IndexedArrayExpr *TypeCheck::acceptIndexedArray(Expr *expr,
00613 NodeVector &argNodes)
00614 {
00615 llvm::SmallVector<Expr*, 4> indices;
00616 if (!checkArrayIndexNodes(argNodes, indices))
00617 return 0;
00618 return acceptIndexedArray(expr, indices);
00619 }
00620
00621 Node TypeCheck::acceptAttribute(Node prefixNode,
00622 IdentifierInfo *name, Location loc)
00623 {
00624 assert(name->getAttributeID() != attrib::UNKNOWN_ATTRIBUTE);
00625
00626 attrib::AttributeID ID = name->getAttributeID();
00627 Ast *prefix = cast_node<Ast>(prefixNode);
00628 Ast *result = checkAttribute(ID, prefix, loc);
00629
00630 if (result) {
00631 prefixNode.release();
00632 return getNode(result);
00633 }
00634 return getInvalidNode();
00635 }
00636
00637 Node TypeCheck::finishName(Node name)
00638 {
00639
00640
00641
00642
00643
00644
00645
00646
00647 if (SubroutineRef *ref = lift_node<SubroutineRef>(name)) {
00648 if (Ast *call = finishSubroutineRef(ref)) {
00649 name.release();
00650 return getNode(call);
00651 }
00652 return getInvalidNode();
00653 }
00654
00655 if (TypeRef *ref = lift_node<TypeRef>(name)) {
00656 if (finishTypeRef(ref)) {
00657 name.release();
00658 return name;
00659 }
00660 return getInvalidNode();
00661 }
00662 return name;
00663 }
00664
00665 Ast *TypeCheck::finishSubroutineRef(SubroutineRef *ref)
00666 {
00667 IdentifierInfo *name = ref->getIdInfo();
00668 Location loc = ref->getLocation();
00669
00670
00671
00672 if (!ref->keepSubroutinesWithArity(0)) {
00673 report(loc, diag::NAME_NOT_VISIBLE) << name;
00674 return 0;
00675 }
00676
00677 if (ref->referencesFunctions())
00678 return new FunctionCallExpr(ref, 0, 0, 0, 0);
00679 return new ProcedureCallStmt(ref, 0, 0, 0, 0);
00680 }
00681
00682 bool TypeCheck::finishTypeRef(TypeRef *ref)
00683 {
00684
00685
00686 if (ref->isIncomplete()) {
00687 report(ref->getLocation(), diag::WRONG_NUM_ARGS_FOR_TYPE)
00688 << ref->getIdInfo();
00689 return false;
00690 }
00691 return true;
00692 }