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 }