00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00013 
00014 
00015 #include "TypeCheck.h"
00016 #include "comma/ast/AggExpr.h"
00017 #include "comma/ast/KeywordSelector.h"
00018 #include "comma/ast/DiagPrint.h"
00019 #include "comma/ast/Stmt.h"
00020 
00021 using namespace comma;
00022 using llvm::dyn_cast;
00023 using llvm::cast;
00024 using llvm::isa;
00025 
00026 namespace {
00027 
00030 bool routineAcceptsKeywords(SubroutineDecl *decl,
00031                             unsigned numPositional,
00032                             llvm::SmallVectorImpl<KeywordSelector*> &keys)
00033 {
00034     for (unsigned j = 0; j < keys.size(); ++j) {
00035         KeywordSelector *selector = keys[j];
00036         IdentifierInfo *key = selector->getKeyword();
00037         int keyIndex = decl->getKeywordIndex(key);
00038 
00039         if (keyIndex < 0 || unsigned(keyIndex) < numPositional)
00040             return false;
00041     }
00042     return true;
00043 }
00044 
00047 SubroutineCall *
00048 makeSubroutineCall(SubroutineRef *ref,
00049                    Expr **positionalArgs, unsigned numPositional,
00050                    KeywordSelector **keyedArgs, unsigned numKeys)
00051 {
00052     assert(!ref->empty() && "Empty subroutine reference!");
00053 
00054     if (ref->referencesFunctions())
00055         return new FunctionCallExpr(ref, positionalArgs, numPositional,
00056                                     keyedArgs, numKeys);
00057     else
00058         return new ProcedureCallStmt(ref, positionalArgs, numPositional,
00059                                      keyedArgs, numKeys);
00060 }
00061 
00065 void
00066 convertSubroutineArguments(SubroutineDecl *decl,
00067                            llvm::SmallVectorImpl<Expr*> &posArgs,
00068                            llvm::SmallVectorImpl<KeywordSelector*> &keyArgs)
00069 {
00070     typedef llvm::SmallVectorImpl<Expr*>::iterator pos_iterator;
00071     pos_iterator PI = posArgs.begin();
00072     for (unsigned i = 0; PI != posArgs.end(); ++PI, ++i) {
00073         Expr *arg = *PI;
00074         Type *targetType = decl->getParamType(i);
00075         *PI = TypeCheck::convertIfNeeded(arg, targetType);
00076     }
00077 
00078     typedef llvm::SmallVectorImpl<KeywordSelector*>::iterator key_iterator;
00079     key_iterator KI = keyArgs.begin();
00080     for ( ; KI != keyArgs.end(); ++KI) {
00081         KeywordSelector *selector = *KI;
00082         Expr *arg = selector->getExpression();
00083         unsigned index = unsigned(decl->getKeywordIndex(selector));
00084         Type *targetType = decl->getParamType(index);
00085         selector->setRHS(TypeCheck::convertIfNeeded(arg, targetType));
00086     }
00087 }
00088 
00092 void convertSubroutineCallArguments(SubroutineCall *call)
00093 {
00094     assert(call->isUnambiguous() && "Expected resolved call!");
00095 
00096     typedef SubroutineCall::arg_iterator iterator;
00097     iterator I = call->begin_arguments();
00098     iterator E = call->end_arguments();
00099     SubroutineDecl *decl = call->getConnective();
00100     for (unsigned i = 0; I != E; ++I, ++i) {
00101         Expr *arg = *I;
00102         Type *targetType = decl->getParamType(i);
00103         call->setArgument(I, TypeCheck::convertIfNeeded(arg, targetType));
00104     }
00105 }
00106 
00107 } 
00108 
00109 bool TypeCheck::checkApplicableArgument(Expr *arg, Type *targetType)
00110 {
00111     
00112     
00113     if (arg->hasResolvedType())
00114         return covers(arg->getType(), targetType);
00115 
00116     
00117     
00118     if (isa<IntegerLiteral>(arg))
00119         return targetType->isIntegerType();
00120 
00121     
00122     
00123     if (isa<NullExpr>(arg))
00124         return targetType->isAccessType();
00125 
00126     
00127     
00128     
00129     
00130     
00131     if (isa<AggregateExpr>(arg) || isa<StringLiteral>(arg))
00132         return targetType->isCompositeType();
00133 
00134     
00135     
00136     typedef FunctionCallExpr::fun_iterator iterator;
00137     FunctionCallExpr *call = cast<FunctionCallExpr>(arg);
00138 
00139     iterator I = call->begin_functions();
00140     iterator E = call->end_functions();
00141     for ( ; I != E; ++I) {
00142         FunctionDecl *connective = *I;
00143         Type *returnType = connective->getReturnType();
00144         if (covers(returnType, targetType))
00145             return true;
00146     }
00147     return false;
00148 }
00149 
00152 bool TypeCheck::routineAcceptsArgs(SubroutineDecl *decl,
00153                                    SVImpl<Expr*>::Type &args)
00154 {
00155     unsigned numArgs = args.size();
00156     for (unsigned i = 0; i < numArgs; ++i) {
00157         Expr *arg = args[i];
00158         Type *targetType = decl->getParamType(i);
00159         if (!checkApplicableArgument(arg, targetType))
00160             return false;
00161     }
00162     return true;
00163 }
00164 
00167 bool
00168 TypeCheck::routineAcceptsArgs(SubroutineDecl *decl,
00169                               SVImpl<KeywordSelector*>::Type &args)
00170 {
00171     unsigned numKeys = args.size();
00172     for (unsigned i = 0; i < numKeys; ++i) {
00173         KeywordSelector *selector = args[i];
00174         Expr *arg = selector->getExpression();
00175         IdentifierInfo *key = selector->getKeyword();
00176         unsigned targetIndex = decl->getKeywordIndex(key);
00177         Type *targetType = decl->getParamType(targetIndex);
00178 
00179         if (!checkApplicableArgument(arg, targetType))
00180             return false;
00181     }
00182     return true;
00183 }
00184 
00185 Ast* TypeCheck::acceptSubroutineCall(SubroutineRef *ref,
00186                                      SVImpl<Expr*>::Type &positionalArgs,
00187                                      SVImpl<KeywordSelector*>::Type &keyedArgs)
00188 {
00189     Location loc = ref->getLocation();
00190     unsigned numPositional = positionalArgs.size();
00191     unsigned numKeys = keyedArgs.size();
00192 
00193     
00194     
00195     if (ref->isResolved()) {
00196         SubroutineCall *call;
00197         call = checkSubroutineCall(ref, positionalArgs, keyedArgs);
00198         return call ? call->asAst() : 0;
00199     }
00200 
00201     
00202     
00203     SubroutineRef::iterator I = ref->begin();
00204     while (I != ref->end()) {
00205         SubroutineDecl *decl = *I;
00206         if (routineAcceptsKeywords(decl, numPositional, keyedArgs))
00207             ++I;
00208         else
00209             I = ref->erase(I);
00210     }
00211 
00212     
00213     
00214     if (ref->empty()) {
00215         report(loc, diag::AMBIGUOUS_EXPRESSION);
00216         return 0;
00217     }
00218 
00219     
00220     
00221     for (I = ref->begin(); I != ref->end();) {
00222         SubroutineDecl *decl = *I;
00223 
00224         
00225         
00226         if (!routineAcceptsArgs(decl, positionalArgs)) {
00227             I = ref->erase(I);
00228             continue;
00229         }
00230 
00231         
00232         if (!routineAcceptsArgs(decl, keyedArgs)) {
00233             I = ref->erase(I);
00234             continue;
00235         }
00236 
00237         
00238         ++I;
00239     }
00240 
00241     
00242     
00243     if (ref->empty()) {
00244         report(loc, diag::AMBIGUOUS_EXPRESSION);
00245         return 0;
00246     }
00247 
00248     
00249     if (ref->isResolved()) {
00250         SubroutineCall *call;
00251         call = checkSubroutineCall(ref, positionalArgs, keyedArgs);
00252         return call ? call->asAst() : 0;
00253     }
00254 
00255     
00256     
00257     if (ref->referencesProcedures()) {
00258         report(loc, diag::AMBIGUOUS_EXPRESSION);
00259         for (SubroutineRef::iterator I = ref->begin(); I != ref->end(); ++I)
00260             report(loc, diag::CANDIDATE_NOTE) << diag::PrintDecl(*I);
00261         return 0;
00262     }
00263 
00264     SubroutineCall *call =
00265         makeSubroutineCall(ref,
00266                            positionalArgs.data(), numPositional,
00267                            keyedArgs.data(), numKeys);
00268     return call->asAst();
00269 }
00270 
00271 FunctionDecl *TypeCheck::resolvePreferredConnective(FunctionCallExpr *call,
00272                                                     Type *targetType)
00273 {
00274     typedef FunctionCallExpr::fun_iterator iterator;
00275 
00276     
00277     
00278     llvm::SmallVector<FunctionDecl *, 8> candidates;
00279     iterator I = call->begin_functions();
00280     iterator E = call->end_functions();
00281     for ( ; I != E; ++I) {
00282         FunctionDecl *candidate = *I;
00283         Type *returnType = candidate->getReturnType();
00284         if (covers(returnType, targetType))
00285             candidates.push_back(candidate);
00286     }
00287 
00288     
00289     
00290     
00291     
00292     FunctionDecl *preference;
00293     if (candidates.empty())
00294         preference = 0;
00295     else if (candidates.size() == 1)
00296         preference = candidates.front();
00297     else
00298         preference = resolvePreferredOperator(candidates);
00299     return preference;
00300 }
00301 
00302 FunctionDecl *
00303 TypeCheck::resolvePreferredOperator(SVImpl<FunctionDecl*>::Type &decls)
00304 {
00305     
00306     
00307     
00308     IntegerDecl *theRootInteger = resource.getTheRootIntegerDecl();
00309     FunctionDecl *preference = 0;
00310 
00311     typedef SVImpl<FunctionDecl*>::Type::iterator iterator;
00312     iterator I = decls.begin();
00313     iterator E = decls.end();
00314     for ( ; I != E; ++I) {
00315         FunctionDecl *candidate = *I;
00316         if (candidate->isPrimitive()) {
00317             if (candidate->isDeclaredIn(theRootInteger)) {
00318                 
00319                 
00320                 assert(preference == 0 && "More than one prefered decl!");
00321                 preference = candidate;
00322             }
00323         }
00324         else {
00325             
00326             
00327             return 0;
00328         }
00329     }
00330     return preference;
00331 }
00332 
00333 SubroutineCall *
00334 TypeCheck::checkSubroutineCall(SubroutineRef *ref,
00335                                SVImpl<Expr*>::Type &posArgs,
00336                                SVImpl<KeywordSelector*>::Type &keyArgs)
00337 {
00338     assert(ref->isResolved() && "Cannot check call for unresolved reference!");
00339 
00340     Location loc = ref->getLocation();
00341     SubroutineDecl *decl = ref->getDeclaration();
00342     unsigned numArgs = posArgs.size() + keyArgs.size();
00343 
00344     if (decl->getArity() != numArgs) {
00345         report(loc, diag::WRONG_NUM_ARGS_FOR_SUBROUTINE) << decl->getIdInfo();
00346         return 0;
00347     }
00348 
00349     if (!checkSubroutineArguments(decl, posArgs, keyArgs))
00350         return 0;
00351 
00352     convertSubroutineArguments(decl, posArgs, keyArgs);
00353     return makeSubroutineCall(ref, posArgs.data(), posArgs.size(),
00354                               keyArgs.data(), keyArgs.size());
00355 }
00356 
00357 Expr *TypeCheck::checkSubroutineArgument(Expr *arg, Type *targetType,
00358                                          PM::ParameterMode targetMode)
00359 {
00360     
00361     
00362     if (targetMode == PM::MODE_OUT || targetMode == PM::MODE_IN_OUT) {
00363         Expr *immutable;
00364         if (!arg->isMutable(immutable)) {
00365             Location loc = immutable->getLocation();
00366 
00367             
00368             if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(immutable)) {
00369                 if (isa<LoopDecl>(ref->getDeclaration())) {
00370                     report(loc, diag::LOOP_PARAM_NOT_VARIABLE);
00371                     return 0;
00372                 }
00373             }
00374 
00375             
00376             report(loc, diag::EXPRESSION_NOT_MODE_COMPATIBLE) << targetMode;
00377             return 0;
00378         }
00379     }
00380     return checkExprInContext(arg, targetType);
00381 }
00382 
00383 bool
00384 TypeCheck::checkSubroutineArguments(SubroutineDecl *decl,
00385                                     SVImpl<Expr*>::Type &posArgs,
00386                                     SVImpl<KeywordSelector*>::Type &keyArgs)
00387 {
00388     
00389     typedef SVImpl<Expr*>::Type::iterator pos_iterator;
00390     pos_iterator PI = posArgs.begin();
00391     for (unsigned i = 0; PI != posArgs.end(); ++PI, ++i) {
00392         Expr *arg = *PI;
00393         Type *targetType = decl->getParamType(i);
00394         PM::ParameterMode targetMode = decl->getParamMode(i);
00395 
00396         if (!(arg = checkSubroutineArgument(arg, targetType, targetMode)))
00397             return false;
00398         else
00399             *PI = arg;
00400     }
00401 
00402     
00403     typedef SVImpl<KeywordSelector*>::Type::iterator key_iterator;
00404     key_iterator KI = keyArgs.begin();
00405     for ( ; KI != keyArgs.end(); ++KI) {
00406         KeywordSelector *selector = *KI;
00407         IdentifierInfo *key = selector->getKeyword();
00408         Location keyLoc = selector->getLocation();
00409         Expr *arg = selector->getExpression();
00410         int keyIndex = decl->getKeywordIndex(key);
00411 
00412         
00413         if (keyIndex < 0) {
00414             report(keyLoc, diag::SUBROUTINE_HAS_NO_SUCH_KEYWORD)
00415                 << key << decl->getIdInfo();
00416             return false;
00417         }
00418         unsigned argIndex = unsigned(keyIndex);
00419 
00420         
00421         
00422         
00423         if (argIndex < posArgs.size()) {
00424                 report(keyLoc, diag::PARAM_PROVIDED_POSITIONALLY) << key;
00425                 return false;
00426         }
00427 
00428         
00429         
00430         for (key_iterator I = keyArgs.begin(); I != KI; ++I) {
00431             KeywordSelector *prevSelector = *I;
00432             if (prevSelector->getKeyword() == key) {
00433                 report(keyLoc, diag::DUPLICATE_KEYWORD) << key;
00434                 return false;
00435             }
00436         }
00437 
00438         
00439         Type *targetType = decl->getParamType(argIndex);
00440         PM::ParameterMode targetMode = decl->getParamMode(argIndex);
00441         if (!(arg = checkSubroutineArgument(arg, targetType, targetMode)))
00442             return false;
00443         else
00444             selector->setRHS(arg);
00445     }
00446     return true;
00447 }
00448 
00449 bool TypeCheck::checkSubroutineCallArguments(SubroutineCall *call)
00450 {
00451     assert(call->isUnambiguous() && "Expected unambiguous call!");
00452 
00453     typedef SubroutineCall::arg_iterator iterator;
00454     iterator I = call->begin_arguments();
00455     iterator E = call->end_arguments();
00456     bool status = true;
00457     SubroutineDecl *decl = call->getConnective();
00458 
00459     for (unsigned i = 0; I != E; ++I, ++i) {
00460         PM::ParameterMode targetMode = decl->getParamMode(i);
00461         Type *targetType = decl->getParamType(i);
00462         Expr *arg = *I;
00463         if (!(arg = checkSubroutineArgument(*I, targetType, targetMode)))
00464             status = false;
00465         else
00466             call->setArgument(I, arg);
00467     }
00468     return status;
00469 }
00470 
00471 Expr *TypeCheck::resolveFunctionCall(FunctionCallExpr *call, Type *targetType)
00472 {
00473     if (!call->isAmbiguous())
00474         return checkExprAndDereferenceInContext(call, targetType);
00475 
00476     FunctionDecl *preference = resolvePreferredConnective(call, targetType);
00477 
00478     if (!preference)  {
00479         Location loc = call->getLocation();
00480         report(loc, diag::AMBIGUOUS_EXPRESSION);
00481         for (SubroutineCall::connective_iterator I = call->begin_connectives();
00482              I != call->end_connectives(); ++I) {
00483             report(loc, diag::CANDIDATE_NOTE) << diag::PrintDecl(*I);
00484         }
00485         return 0;
00486     }
00487 
00488     
00489     
00490     call->resolveConnective(preference);
00491     if (!checkSubroutineCallArguments(call))
00492         return 0;
00493     convertSubroutineCallArguments(call);
00494     return convertIfNeeded(call, targetType);
00495 }
00496 
00497 bool TypeCheck::resolveFunctionCall(FunctionCallExpr *call,
00498                                     Type::Classification ID)
00499 {
00500     typedef FunctionCallExpr::fun_iterator iterator;
00501 
00502     if (!call->isAmbiguous()) {
00503         
00504         
00505         if (call->getType()->memberOf(ID))
00506             return true;
00507 
00508         
00509         report(call->getLocation(), diag::INCOMPATIBLE_TYPES);
00510         return false;
00511     }
00512 
00513     llvm::SmallVector<FunctionDecl*, 8> candidates;
00514     iterator I = call->begin_functions();
00515     iterator E = call->end_functions();
00516     for ( ; I != E; ++I) {
00517         FunctionDecl *candidate  = *I;
00518         Type *returnType = candidate->getReturnType();
00519         if (returnType->memberOf(ID))
00520             candidates.push_back(candidate);
00521     }
00522 
00523     
00524     
00525     
00526     
00527     FunctionDecl *preference = 0;
00528     if (candidates.empty())
00529         preference = 0;
00530     else if (candidates.size() == 1)
00531         preference = candidates.front();
00532     else
00533         preference = resolvePreferredOperator(candidates);
00534 
00535     if (!preference) {
00536         report(call->getLocation(), diag::AMBIGUOUS_EXPRESSION);
00537 
00538         for (unsigned i = 0; i < candidates.size(); ++i) {
00539             Type *type = candidates[i]->getType();
00540             report(0, diag::CANDIDATE_NOTE) << diag::PrintType(type);
00541         }
00542         return false;
00543     }
00544 
00545     
00546     
00547     call->resolveConnective(preference);
00548     if (!checkSubroutineCallArguments(call))
00549         return false;
00550     convertSubroutineCallArguments(call);
00551     return true;
00552 }
00553 
00554 
00555 Expr *TypeCheck::resolveFunctionCall(FunctionCallExpr *call,
00556                                      IdentifierInfo *selector,
00557                                      Type *targetType)
00558 {
00559     assert(call->isAmbiguous());
00560 
00561     
00562     
00563     typedef llvm::SmallVector<FunctionDecl*, 8> CandidateVec;
00564     typedef FunctionCallExpr::fun_iterator iterator;
00565     CandidateVec candidates;
00566     iterator I = call->begin_functions();
00567     iterator E = call->end_functions();
00568     for ( ; I != E; ++I) {
00569         FunctionDecl *candidate = *I;
00570         Type *returnType = resolveType(candidate->getReturnType());
00571         if (RecordType *recType = dyn_cast<RecordType>(returnType)) {
00572             RecordDecl *decl = recType->getDefiningDecl();
00573             ComponentDecl *component = decl->getComponent(selector);
00574             if (component) {
00575                 Type *componentType = component->getType();
00576                 if (covers(componentType, targetType))
00577                     candidates.push_back(candidate);
00578             }
00579         }
00580     }
00581 
00582     
00583     
00584     if (candidates.size() != 1) {
00585         Location loc = call->getLocation();
00586         report(loc, diag::AMBIGUOUS_EXPRESSION);
00587         for (CandidateVec::iterator I = candidates.begin();
00588              I != candidates.end(); ++I) {
00589             report(loc, diag::CANDIDATE_NOTE) << diag::PrintDecl(*I);
00590         }
00591         return 0;
00592     }
00593 
00594     FunctionDecl *connective = candidates.front();
00595     call->resolveConnective(connective);
00596     if (!checkSubroutineCallArguments(call))
00597         return 0;
00598     convertSubroutineCallArguments(call);
00599 
00600     
00601     
00602     return call;
00603 }