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 }