This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- typecheck/CheckExpr.cpp ------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 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 // Statements and declarations are parsed and typechecked in a controlled 00037 // manner. We should never have to cope with either of these things where 00038 // an expression is expected. 00039 // 00040 // The only cases we need to diagnose is when the node denotes a type 00041 // (by far the most common case), or an exception. 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 // If the expression is ambiguous we must wait for the top-down pass and 00059 // the accompanying type context. Since we will be checking the node 00060 // entirely at that time simply construct the expression with an 00061 // unresolved type without checks. 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 // Check that the number of indices matches the rank of the array type. 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 // Ensure each index is compatible with the arrays type. If an index does 00088 // not check, continue checking each remaining index. 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 // If the context is a universal type, resolve according to the 00110 // classification denoted by the type. 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 // The following sequence dispatches over the types of expressions which are 00119 // "sensitive" to context, meaning that we might need to patch up the AST so 00120 // that it conforms to the context. 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 // Classification is never a rich enough context to resolve aggregate 00153 // expressions. 00154 report(expr->getLocation(), diag::INVALID_CONTEXT_FOR_AGGREGATE); 00155 return false; 00156 } 00157 00158 // Otherwise, the expression must have a resolved type which belongs to the 00159 // given classification. 00160 Type *exprTy = resolveType(expr->getType()); 00161 assert(exprTy && "Expression does not have a resolved type!"); 00162 00163 if (!exprTy->memberOf(ID)) { 00164 // FIXME: Need a better diagnostic here. 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 // Check if the expression satisfies the given context. If so, perform any 00178 // required conversions and return. 00179 if (covers(exprTy, context)) 00180 return convertIfNeeded(expr, context); 00181 00182 // If implicit dereferencing of the expression can yield an expression of 00183 // the appropriate type, and the expression itself denotes a name, 00184 // implicitly dereference the expression. 00185 if (getCoveringDereference(exprTy, context) && expr->denotesName()) { 00186 expr = implicitlyDereference(expr, context); 00187 return convertIfNeeded(expr, context); 00188 } 00189 00190 // FIXME: Need a better diagnostic here. 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 // FIXME: Need a better diagnostic here. 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 // FIXME: Need a better diagnostic here. 00247 report(intLit->getLocation(), diag::INCOMPATIBLE_TYPES); 00248 return 0; 00249 } 00250 00251 // Since integer types are always signed, the literal is within the bounds 00252 // of the base type iff its width is less than or equal to the base types 00253 // width. If the literal is in bounds, sign extend if needed to match the 00254 // base type. 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 // If the value is contained by the context type simply set the type of the 00269 // literal to the context and return. 00270 if (containment == DiscreteType::Is_Contained) { 00271 intLit->setType(context); 00272 return intLit; 00273 } 00274 00275 // If the value is definitely not contained by the context return null. 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 // Otherwise check that the literal is representable as root_integer and, if 00283 // so, set its type to root_integer and wrap it in a conversion expression. 00284 // 00285 // FIXME: It would probably be better to check if the literal fits within 00286 // the base type of the context. This would be more efficient for codegen 00287 // as it would remove unnecessary truncations. 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 // Currently the only constraint which the type context must satisfy is that 00310 // it represent an access type. 00311 AccessType *targetType = dyn_cast<AccessType>(context); 00312 if (!targetType) { 00313 // FIXME: Need a better diagnostic here. 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 // The context must be an access type. 00331 AccessType *pointerType = dyn_cast<AccessType>(context); 00332 if (!pointerType) { 00333 report(alloc->getLocation(), diag::INCOMPATIBLE_TYPES); 00334 return 0; 00335 } 00336 00337 // Check that the pointee type is compatible with the operand of the 00338 // allocator. 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 // Everything looks OK. 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 // FIXME: The following is not general enough. A full implementation is 00362 // waiting on a reorganization of the type check code that incapsultes the 00363 // top-down resolution phase into a seperate class. 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 // The resolved prefix has a record type. Locate the required component 00374 // declaration and resolve this expression. 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 // Check that the given expression is of the current domain type. 00392 DomainType *domTy = domoid->getPercentType(); 00393 Expr *expr = ensureExpr(exprNode); 00394 if (!expr || !(expr = checkExprInContext(expr, domTy))) 00395 return getInvalidNode(); 00396 00397 // Check that the carrier type has been defined. 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 // Check that the carrier type has been defined. 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 // Integer literals are always unsigned (we have yet to apply a negation 00437 // operator, for example). The parser is commited to procuding APInt's 00438 // which are no wider than necessary to represent the unsigned value. 00439 // Assert this property of the parser. 00440 assert((value == 0 || value.countLeadingZeros() == 0) && 00441 "Unexpected literal representation!"); 00442 00443 // If non-zero, zero extend the literal by one bit. Literals internally 00444 // represented as "minimally sized" signed integers until they are resolved 00445 // to a particular type. This convetion simplifies the evaluation of 00446 // static integer expressions. 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 // We cannot type check null expression until a context has been 00456 // extablished. Simply return an expression node and defer checking until 00457 // the top-down pass. 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 // The prefix to a qualified expression must denote a type decl. 00480 TypeDecl *prefix = ensureCompleteTypeDecl(qualifierNode); 00481 Expr *expr = ensureExpr(exprNode); 00482 00483 if (!(prefix && expr)) 00484 return getInvalidNode(); 00485 00486 // Resolve the operand in the type context provided by the prefix. 00487 if (!(expr = checkExprInContext(expr, prefix->getType()))) 00488 return getInvalidNode(); 00489 00490 // Construct the expression node. 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