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 //===-- ast/AstResource.cpp ----------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #include "comma/ast/AstResource.h" 00010 #include "comma/ast/Decl.h" 00011 #include "comma/ast/DSTDefinition.h" 00012 #include "comma/ast/Expr.h" 00013 #include "comma/ast/Type.h" 00014 00015 using namespace comma; 00016 using llvm::dyn_cast; 00017 using llvm::cast_or_null; 00018 using llvm::cast; 00019 using llvm::isa; 00020 00021 AstResource::AstResource(TextProvider &txtProvider, IdentifierPool &idPool) 00022 : txtProvider(txtProvider), 00023 idPool(idPool) 00024 { 00025 initializeLanguageDefinedNodes(); 00026 } 00027 00028 void AstResource::initializeLanguageDefinedNodes() 00029 { 00030 initializeBoolean(); 00031 initializeCharacter(); 00032 initializeRootInteger(); 00033 initializeInteger(); 00034 initializeNatural(); 00035 initializePositive(); 00036 initializeString(); 00037 initializeExceptions(); 00038 00039 // Initialize the implicit operations for each declared type. 00040 theBooleanDecl->generateBooleanDeclarations(*this); 00041 theRootIntegerDecl->generateImplicitDeclarations(*this); 00042 theIntegerDecl->generateImplicitDeclarations(*this); 00043 theCharacterDecl->generateImplicitDeclarations(*this); 00044 } 00045 00046 void AstResource::initializeBoolean() 00047 { 00048 IdentifierInfo *boolId = getIdentifierInfo("Boolean"); 00049 IdentifierInfo *trueId = getIdentifierInfo("true"); 00050 IdentifierInfo *falseId = getIdentifierInfo("false"); 00051 00052 // Create a vector of Id/Loc pairs for the two elements of this enumeration. 00053 // Declaration order of the True and False enumeration literals is critical. 00054 // We need False defined first so that it codegens to 0. 00055 typedef std::pair<IdentifierInfo*, Location> IdLocPair; 00056 IdLocPair elems[2] = { IdLocPair(falseId, 0), IdLocPair(trueId, 0) }; 00057 theBooleanDecl = createEnumDecl(boolId, 0, &elems[0], 2, 0); 00058 } 00059 00060 void AstResource::initializeCharacter() 00061 { 00062 // FIXME: Eventually there will be a general library API for working with 00063 // character sets. For now, we just build the type Character by hand. 00064 // 00065 // NOTE: The following is just the first half of the full standard character 00066 // type. 00067 static const unsigned numNames = 128; 00068 const char* names[numNames] = { 00069 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", 00070 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", 00071 00072 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", 00073 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", 00074 00075 "' '", "'!'", "'\"'", "'#'", "'$'", "'%'", "'&'", "'''", 00076 "'('", "')'", "'*'", "'+'", "','", "'-'", "'.'", "'/'", 00077 00078 "'0'", "'1'", "'2'", "'3'", "'4'", "'5'", "'6'", "'7'", 00079 "'8'", "'9'", "':'", "';'", "'<'", "'='", "'>'", "'?'", 00080 00081 "'@'", "'A'", "'B'", "'C'", "'D'", "'E'", "'F'", "'G'", 00082 "'H'", "'I'", "'J'", "'K'", "'L'", "'M'", "'N'", "'O'", 00083 00084 "'P'", "'Q'", "'R'", "'S'", "'T'", "'U'", "'V'", "'W'", 00085 "'X'", "'Y'", "'Z'", "'['", "'\\'", "']'", "'^'", "'_'", 00086 00087 "'`'", "'a'", "'b'", "'c'", "'d'", "'e'", "'f'", "'g'", 00088 "'h'", "'i'", "'j'", "'k'", "'l'", "'m'", "'n'", "'o'", 00089 00090 "'p'", "'q'", "'r'", "'s'", "'t'", "'u'", "'v'", "'w'", 00091 "'x'", "'y'", "'z'", "'{'", "'|'", "'}'", "'~'", "DEL" }; 00092 00093 IdentifierInfo *charId = getIdentifierInfo("Character"); 00094 00095 typedef std::pair<IdentifierInfo*, Location> IdLocPair; 00096 IdLocPair elems[numNames]; 00097 for (unsigned i = 0; i < numNames; ++i) { 00098 IdentifierInfo *id = getIdentifierInfo(names[i]); 00099 elems[i] = IdLocPair(id, 0); 00100 } 00101 theCharacterDecl = createEnumDecl(charId, 0, elems, numNames, 0); 00102 theCharacterDecl->markAsCharacterType(); 00103 } 00104 00105 void AstResource::initializeRootInteger() 00106 { 00107 // Define root_integer as a signed 64 bit type. 00108 // 00109 // FIXME: This is target dependent. 00110 IdentifierInfo *id = getIdentifierInfo("root_integer"); 00111 llvm::APInt lower = llvm::APInt::getSignedMinValue(64); 00112 llvm::APInt upper = llvm::APInt::getSignedMaxValue(64); 00113 IntegerLiteral *lowerExpr = new IntegerLiteral(lower, 0); 00114 IntegerLiteral *upperExpr = new IntegerLiteral(upper, 0); 00115 theRootIntegerDecl = 00116 createIntegerDecl(id, 0, lowerExpr, upperExpr, 0); 00117 } 00118 00119 void AstResource::initializeInteger() 00120 { 00121 // Define Integer as a signed 32 bit type. 00122 IdentifierInfo *integerId = getIdentifierInfo("Integer"); 00123 llvm::APInt lower = llvm::APInt::getSignedMinValue(32); 00124 llvm::APInt upper = llvm::APInt::getSignedMaxValue(32); 00125 IntegerLiteral *lowerExpr = new IntegerLiteral(lower, 0); 00126 IntegerLiteral *upperExpr = new IntegerLiteral(upper, 0); 00127 theIntegerDecl = createIntegerDecl(integerId, 0, 00128 lowerExpr, upperExpr, 0); 00129 } 00130 00131 void AstResource::initializeNatural() 00132 { 00133 // FIXME: This is a temporary hack until we have actual subtype declaration 00134 // nodes. 00135 IdentifierInfo *name = getIdentifierInfo("Natural"); 00136 IntegerType *type = theIntegerDecl->getType(); 00137 unsigned width = type->getSize(); 00138 llvm::APInt lowInt(width, 0, false); 00139 llvm::APInt highInt; 00140 type->getUpperLimit(highInt); 00141 00142 // Allocate static expressions for the bounds. 00143 Expr *low = new IntegerLiteral(lowInt, type, 0); 00144 Expr *high = new IntegerLiteral(highInt, type, 0); 00145 00146 theNaturalDecl = createIntegerSubtypeDecl(name, 0, type, low, high, 0); 00147 } 00148 00149 void AstResource::initializePositive() 00150 { 00151 IdentifierInfo *name = getIdentifierInfo("Positive"); 00152 IntegerType *type = theIntegerDecl->getType(); 00153 unsigned width = type->getSize(); 00154 llvm::APInt lowInt(width, 1, false); 00155 llvm::APInt highInt; 00156 type->getUpperLimit(highInt); 00157 00158 // Allocate static expressions for the bounds. 00159 Expr *low = new IntegerLiteral(lowInt, type, 0); 00160 Expr *high = new IntegerLiteral(highInt, type, 0); 00161 00162 thePositiveDecl = createIntegerSubtypeDecl(name, 0, type, low, high, 0); 00163 } 00164 00165 void AstResource::initializeString() 00166 { 00167 IdentifierInfo *name = getIdentifierInfo("String"); 00168 DiscreteType *indexTy = getThePositiveType(); 00169 DSTDefinition::DSTTag tag = DSTDefinition::Type_DST; 00170 DSTDefinition *DST = new DSTDefinition(0, indexTy, tag); 00171 theStringDecl = createArrayDecl(name, 0, 1, &DST, 00172 getTheCharacterType(), false, 0); 00173 } 00174 00175 void AstResource::initializeExceptions() 00176 { 00177 IdentifierInfo *PEName = getIdentifierInfo("Program_Error"); 00178 ExceptionDecl::ExceptionKind PEKind = ExceptionDecl::Program_Error; 00179 theProgramError = new ExceptionDecl(PEKind, PEName, 0, 0); 00180 00181 IdentifierInfo *CEName = getIdentifierInfo("Constraint_Error"); 00182 ExceptionDecl::ExceptionKind CEKind = ExceptionDecl::Constraint_Error; 00183 theConstraintError = new ExceptionDecl(CEKind, CEName, 0, 0); 00184 00185 IdentifierInfo *AEName = getIdentifierInfo("Assertion_Error"); 00186 ExceptionDecl::ExceptionKind AEKind = ExceptionDecl::Assertion_Error; 00187 theAssertionError = new ExceptionDecl(AEKind, AEName, 0, 0); 00188 } 00189 00192 EnumerationType *AstResource::getTheBooleanType() const 00193 { 00194 return theBooleanDecl->getType(); 00195 } 00196 00197 IntegerType *AstResource::getTheRootIntegerType() const 00198 { 00199 return theRootIntegerDecl->getBaseSubtype(); 00200 } 00201 00202 IntegerType *AstResource::getTheIntegerType() const 00203 { 00204 return theIntegerDecl->getType(); 00205 } 00206 00207 IntegerType *AstResource::getTheNaturalType() const 00208 { 00209 return theNaturalDecl->getType(); 00210 } 00211 00212 IntegerType *AstResource::getThePositiveType() const 00213 { 00214 return thePositiveDecl->getType(); 00215 } 00216 00217 EnumerationType *AstResource::getTheCharacterType() const 00218 { 00219 return theCharacterDecl->getType(); 00220 } 00221 00222 ArrayType *AstResource::getTheStringType() const 00223 { 00224 return theStringDecl->getType(); 00225 } 00226 00227 FunctionType *AstResource::getFunctionType(Type **argTypes, unsigned numArgs, 00228 Type *returnType) 00229 { 00230 llvm::FoldingSetNodeID ID; 00231 FunctionType::Profile(ID, argTypes, numArgs, returnType); 00232 00233 void *pos = 0; 00234 if (FunctionType *uniqued = functionTypes.FindNodeOrInsertPos(ID, pos)) 00235 return uniqued; 00236 00237 FunctionType *res = new FunctionType(argTypes, numArgs, returnType); 00238 functionTypes.InsertNode(res, pos); 00239 return res; 00240 } 00241 00242 ProcedureType *AstResource::getProcedureType(Type **argTypes, unsigned numArgs) 00243 { 00244 llvm::FoldingSetNodeID ID; 00245 ProcedureType::Profile(ID, argTypes, numArgs); 00246 00247 void *pos = 0; 00248 if (ProcedureType *uniqued = procedureTypes.FindNodeOrInsertPos(ID, pos)) 00249 return uniqued; 00250 00251 ProcedureType *res = new ProcedureType(argTypes, numArgs); 00252 procedureTypes.InsertNode(res, pos); 00253 return res; 00254 } 00255 00256 DomainType *AstResource::createDomainType(DomainTypeDecl *decl) 00257 { 00258 DomainType *domTy; 00259 00260 // Construct the root type. 00261 domTy = new DomainType(decl); 00262 types.push_back(domTy); 00263 00264 // Construct a named first subtype of the root. 00265 domTy = new DomainType(domTy, domTy->getIdInfo()); 00266 types.push_back(domTy); 00267 return domTy; 00268 } 00269 00270 DomainType *AstResource::createDomainSubtype(DomainType *root, 00271 IdentifierInfo *name) 00272 { 00273 return new DomainType(root, name); 00274 } 00275 00276 EnumerationDecl * 00277 AstResource::createEnumDecl(IdentifierInfo *name, Location loc, 00278 std::pair<IdentifierInfo*, Location> *elems, 00279 unsigned numElems, DeclRegion *parent) 00280 { 00281 EnumerationDecl *res; 00282 res = new EnumerationDecl(*this, name, loc, elems, numElems, parent); 00283 decls.push_back(res); 00284 return res; 00285 } 00286 00287 EnumerationDecl * 00288 AstResource::createEnumSubtypeDecl(IdentifierInfo *name, Location loc, 00289 EnumerationType *subtype, 00290 Expr *lower, Expr *upper, 00291 DeclRegion *region) 00292 { 00293 EnumerationDecl *res; 00294 res = new EnumerationDecl(*this, name, loc, subtype, lower, upper, region); 00295 decls.push_back(res); 00296 return res; 00297 } 00298 00299 EnumerationDecl * 00300 AstResource::createEnumSubtypeDecl(IdentifierInfo *name, Location loc, 00301 EnumerationType *subtype, 00302 DeclRegion *region) 00303 { 00304 EnumerationDecl *res; 00305 res = new EnumerationDecl(*this, name, loc, subtype, region); 00306 decls.push_back(res); 00307 return res; 00308 } 00309 00310 EnumerationType *AstResource::createEnumType(EnumerationDecl *decl) 00311 { 00312 EnumerationType *res = EnumerationType::create(*this, decl); 00313 types.push_back(res); 00314 return res; 00315 } 00316 00317 EnumerationType *AstResource::createEnumSubtype(EnumerationType *base, 00318 EnumerationDecl *decl) 00319 { 00320 EnumerationType *res = EnumerationType::createSubtype(base, decl); 00321 types.push_back(res); 00322 return res; 00323 } 00324 00325 EnumerationType *AstResource::createEnumSubtype(EnumerationType *base, 00326 Expr *low, Expr *high, 00327 EnumerationDecl *decl) 00328 { 00329 EnumerationType *res; 00330 res = EnumerationType::createConstrainedSubtype(base, low, high, decl); 00331 types.push_back(res); 00332 return res; 00333 } 00334 00335 IntegerDecl *AstResource::createIntegerDecl(IdentifierInfo *name, Location loc, 00336 Expr *lowRange, Expr *highRange, 00337 DeclRegion *parent) 00338 { 00339 IntegerDecl *res; 00340 res = new IntegerDecl(*this, name, loc, lowRange, highRange, parent); 00341 decls.push_back(res); 00342 return res; 00343 } 00344 00345 IntegerDecl * 00346 AstResource::createIntegerSubtypeDecl(IdentifierInfo *name, Location loc, 00347 IntegerType *subtype, 00348 Expr *lower, Expr *upper, 00349 DeclRegion *parent) 00350 { 00351 IntegerDecl *res = new IntegerDecl 00352 (*this, name, loc, subtype, lower, upper, parent); 00353 decls.push_back(res); 00354 return res; 00355 } 00356 00357 IntegerDecl * 00358 AstResource::createIntegerSubtypeDecl(IdentifierInfo *name, Location loc, 00359 IntegerType *subtype, DeclRegion *parent) 00360 { 00361 IntegerDecl *res = new IntegerDecl 00362 (*this, name, loc, subtype, parent); 00363 decls.push_back(res); 00364 return res; 00365 } 00366 00367 IntegerType *AstResource::createIntegerType(IntegerDecl *decl, 00368 const llvm::APInt &low, 00369 const llvm::APInt &high) 00370 { 00371 IntegerType *res = IntegerType::create(*this, decl, low, high); 00372 types.push_back(res); 00373 return res; 00374 } 00375 00376 IntegerType *AstResource::createIntegerSubtype(IntegerType *base, 00377 Expr *low, Expr *high, 00378 IntegerDecl *decl) 00379 { 00380 IntegerType *res; 00381 res = IntegerType::createConstrainedSubtype(base, low, high, decl); 00382 types.push_back(res); 00383 return res; 00384 } 00385 00386 IntegerType *AstResource::createIntegerSubtype(IntegerType *base, 00387 const llvm::APInt &low, 00388 const llvm::APInt &high, 00389 IntegerDecl *decl) 00390 { 00391 Expr *lowExpr = new IntegerLiteral(low, base, 0); 00392 Expr *highExpr = new IntegerLiteral(high, base, 0); 00393 return createIntegerSubtype(base, lowExpr, highExpr, decl); 00394 } 00395 00396 IntegerType *AstResource::createIntegerSubtype(IntegerType *base, 00397 IntegerDecl *decl) 00398 { 00399 IntegerType *res = IntegerType::createSubtype(base, decl); 00400 types.push_back(res); 00401 return res; 00402 } 00403 00404 DiscreteType *AstResource::createDiscreteSubtype(DiscreteType *base, 00405 Expr *low, Expr *high, 00406 TypeDecl *decl) 00407 { 00408 if (IntegerType *intTy = dyn_cast<IntegerType>(base)) { 00409 IntegerDecl *subdecl = cast_or_null<IntegerDecl>(decl); 00410 return createIntegerSubtype(intTy, low, high, subdecl); 00411 } 00412 else { 00413 EnumerationType *enumTy = cast<EnumerationType>(base); 00414 EnumerationDecl *subdecl = cast_or_null<EnumerationDecl>(decl); 00415 return createEnumSubtype(enumTy, low, high, subdecl); 00416 } 00417 } 00418 00419 00420 ArrayDecl *AstResource::createArrayDecl(IdentifierInfo *name, Location loc, 00421 unsigned rank, DSTDefinition **indices, 00422 Type *component, bool isConstrained, 00423 DeclRegion *parent) 00424 { 00425 ArrayDecl *res = new ArrayDecl(*this, name, loc, rank, indices, component, 00426 isConstrained, parent); 00427 decls.push_back(res); 00428 return res; 00429 } 00430 00431 ArrayType *AstResource::createArrayType(ArrayDecl *decl, 00432 unsigned rank, DiscreteType **indices, 00433 Type *component, bool isConstrained) 00434 { 00435 ArrayType *res; 00436 res = new ArrayType(decl, rank, indices, component, isConstrained); 00437 types.push_back(res); 00438 return res; 00439 } 00440 00441 ArrayType *AstResource::createArraySubtype(IdentifierInfo *name, 00442 ArrayType *base, 00443 DiscreteType **indices) 00444 { 00445 ArrayType *res = new ArrayType(name, base, indices); 00446 types.push_back(res); 00447 return res; 00448 } 00449 00450 ArrayType *AstResource::createArraySubtype(IdentifierInfo *name, 00451 ArrayType *base) 00452 { 00453 ArrayType *res = new ArrayType(name, base); 00454 types.push_back(res); 00455 return res; 00456 } 00457 00458 RecordDecl *AstResource::createRecordDecl(IdentifierInfo *name, Location loc, 00459 DeclRegion *parent) 00460 { 00461 RecordDecl *res = new RecordDecl(*this, name, loc, parent); 00462 decls.push_back(res); 00463 return res; 00464 } 00465 00466 RecordType *AstResource::createRecordType(RecordDecl *decl) 00467 { 00468 RecordType *res = new RecordType(decl); 00469 types.push_back(res); 00470 return res; 00471 } 00472 00473 RecordType *AstResource::createRecordSubtype(IdentifierInfo *name, 00474 RecordType *base) 00475 { 00476 RecordType *res = new RecordType(base, name); 00477 types.push_back(res); 00478 return res; 00479 } 00480 00481 AccessDecl *AstResource::createAccessDecl(IdentifierInfo *name, Location loc, 00482 Type *targetType, DeclRegion *parent) 00483 { 00484 AccessDecl *result = new AccessDecl(*this, name, loc, targetType, parent); 00485 decls.push_back(result); 00486 return result; 00487 } 00488 00489 AccessType *AstResource::createAccessType(AccessDecl *decl, Type *targetType) 00490 { 00491 AccessType *result = new AccessType(decl, targetType); 00492 types.push_back(result); 00493 return result; 00494 } 00495 00496 AccessType *AstResource::createAccessSubtype(IdentifierInfo *name, 00497 AccessType *base) 00498 { 00499 AccessType *result = new AccessType(base, name); 00500 types.push_back(result); 00501 return result; 00502 } 00503 00504 IncompleteTypeDecl * 00505 AstResource::createIncompleteTypeDecl(IdentifierInfo *name, Location loc, 00506 DeclRegion *parent) 00507 { 00508 IncompleteTypeDecl *res = new IncompleteTypeDecl(*this, name, loc, parent); 00509 decls.push_back(res); 00510 return res; 00511 } 00512 00513 IncompleteType *AstResource::createIncompleteType(IncompleteTypeDecl *decl) 00514 { 00515 IncompleteType *res = new IncompleteType(decl); 00516 types.push_back(res); 00517 return res; 00518 } 00519 00520 IncompleteType *AstResource::createIncompleteSubtype(IdentifierInfo *name, 00521 IncompleteType *base) 00522 { 00523 IncompleteType *res = new IncompleteType(base, name); 00524 types.push_back(res); 00525 return res; 00526 } 00527 00528 ExceptionDecl *AstResource::createExceptionDecl(IdentifierInfo *name, 00529 Location loc, 00530 DeclRegion *region) 00531 { 00532 ExceptionDecl::ExceptionKind ID = ExceptionDecl::User; 00533 return new ExceptionDecl(ID, name, loc, region); 00534 } 00535 00536 FunctionDecl * 00537 AstResource::createPrimitiveDecl(PO::PrimitiveID ID, Location loc, 00538 Type *type, DeclRegion *region) 00539 { 00540 assert(PO::denotesOperator(ID) && "Not a primitive operator!"); 00541 00542 IdentifierInfo *name = getIdentifierInfo(PO::getOpName(ID)); 00543 IdentifierInfo *left = getIdentifierInfo("Left"); 00544 IdentifierInfo *right = getIdentifierInfo("Right"); 00545 00546 // Create the parameter declarations. 00547 llvm::SmallVector<ParamValueDecl *, 2> params; 00548 00549 if (ID == PO::POW_op) { 00550 params.push_back(new ParamValueDecl(left, type, PM::MODE_DEFAULT, 0)); 00551 params.push_back(new ParamValueDecl( 00552 left, getTheNaturalType(), PM::MODE_DEFAULT, 0)); 00553 } else if (PO::denotesBinaryOp(ID)) { 00554 params.push_back(new ParamValueDecl(left, type, PM::MODE_DEFAULT, 0)); 00555 params.push_back(new ParamValueDecl(right, type, PM::MODE_DEFAULT, 0)); 00556 } 00557 else { 00558 assert(PO::denotesUnaryOp(ID) && "Unexpected operator kind!"); 00559 params.push_back(new ParamValueDecl(right, type, PM::MODE_DEFAULT, 0)); 00560 } 00561 00562 // Determine the return type. 00563 Type *returnTy; 00564 if (PO::denotesPredicateOp(ID)) 00565 returnTy = theBooleanDecl->getType(); 00566 else 00567 returnTy = type; 00568 00569 FunctionDecl *op; 00570 op = new FunctionDecl(*this, name, loc, 00571 ¶ms[0], params.size(), returnTy, region); 00572 op->setAsPrimitive(ID); 00573 return op; 00574 }