00001
00002
00003
00004
00005
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
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
00053
00054
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
00063
00064
00065
00066
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
00108
00109
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
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
00134
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
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
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
00261 domTy = new DomainType(decl);
00262 types.push_back(domTy);
00263
00264
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
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
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 }