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