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 }