00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "Scope.h"
00010 #include "TypeCheck.h"
00011 #include "comma/ast/AggExpr.h"
00012 #include "comma/ast/ExceptionRef.h"
00013 #include "comma/ast/Stmt.h"
00014 #include "comma/ast/TypeRef.h"
00015
00016 #include <algorithm>
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 Expr *TypeCheck::ensureExpr(Node node)
00025 {
00026 return ensureExpr(cast_node<Ast>(node));
00027 }
00028
00029 Expr *TypeCheck::ensureExpr(Ast *node)
00030 {
00031 Expr *expr = dyn_cast<Expr>(node);
00032
00033 if (expr)
00034 return expr;
00035
00036
00037
00038
00039
00040
00041
00042 if (TypeRef *ref = dyn_cast<TypeRef>(node)) {
00043 report(ref->getLocation(), diag::TYPE_FOUND_EXPECTED_EXPRESSION);
00044 }
00045 else {
00046 ExceptionRef *ref = cast<ExceptionRef>(node);
00047 report(ref->getLocation(), diag::EXCEPTION_CANNOT_DENOTE_VALUE);
00048 }
00049 return 0;
00050 }
00051
00052 IndexedArrayExpr *TypeCheck::acceptIndexedArray(Expr *expr,
00053 SVImpl<Expr*>::Type &indices)
00054 {
00055 Location loc = expr->getLocation();
00056
00057 if (!expr->hasResolvedType()) {
00058
00059
00060
00061
00062 return new IndexedArrayExpr(expr, &indices[0], indices.size());
00063 }
00064
00065 ArrayType *arrTy;
00066 bool requiresDereference = false;
00067
00068 if (!(arrTy = dyn_cast<ArrayType>(expr->getType()))) {
00069 Type *type = expr->getType();
00070 type = getCoveringDereference(type, Type::CLASS_Array);
00071 arrTy = cast_or_null<ArrayType>(type);
00072 requiresDereference = arrTy != 0;
00073 }
00074
00075 if (!arrTy) {
00076 report(loc, diag::EXPECTED_ARRAY_FOR_INDEX);
00077 return 0;
00078 }
00079
00080
00081 unsigned numIndices = indices.size();
00082 if (numIndices != arrTy->getRank()) {
00083 report(loc, diag::WRONG_NUM_SUBSCRIPTS_FOR_ARRAY);
00084 return 0;
00085 }
00086
00087
00088
00089 bool allOK = true;
00090 for (unsigned i = 0; i < numIndices; ++i) {
00091 Expr *index = checkExprInContext(indices[i], arrTy->getIndexType(i));
00092 if (!(indices[i] = index))
00093 allOK = false;
00094 }
00095
00096 if (allOK) {
00097 if (requiresDereference)
00098 expr = implicitlyDereference(expr, arrTy);
00099 return new IndexedArrayExpr(expr, &indices[0], numIndices);
00100 }
00101 else
00102 return 0;
00103 }
00104
00105 Expr *TypeCheck::checkExprInContext(Expr *expr, Type *context)
00106 {
00107 context = resolveType(context);
00108
00109
00110
00111 if (UniversalType *universalTy = dyn_cast<UniversalType>(context)) {
00112 if (checkExprInContext(expr, universalTy->getClassification()))
00113 return expr;
00114 else
00115 return 0;
00116 }
00117
00118
00119
00120
00121 if (FunctionCallExpr *fcall = dyn_cast<FunctionCallExpr>(expr))
00122 return resolveFunctionCall(fcall, context);
00123 if (IntegerLiteral *intLit = dyn_cast<IntegerLiteral>(expr))
00124 return resolveIntegerLiteral(intLit, context);
00125 if (StringLiteral *strLit = dyn_cast<StringLiteral>(expr))
00126 return resolveStringLiteral(strLit, context);
00127 if (AggregateExpr *agg = dyn_cast<AggregateExpr>(expr))
00128 return resolveAggregateExpr(agg, context);
00129 if (NullExpr *null = dyn_cast<NullExpr>(expr))
00130 return resolveNullExpr(null, context);
00131 if (AllocatorExpr *alloc = dyn_cast<AllocatorExpr>(expr))
00132 return resolveAllocatorExpr(alloc, context);
00133 if (SelectedExpr *select = dyn_cast<SelectedExpr>(expr))
00134 return resolveSelectedExpr(select, context);
00135 if (DiamondExpr *diamond = dyn_cast<DiamondExpr>(expr))
00136 return resolveDiamondExpr(diamond, context);
00137
00138 assert(expr->hasResolvedType() && "Expression does not have a resolved type!");
00139
00140 return checkExprAndDereferenceInContext(expr, context);
00141 }
00142
00143 bool TypeCheck::checkExprInContext(Expr *expr, Type::Classification ID)
00144 {
00145 if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(expr)) {
00146 return resolveFunctionCall(call, ID);
00147 }
00148 else if (IntegerLiteral *lit = dyn_cast<IntegerLiteral>(expr)) {
00149 return resolveIntegerLiteral(lit, ID);
00150 }
00151 else if (isa<AggregateExpr>(expr)) {
00152
00153
00154 report(expr->getLocation(), diag::INVALID_CONTEXT_FOR_AGGREGATE);
00155 return false;
00156 }
00157
00158
00159
00160 Type *exprTy = resolveType(expr->getType());
00161 assert(exprTy && "Expression does not have a resolved type!");
00162
00163 if (!exprTy->memberOf(ID)) {
00164
00165 report(expr->getLocation(), diag::INCOMPATIBLE_TYPES);
00166 return false;
00167 }
00168 return true;
00169 }
00170
00171 Expr *TypeCheck::checkExprAndDereferenceInContext(Expr *expr, Type *context)
00172 {
00173 assert(expr->hasType() && "Expected resolved expression!");
00174
00175 Type *exprTy = resolveType(expr);
00176
00177
00178
00179 if (covers(exprTy, context))
00180 return convertIfNeeded(expr, context);
00181
00182
00183
00184
00185 if (getCoveringDereference(exprTy, context) && expr->denotesName()) {
00186 expr = implicitlyDereference(expr, context);
00187 return convertIfNeeded(expr, context);
00188 }
00189
00190
00191 report(expr->getLocation(), diag::INCOMPATIBLE_TYPES);
00192 return 0;
00193 }
00194
00195 Expr *TypeCheck::resolveDiamondExpr(DiamondExpr *diamond, Type *context)
00196 {
00197 if (diamond->hasType()) {
00198 assert(covers(diamond->getType(), context) &&
00199 "Cannot resolve to a different type.");
00200 return diamond;
00201 }
00202
00203 diamond->setType(context);
00204 return diamond;
00205 }
00206
00207 bool TypeCheck::resolveIntegerLiteral(IntegerLiteral *lit,
00208 Type::Classification ID)
00209 {
00210 if (lit->isUniversalInteger()) {
00211 IntegerType *rootTy = resource.getTheRootIntegerType();
00212
00213 if (!rootTy->memberOf(ID)) {
00214 report(lit->getLocation(), diag::INCOMPATIBLE_TYPES);
00215 return false;
00216 }
00217
00218 if (!rootTy->baseContains(lit->getValue())) {
00219 report(lit->getLocation(), diag::VALUE_NOT_IN_RANGE_FOR_TYPE)
00220 << rootTy->getIdInfo();
00221 return false;
00222 }
00223
00224 lit->setType(rootTy);
00225 return true;
00226 }
00227
00228
00229 if (!lit->getType()->memberOf(ID)) {
00230 report(lit->getLocation(), diag::INCOMPATIBLE_TYPES);
00231 return false;
00232 }
00233 return true;
00234 }
00235
00236 Expr *TypeCheck::resolveIntegerLiteral(IntegerLiteral *intLit, Type *context)
00237 {
00238 if (!intLit->isUniversalInteger()) {
00239 assert(intLit->getType() == context &&
00240 "Cannot resolve literal to different type!");
00241 return intLit;
00242 }
00243
00244 IntegerType *subtype = dyn_cast<IntegerType>(context);
00245 if (!subtype) {
00246
00247 report(intLit->getLocation(), diag::INCOMPATIBLE_TYPES);
00248 return 0;
00249 }
00250
00251
00252
00253
00254
00255 llvm::APInt &litValue = intLit->getValue();
00256 unsigned targetWidth = subtype->getSize();
00257 unsigned literalWidth = litValue.getBitWidth();
00258 if (literalWidth < targetWidth)
00259 litValue.sext(targetWidth);
00260 else if (literalWidth > targetWidth) {
00261 report(intLit->getLocation(), diag::VALUE_NOT_IN_RANGE_FOR_TYPE)
00262 << subtype->getIdInfo();
00263 return 0;
00264 }
00265
00266 DiscreteType::ContainmentResult containment = subtype->contains(litValue);
00267
00268
00269
00270 if (containment == DiscreteType::Is_Contained) {
00271 intLit->setType(context);
00272 return intLit;
00273 }
00274
00275
00276 if (containment == DiscreteType::Not_Contained) {
00277 report(intLit->getLocation(), diag::VALUE_NOT_IN_RANGE_FOR_TYPE)
00278 << subtype->getIdInfo();
00279 return 0;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 IntegerType *rootTy = resource.getTheRootIntegerType();
00289 containment = rootTy->contains(litValue);
00290
00291 if (containment == DiscreteType::Not_Contained) {
00292 report(intLit->getLocation(), diag::VALUE_NOT_IN_RANGE_FOR_TYPE)
00293 << subtype->getIdInfo();
00294 return 0;
00295 }
00296
00297 intLit->setType(rootTy);
00298 return new ConversionExpr(intLit, context);
00299 }
00300
00301 Expr *TypeCheck::resolveNullExpr(NullExpr *expr, Type *context)
00302 {
00303 if (expr->hasResolvedType()) {
00304 assert(covers(expr->getType(), context) &&
00305 "Cannot resolve to different type");
00306 return expr;
00307 }
00308
00309
00310
00311 AccessType *targetType = dyn_cast<AccessType>(context);
00312 if (!targetType) {
00313
00314 report(expr->getLocation(), diag::INCOMPATIBLE_TYPES);
00315 return 0;
00316 }
00317
00318 expr->setType(targetType);
00319 return expr;
00320 }
00321
00322 Expr *TypeCheck::resolveAllocatorExpr(AllocatorExpr *alloc, Type *context)
00323 {
00324 if (alloc->hasResolvedType()) {
00325 assert(covers(alloc->getType(), context) &&
00326 "Cannot resolve expression to an incompatible type!");
00327 return alloc;
00328 }
00329
00330
00331 AccessType *pointerType = dyn_cast<AccessType>(context);
00332 if (!pointerType) {
00333 report(alloc->getLocation(), diag::INCOMPATIBLE_TYPES);
00334 return 0;
00335 }
00336
00337
00338
00339 Type *targetType = pointerType->getTargetType();
00340 if (alloc->isInitialized()) {
00341 Expr *operand = alloc->getInitializer();
00342 if (!(operand = checkExprInContext(operand, targetType)))
00343 return 0;
00344 alloc->setInitializer(operand);
00345 }
00346 else if (!covers(alloc->getAllocatedType(), targetType)) {
00347 report(alloc->getLocation(), diag::INCOMPATIBLE_TYPES);
00348 return 0;
00349 }
00350
00351
00352 alloc->setType(pointerType);
00353 return alloc;
00354 }
00355
00356 Expr *TypeCheck::resolveSelectedExpr(SelectedExpr *select, Type *context)
00357 {
00358 if (select->hasResolvedType())
00359 return checkExprAndDereferenceInContext(select, context);
00360
00361
00362
00363
00364 Expr *prefix = select->getPrefix();
00365 IdentifierInfo *selector = select->getSelectorIdInfo();
00366
00367 FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(prefix);
00368 assert(call && "Cannot resolve this type of selected expression!");
00369
00370 if (!(prefix = resolveFunctionCall(call, selector, context)))
00371 return 0;
00372
00373
00374
00375 RecordType *recTy = cast<RecordType>(prefix->getType());
00376 RecordDecl *recDecl = recTy->getDefiningDecl();
00377 ComponentDecl *component = recDecl->getComponent(selector);
00378 select->resolve(component, component->getType());
00379 return convertIfNeeded(select, context);
00380 }
00381
00382 Node TypeCheck::acceptInj(Location loc, Node exprNode)
00383 {
00384 Domoid *domoid = getCurrentDomoid();
00385
00386 if (!domoid) {
00387 report(loc, diag::INVALID_INJ_CONTEXT);
00388 return getInvalidNode();
00389 }
00390
00391
00392 DomainType *domTy = domoid->getPercentType();
00393 Expr *expr = ensureExpr(exprNode);
00394 if (!expr || !(expr = checkExprInContext(expr, domTy)))
00395 return getInvalidNode();
00396
00397
00398 CarrierDecl *carrier = domoid->getImplementation()->getCarrier();
00399 if (!carrier) {
00400 report(loc, diag::CARRIER_TYPE_UNDEFINED);
00401 return getInvalidNode();
00402 }
00403
00404 exprNode.release();
00405 return getNode(new InjExpr(expr, carrier->getType(), loc));
00406 }
00407
00408 Node TypeCheck::acceptPrj(Location loc, Node exprNode)
00409 {
00410 Domoid *domoid = getCurrentDomoid();
00411
00412 if (!domoid) {
00413 report(loc, diag::INVALID_PRJ_CONTEXT);
00414 return getInvalidNode();
00415 }
00416
00417
00418 CarrierDecl *carrier = domoid->getImplementation()->getCarrier();
00419 if (!carrier) {
00420 report(loc, diag::CARRIER_TYPE_UNDEFINED);
00421 return getInvalidNode();
00422 }
00423
00424 Type *carrierTy = carrier->getType();
00425 Expr *expr = ensureExpr(exprNode);
00426 if (!expr || !(expr = checkExprInContext(expr, carrierTy)))
00427 return getInvalidNode();
00428
00429 exprNode.release();
00430 DomainType *prjType = domoid->getPercentType();
00431 return getNode(new PrjExpr(expr, prjType, loc));
00432 }
00433
00434 Node TypeCheck::acceptIntegerLiteral(llvm::APInt &value, Location loc)
00435 {
00436
00437
00438
00439
00440 assert((value == 0 || value.countLeadingZeros() == 0) &&
00441 "Unexpected literal representation!");
00442
00443
00444
00445
00446
00447 if (value != 0)
00448 value.zext(value.getBitWidth() + 1);
00449
00450 return getNode(new IntegerLiteral(value, loc));
00451 }
00452
00453 Node TypeCheck::acceptNullExpr(Location loc)
00454 {
00455
00456
00457
00458 return getNode(new NullExpr(loc));
00459 }
00460
00461 Node TypeCheck::acceptAllocatorExpr(Node operandNode, Location loc)
00462 {
00463 AllocatorExpr *alloc = 0;
00464
00465 if (QualifiedExpr *operand = lift_node<QualifiedExpr>(operandNode))
00466 alloc = new AllocatorExpr(operand, loc);
00467 else {
00468 TypeDecl *operand = ensureCompleteTypeDecl(operandNode);
00469 if (!operand)
00470 return getInvalidNode();
00471 alloc = new AllocatorExpr(operand->getType(), loc);
00472 }
00473 operandNode.release();
00474 return getNode(alloc);
00475 }
00476
00477 Node TypeCheck::acceptQualifiedExpr(Node qualifierNode, Node exprNode)
00478 {
00479
00480 TypeDecl *prefix = ensureCompleteTypeDecl(qualifierNode);
00481 Expr *expr = ensureExpr(exprNode);
00482
00483 if (!(prefix && expr))
00484 return getInvalidNode();
00485
00486
00487 if (!(expr = checkExprInContext(expr, prefix->getType())))
00488 return getInvalidNode();
00489
00490
00491 qualifierNode.release();
00492 exprNode.release();
00493 QualifiedExpr *result;
00494 result = new QualifiedExpr(prefix, expr, getNodeLoc(qualifierNode));
00495 return getNode(result);
00496 }
00497
00498 Node TypeCheck::acceptDereference(Node prefixNode, Location loc)
00499 {
00500 Expr *expr = ensureExpr(prefixNode);
00501
00502 if (!expr)
00503 return getInvalidNode();
00504
00505 if (!checkExprInContext(expr, Type::CLASS_Access))
00506 return getInvalidNode();
00507
00508 prefixNode.release();
00509 DereferenceExpr *deref = new DereferenceExpr(expr, loc);
00510 return getNode(deref);
00511 }
00512
00513
00514
00515