00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/ast/AstResource.h"
00010 #include "comma/ast/AttribDecl.h"
00011 #include "comma/ast/AttribExpr.h"
00012 #include "comma/ast/Decl.h"
00013 #include "comma/ast/DeclRewriter.h"
00014 #include "comma/ast/DSTDefinition.h"
00015 #include "comma/ast/KeywordSelector.h"
00016 #include "comma/ast/Stmt.h"
00017
00018 #include "llvm/ADT/STLExtras.h"
00019
00020 #include <algorithm>
00021 #include <cstring>
00022 #include <iostream>
00023
00024 using namespace comma;
00025 using llvm::dyn_cast;
00026 using llvm::cast;
00027 using llvm::isa;
00028
00029
00030
00031
00032 DeclRegion *Decl::asDeclRegion()
00033 {
00034 switch (getKind()) {
00035 default:
00036 return 0;
00037 case AST_DomainInstanceDecl:
00038 return static_cast<DomainInstanceDecl*>(this);
00039 case AST_AbstractDomainDecl:
00040 return static_cast<AbstractDomainDecl*>(this);
00041 case AST_PercentDecl:
00042 return static_cast<PercentDecl*>(this);
00043 case AST_EnumerationDecl:
00044 return static_cast<EnumerationDecl*>(this);
00045 case AST_AddDecl:
00046 return static_cast<AddDecl*>(this);
00047 case AST_FunctionDecl:
00048 return static_cast<FunctionDecl*>(this);
00049 case AST_ProcedureDecl:
00050 return static_cast<ProcedureDecl*>(this);
00051 case AST_IntegerDecl:
00052 return static_cast<IntegerDecl*>(this);
00053 case AST_AccessDecl:
00054 return static_cast<AccessDecl*>(this);
00055 }
00056 }
00057
00058 Decl *Decl::resolveOrigin()
00059 {
00060 Decl *res = this;
00061
00062 while (res->hasOrigin())
00063 res = res->getOrigin();
00064
00065 return res;
00066 }
00067
00068
00069
00070
00071 ModelDecl::ModelDecl(AstResource &resource,
00072 AstKind kind, IdentifierInfo *name, Location loc)
00073 : Decl(kind, name, loc),
00074 percent(0),
00075 resource(resource)
00076 {
00077 percent = new PercentDecl(resource, this);
00078 }
00079
00080 ModelDecl::~ModelDecl()
00081 {
00082 delete percent;
00083 }
00084
00085 const SignatureSet &ModelDecl::getSignatureSet() const
00086 {
00087 return percent->getSignatureSet();
00088 }
00089
00090 bool ModelDecl::addDirectSignature(SigInstanceDecl *signature)
00091 {
00092
00093
00094 AstRewriter rewrites(resource);
00095 rewrites.addTypeRewrite(signature->getSigoid()->getPercentType(),
00096 getPercentType());
00097 rewrites.installRewrites(signature);
00098 return percent->sigset.addDirectSignature(signature, rewrites);
00099 }
00100
00101 unsigned ModelDecl::getArity() const
00102 {
00103 return 0;
00104 }
00105
00109 AbstractDomainDecl *ModelDecl::getFormalDecl(unsigned i)
00110 {
00111 assert(!isParameterized() &&
00112 "Parameterized decls must implement this method!");
00113 assert(false &&
00114 "Cannot retrieve formal decls from a non-parameterized model!");
00115 return 0;
00116 }
00117
00121 unsigned ModelDecl::getFormalIndex(const AbstractDomainDecl *ADDecl) const
00122 {
00123 assert(isParameterized() &&
00124 "Cannot retrieve formal index from a non-parameterized model!");
00125 unsigned arity = getArity();
00126 for (unsigned i = 0; i < arity; ++i) {
00127 const AbstractDomainDecl *candidate = getFormalDecl(i);
00128 if (candidate == ADDecl)
00129 return i;
00130 }
00131 assert(false && "Not a formal parameter decl!");
00132 return -1U;
00133 }
00134
00135 DomainType *ModelDecl::getFormalType(unsigned i)
00136 {
00137 assert(isParameterized() &&
00138 "Cannot retrieve formal type from a non-parameterized model!");
00139 return getFormalDecl(i)->getType();
00140 }
00141
00144 SigInstanceDecl *ModelDecl::getFormalSignature(unsigned i) const
00145 {
00146 assert(isParameterized() &&
00147 "Cannot retrieve formal signature from a non-parameterized model!");
00148 return getFormalDecl(i)->getPrincipleSignature();
00149 }
00150
00153 IdentifierInfo *ModelDecl::getFormalIdInfo(unsigned i) const
00154 {
00155 assert(isParameterized() &&
00156 "Cannot retrieve formal identifier from a non-parameterized model!");
00157 return getFormalDecl(i)->getIdInfo();
00158 }
00159
00163 int ModelDecl::getKeywordIndex(IdentifierInfo *keyword) const
00164 {
00165 assert(isParameterized() &&
00166 "Cannot retrieve keyword index from a non-parameterized model!");
00167 for (unsigned i = 0; i < getArity(); ++i)
00168 if (getFormalDecl(i)->getIdInfo() == keyword)
00169 return i;
00170 return -1;
00171 }
00172
00173
00174
00175 SignatureDecl::SignatureDecl(AstResource &resource,
00176 IdentifierInfo *info, const Location &loc)
00177 : Sigoid(resource, AST_SignatureDecl, info, loc)
00178 {
00179 theInstance = new SigInstanceDecl(this);
00180 }
00181
00182
00183
00184
00185 VarietyDecl::VarietyDecl(AstResource &resource,
00186 IdentifierInfo *name, Location loc,
00187 AbstractDomainDecl **formals, unsigned arity)
00188 : Sigoid(resource, AST_VarietyDecl, name, loc),
00189 arity(arity)
00190 {
00191 formalDecls = new AbstractDomainDecl*[arity];
00192 std::copy(formals, formals + arity, formalDecls);
00193 }
00194
00195 SigInstanceDecl *
00196 VarietyDecl::getInstance(DomainTypeDecl **args, unsigned numArgs)
00197 {
00198 llvm::FoldingSetNodeID id;
00199 void *insertPos = 0;
00200 SigInstanceDecl *instance;
00201
00202 SigInstanceDecl::Profile(id, args, numArgs);
00203 instance = instances.FindNodeOrInsertPos(id, insertPos);
00204 if (instance)
00205 return instance;
00206
00207 instance = new SigInstanceDecl(this, args, numArgs);
00208 instances.InsertNode(instance, insertPos);
00209 return instance;
00210 }
00211
00212
00213
00214
00215 Domoid::Domoid(AstResource &resource,
00216 AstKind kind, IdentifierInfo *idInfo, Location loc)
00217 : ModelDecl(resource, kind, idInfo, loc) { }
00218
00219
00220
00221
00222 AddDecl::AddDecl(PercentDecl *percent)
00223 : Decl(AST_AddDecl),
00224 DeclRegion(AST_AddDecl, percent),
00225 carrier(0) { }
00226
00227 Domoid *AddDecl::getImplementedDomoid()
00228 {
00229 Ast *parent = getParent()->asAst();
00230
00231 if (PercentDecl *percent = dyn_cast<PercentDecl>(parent))
00232 return cast<Domoid>(percent->getDefinition());
00233 else {
00234 DomainInstanceDecl *instance = cast<DomainInstanceDecl>(parent);
00235 return instance->getDefinition();
00236 }
00237 }
00238
00239 DomainDecl *AddDecl::getImplementedDomain()
00240 {
00241 return dyn_cast<DomainDecl>(getImplementedDomoid());
00242 }
00243
00244 FunctorDecl *AddDecl::getImplementedFunctor()
00245 {
00246 return dyn_cast<FunctorDecl>(getImplementedDomoid());
00247 }
00248
00249 bool AddDecl::implementsDomain() const
00250 {
00251 return getImplementedDomain() != 0;
00252 }
00253
00254 bool AddDecl::implementsFunctor() const
00255 {
00256 return getImplementedFunctor() != 0;
00257 }
00258
00259
00260
00261
00262 DomainDecl::DomainDecl(AstResource &resource,
00263 IdentifierInfo *name, const Location &loc)
00264 : Domoid(resource, AST_DomainDecl, name, loc),
00265 instance(0)
00266 {
00267 implementation = new AddDecl(getPercent());
00268 }
00269
00270
00271
00272
00273
00274 DomainInstanceDecl *DomainDecl::getInstance()
00275 {
00276 if (instance == 0)
00277 instance = new DomainInstanceDecl(getAstResource(), this);
00278 return instance;
00279 }
00280
00281 void DomainDecl::finalize()
00282 {
00283
00284
00285 getInstance()->finalize();
00286
00287
00288 bits = 1;
00289 }
00290
00291 bool DomainDecl::isFinalized() const
00292 {
00293 return bits == 1;
00294 }
00295
00296
00297
00298
00299 FunctorDecl::FunctorDecl(AstResource &resource,
00300 IdentifierInfo *name, Location loc,
00301 AbstractDomainDecl **formals, unsigned arity)
00302 : Domoid(resource, AST_FunctorDecl, name, loc),
00303 arity(arity)
00304 {
00305 assert(arity && "Cannot construct functors with no arguments!");
00306
00307 formalDecls = new AbstractDomainDecl*[arity];
00308 std::copy(formals, formals + arity, formalDecls);
00309 implementation = new AddDecl(getPercent());
00310 }
00311
00312 DomainInstanceDecl *
00313 FunctorDecl::getInstance(DomainTypeDecl **args, unsigned numArgs)
00314 {
00315 llvm::FoldingSetNodeID id;
00316 void *insertPos = 0;
00317 DomainInstanceDecl *instance;
00318
00319 DomainInstanceDecl::Profile(id, args, numArgs);
00320 instance = instances.FindNodeOrInsertPos(id, insertPos);
00321 if (instance) return instance;
00322
00323 instance = new DomainInstanceDecl(getAstResource(), this, args, numArgs);
00324 instances.InsertNode(instance, insertPos);
00325 return instance;
00326 }
00327
00328
00329 void FunctorDecl::finalize()
00330 {
00331
00332 InstanceSet::iterator I = instances.begin();
00333 InstanceSet::iterator E = instances.end();
00334 for ( ; I != E; ++I)
00335 I->finalize();
00336
00337
00338 bits = 1;
00339 }
00340
00341 bool FunctorDecl::isFinalized() const
00342 {
00343 return bits == 1;
00344 }
00345
00346
00347
00348
00349 SigInstanceDecl::SigInstanceDecl(SignatureDecl *decl)
00350 : Decl(AST_SigInstanceDecl, decl->getIdInfo()),
00351 underlyingSigoid(decl),
00352 arguments(0)
00353 { }
00354
00355 SigInstanceDecl::SigInstanceDecl(VarietyDecl *decl,
00356 DomainTypeDecl **args, unsigned numArgs)
00357 : Decl(AST_SigInstanceDecl, decl->getIdInfo()),
00358 underlyingSigoid(decl)
00359 {
00360 assert(numArgs && "No arguments given to parameterized instance!");
00361 arguments = new DomainTypeDecl*[numArgs];
00362 std::copy(args, args + numArgs, arguments);
00363 }
00364
00365 SignatureDecl *SigInstanceDecl::getSignature() const
00366 {
00367 return dyn_cast<SignatureDecl>(underlyingSigoid);
00368 }
00369
00370 VarietyDecl *SigInstanceDecl::getVariety() const
00371 {
00372 return dyn_cast<VarietyDecl>(underlyingSigoid);
00373 }
00374
00375 unsigned SigInstanceDecl::getArity() const
00376 {
00377 VarietyDecl *variety = getVariety();
00378 if (variety)
00379 return variety->getArity();
00380 return 0;
00381 }
00382
00383 void SigInstanceDecl::Profile(llvm::FoldingSetNodeID &ID,
00384 DomainTypeDecl **args, unsigned numArgs)
00385 {
00386 if (numArgs == 0)
00387 ID.AddPointer(0);
00388 else {
00389 for (unsigned i = 0; i < numArgs; ++i)
00390 ID.AddPointer(args[i]);
00391 }
00392 }
00393
00394
00395
00396
00397 SubroutineDecl::SubroutineDecl(AstKind kind, IdentifierInfo *name, Location loc,
00398 ParamValueDecl **params, unsigned numParams,
00399 DeclRegion *parent)
00400 : Decl(kind, name, loc, parent),
00401 DeclRegion(kind, parent),
00402 opID(PO::NotPrimitive),
00403 numParameters(numParams),
00404 parameters(0),
00405 body(0),
00406 declarationLink(0, FORWARD_TAG)
00407 {
00408 assert(this->denotesSubroutineDecl());
00409
00410 if (numParams > 0)
00411 parameters = new ParamValueDecl*[numParams];
00412 llvm::SmallVector<const Type*, 8> paramTypes;
00413
00414 for (unsigned i = 0; i < numParams; ++i) {
00415 ParamValueDecl *paramDecl = params[i];
00416 parameters[i] = paramDecl;
00417 paramTypes.push_back(paramDecl->getType());
00418 }
00419 }
00420
00421 SubroutineDecl::SubroutineDecl(AstKind kind, IdentifierInfo *name, Location loc,
00422 IdentifierInfo **keywords, SubroutineType *type,
00423 DeclRegion *parent)
00424 : Decl(kind, name, loc, parent),
00425 DeclRegion(kind, parent),
00426 opID(PO::NotPrimitive),
00427 numParameters(type->getArity()),
00428 parameters(0),
00429 body(0),
00430 declarationLink(0, FORWARD_TAG)
00431 {
00432 assert(this->denotesSubroutineDecl());
00433
00434 if (numParameters == 0)
00435 return;
00436
00437 parameters = new ParamValueDecl*[numParameters];
00438 for (unsigned i = 0; i < numParameters; ++i) {
00439 Type *paramType = type->getArgType(i);
00440 ParamValueDecl *param =
00441 new ParamValueDecl(keywords[i], paramType, PM::MODE_DEFAULT, 0);
00442 parameters[i] = param;
00443 }
00444 }
00445
00446 SubroutineDecl::SubroutineDecl(AstKind kind, IdentifierInfo *name, Location loc,
00447 DeclRegion *parent)
00448 : Decl(kind, name, loc, parent),
00449 DeclRegion(kind, parent),
00450 opID(PO::NotPrimitive),
00451 numParameters(0),
00452 parameters(0),
00453 body(0),
00454 declarationLink(0, FORWARD_TAG)
00455 {
00456 assert(this->denotesSubroutineDecl());
00457 }
00458
00459 SubroutineDecl::~SubroutineDecl()
00460 {
00461 if (parameters) {
00462 for (unsigned i = 0; i < numParameters; ++i)
00463 delete parameters[i];
00464 delete[] parameters;
00465 }
00466 }
00467
00468 int SubroutineDecl::getKeywordIndex(IdentifierInfo *key) const
00469 {
00470 for (unsigned i = 0; i < getArity(); ++i) {
00471 if (parameters[i]->getIdInfo() == key)
00472 return i;
00473 }
00474 return -1;
00475 }
00476
00477 int SubroutineDecl::getKeywordIndex(KeywordSelector *key) const
00478 {
00479 return getKeywordIndex(key->getKeyword());
00480 }
00481
00482 bool SubroutineDecl::keywordsMatch(const SubroutineDecl *SRDecl) const
00483 {
00484 unsigned arity = getArity();
00485 if (SRDecl->getArity() == arity) {
00486 for (unsigned i = 0; i < arity; ++i)
00487 if (getParamKeyword(i) != SRDecl->getParamKeyword(i))
00488 return false;
00489 return true;
00490 }
00491 return false;
00492 }
00493
00494 bool SubroutineDecl::paramModesMatch(const SubroutineDecl *SRDecl) const
00495 {
00496 unsigned arity = getArity();
00497 if (SRDecl->getArity() == arity) {
00498 for (unsigned i = 0; i < arity; ++i)
00499 if (getParamMode(i) != SRDecl->getParamMode(i))
00500 return false;
00501 return true;
00502 }
00503 return false;
00504 }
00505
00506 void SubroutineDecl::setDefiningDeclaration(SubroutineDecl *routineDecl)
00507 {
00508
00509
00510 assert(declarationLink.getPointer() == 0 && "Cannot reset base declaration!");
00511 assert(((isa<FunctionDecl>(this) && isa<FunctionDecl>(routineDecl)) ||
00512 (isa<ProcedureDecl>(this) && isa<ProcedureDecl>(routineDecl))) &&
00513 "Defining declarations must be of the same kind as the parent!");
00514
00515
00516 assert(routineDecl->declarationLink.getPointer() == 0);
00517
00518 declarationLink.setPointer(routineDecl);
00519 declarationLink.setInt(DEFINITION_TAG);
00520 routineDecl->declarationLink.setPointer(this);
00521 routineDecl->declarationLink.setInt(FORWARD_TAG);
00522 }
00523
00524 bool SubroutineDecl::hasBody() const
00525 {
00526 return body || getDefiningDeclaration();
00527 }
00528
00529 BlockStmt *SubroutineDecl::getBody()
00530 {
00531 if (body)
00532 return body;
00533
00534 if (SubroutineDecl *definition = getDefiningDeclaration())
00535 return definition->body;
00536
00537 return 0;
00538 }
00539
00540 const Pragma *SubroutineDecl::findPragma(pragma::PragmaID ID) const
00541 {
00542 const_pragma_iterator I = begin_pragmas();
00543 const_pragma_iterator E = end_pragmas();
00544 for ( ; I != E; ++I) {
00545 if (I->getKind() == ID)
00546 return &*I;
00547 }
00548 return 0;
00549 }
00550
00551
00552
00553
00554 ProcedureDecl::ProcedureDecl(AstResource &resource,
00555 IdentifierInfo *name, Location loc,
00556 ParamValueDecl **params, unsigned numParams,
00557 DeclRegion *parent)
00558 : SubroutineDecl(AST_ProcedureDecl, name, loc,
00559 params, numParams, parent)
00560 {
00561
00562 llvm::SmallVector<Type*, 8> paramTypes;
00563 for (unsigned i = 0; i < numParams; ++i)
00564 paramTypes.push_back(params[i]->getType());
00565 correspondingType =
00566 resource.getProcedureType(paramTypes.data(), numParams);
00567 }
00568
00569
00570
00571
00572 FunctionDecl::FunctionDecl(AstResource &resource,
00573 IdentifierInfo *name, Location loc,
00574 ParamValueDecl **params, unsigned numParams,
00575 Type *returnType, DeclRegion *parent)
00576 : SubroutineDecl(AST_FunctionDecl, name, loc,
00577 params, numParams, parent)
00578 {
00579 initializeCorrespondingType(resource, returnType);
00580 }
00581
00582 FunctionDecl::FunctionDecl(AstKind kind, AstResource &resource,
00583 IdentifierInfo *name, Location loc,
00584 EnumerationType *returnType, DeclRegion *parent)
00585 : SubroutineDecl(kind, name, loc, parent)
00586 {
00587 initializeCorrespondingType(resource, returnType);
00588 }
00589
00590 void FunctionDecl::initializeCorrespondingType(AstResource &resource,
00591 Type *returnType)
00592 {
00593 llvm::SmallVector<Type*, 8> paramTypes;
00594 for (unsigned i = 0; i < numParameters; ++i)
00595 paramTypes.push_back(parameters[i]->getType());
00596 correspondingType =
00597 resource.getFunctionType(paramTypes.data(), numParameters, returnType);
00598 }
00599
00600
00601
00602
00603 IncompleteTypeDecl::IncompleteTypeDecl(AstResource &resource,
00604 IdentifierInfo *name, Location loc,
00605 DeclRegion *region)
00606 : TypeDecl(AST_IncompleteTypeDecl, name, loc, region),
00607 completion(0)
00608 {
00609
00610
00611 IncompleteType *rootType = resource.createIncompleteType(this);
00612 CorrespondingType = resource.createIncompleteSubtype(name, rootType);
00613 }
00614
00615 bool IncompleteTypeDecl::isCompatibleCompletion(const TypeDecl *decl) const
00616 {
00617 const DeclRegion *thisRegion = this->getDeclRegion();
00618 const DeclRegion *completion = decl->getDeclRegion();
00619
00620 if (this->hasCompletion())
00621 return false;
00622
00623 if (thisRegion == completion)
00624 return true;
00625
00626 if (isa<PercentDecl>(thisRegion) && isa<AddDecl>(completion) &&
00627 thisRegion == completion->getParent())
00628 return true;
00629
00630 return false;
00631 }
00632
00633 bool IncompleteTypeDecl::completionIsVisibleIn(const DeclRegion *region) const
00634 {
00635 if (!hasCompletion())
00636 return false;
00637
00638 const DeclRegion *target = getDeclRegion();
00639
00640 do {
00641 if (target == region)
00642 return true;
00643 } while ((region = region->getParent()));
00644
00645 return false;
00646 }
00647
00648
00649
00650
00651 DomainTypeDecl::DomainTypeDecl(AstKind kind, AstResource &resource,
00652 IdentifierInfo *name, Location loc)
00653 : TypeDecl(kind, name, loc),
00654 DeclRegion(kind)
00655 {
00656 assert(this->denotesDomainTypeDecl());
00657 CorrespondingType = resource.createDomainType(this);
00658 }
00659
00660
00661
00662
00663 AbstractDomainDecl::AbstractDomainDecl(AstResource &resource,
00664 IdentifierInfo *name, Location loc,
00665 SigInstanceDecl *sig)
00666 : DomainTypeDecl(AST_AbstractDomainDecl, resource, name, loc)
00667 {
00668 Sigoid *sigoid = sig->getSigoid();
00669 PercentDecl *percent = sigoid->getPercent();
00670 DeclRewriter rewriter(sigoid->getAstResource(), this, percent);
00671
00672
00673
00674 rewriter.addTypeRewrite(sigoid->getPercentType(), getType());
00675
00676
00677
00678
00679 rewriter.installRewrites(sig);
00680
00681 sigset.addDirectSignature(sig, rewriter);
00682 addDeclarationsUsingRewrites(rewriter, percent);
00683 }
00684
00685
00686
00687 DomainInstanceDecl::DomainInstanceDecl(AstResource &resource,
00688 DomainDecl *domain)
00689 : DomainTypeDecl(AST_DomainInstanceDecl, resource, domain->getIdInfo()),
00690 definition(domain)
00691 {
00692 PercentDecl *percent = domain->getPercent();
00693
00694
00695
00696 percent->addObserver(this);
00697
00698
00699 initializeInstance(domain);
00700 }
00701
00702 DomainInstanceDecl::DomainInstanceDecl(AstResource &resource,
00703 FunctorDecl *functor,
00704 DomainTypeDecl **args, unsigned numArgs)
00705 : DomainTypeDecl(AST_DomainInstanceDecl, resource, functor->getIdInfo()),
00706 definition(functor)
00707 {
00708 assert(functor->getArity() == numArgs &&
00709 "Wrong number of arguments for domain instance!");
00710
00711 arguments = new DomainTypeDecl*[numArgs];
00712 std::copy(args, args + numArgs, arguments);
00713
00714
00715
00716 PercentDecl *percent = functor->getPercent();
00717 percent->addObserver(this);
00718
00719
00720 initializeInstance(functor);
00721 }
00722
00723 void DomainInstanceDecl::initializeInstance(Domoid *definition)
00724 {
00725 AstResource &resource = definition->getAstResource();
00726 PercentDecl *percent = definition->getPercent();
00727
00728
00729 DeclRewriter *rewriter = new DeclRewriter(resource, this, percent);
00730 rewriter->addTypeRewrite(definition->getPercentType(), getType());
00731 rewriter->installRewrites(getType());
00732 addDeclarationsUsingRewrites(*rewriter, percent);
00733
00734
00735 const SignatureSet &SS = definition->getSignatureSet();
00736 for (SignatureSet::const_iterator I = SS.begin(); I != SS.end(); ++I)
00737 sigset.addDirectSignature(*I, *rewriter);
00738
00739
00740
00741 if (definition->isFinalized()) {
00742 initializeRepresentation(*rewriter);
00743 delete rewriter;
00744 }
00745 else {
00746 carrier = rewriter;
00747 representationType = 0;
00748 }
00749 }
00750
00751 void DomainInstanceDecl::finalize()
00752 {
00753
00754
00755 if (representationType) return;
00756
00757 DeclRewriter *rewriter = carrier.get<DeclRewriter*>();
00758 initializeRepresentation(*rewriter);
00759 delete rewriter;
00760 }
00761
00762 void DomainInstanceDecl::initializeRepresentation(DeclRewriter &rewriter)
00763 {
00764 AddDecl *orig = definition->getImplementation();
00765 CarrierDecl *decl = 0;
00766
00767
00768
00769
00770
00771
00772
00773
00774 assert(rewriter.getContext() == this && "Inconsistent rewrite context!");
00775 rewriter.setOrigin(orig);
00776
00777
00778
00779 if (orig->hasCarrier()) {
00780 decl = rewriter.rewriteCarrierDecl(orig->getCarrier());
00781
00782
00783 PrimaryType *rep = decl->getType();
00784
00785 if (DomainType *domain = dyn_cast<DomainType>(rep)) {
00786 DomainInstanceDecl *instance = domain->getInstanceDecl();
00787 rep = instance->getRepresentationType();
00788 }
00789 representationType = rep;
00790 }
00791 carrier = decl;
00792 }
00793
00794 bool DomainInstanceDecl::isDependent() const
00795 {
00796 for (unsigned i = 0; i < getArity(); ++i) {
00797 const DomainType *param = cast<DomainType>(getActualParamType(i));
00798 if (param->isAbstract())
00799 return true;
00800 if (param->denotesPercent())
00801 return true;
00802 if (param->getInstanceDecl()->isDependent())
00803 return true;
00804 }
00805 return false;
00806 }
00807
00808 unsigned DomainInstanceDecl::getArity() const
00809 {
00810 if (getType()->denotesPercent())
00811 return 0;
00812 if (FunctorDecl *functor = dyn_cast<FunctorDecl>(definition))
00813 return functor->getArity();
00814 return 0;
00815 }
00816
00817 void DomainInstanceDecl::notifyAddDecl(Decl *decl)
00818 {
00819 AstResource &resource = getDefinition()->getAstResource();
00820 DeclRewriter rewriter(resource, this, decl->getDeclRegion());
00821 rewriter.addTypeRewrite(getDefinition()->getPercentType(), getType());
00822 rewriter.installRewrites(getType());
00823 addDeclarationUsingRewrites(rewriter, decl);
00824 }
00825
00826 void DomainInstanceDecl::notifyRemoveDecl(Decl *decl)
00827 {
00828
00829 }
00830
00831 void DomainInstanceDecl::Profile(llvm::FoldingSetNodeID &id,
00832 DomainTypeDecl **args, unsigned numArgs)
00833 {
00834 for (unsigned i = 0; i < numArgs; ++i)
00835 id.AddPointer(args[i]);
00836 }
00837
00838
00839
00840
00841 PercentDecl::PercentDecl(AstResource &resource, ModelDecl *model)
00842 : DomainTypeDecl(AST_PercentDecl, resource,
00843 resource.getIdentifierInfo("%"), model->getLocation()),
00844 underlyingModel(model) { }
00845
00846
00847
00848
00849 PM::ParameterMode ParamValueDecl::getExplicitParameterMode() const
00850 {
00851 return static_cast<PM::ParameterMode>(bits);
00852 }
00853
00854 void ParamValueDecl::setParameterMode(PM::ParameterMode mode)
00855 {
00856 bits = mode;
00857 }
00858
00859 bool ParamValueDecl::parameterModeSpecified() const
00860 {
00861 return getExplicitParameterMode() != PM::MODE_DEFAULT;
00862 }
00863
00864 PM::ParameterMode ParamValueDecl::getParameterMode() const
00865 {
00866 PM::ParameterMode mode = getExplicitParameterMode();
00867 if (mode == PM::MODE_DEFAULT)
00868 return PM::MODE_IN;
00869 else
00870 return mode;
00871 }
00872
00873
00874
00875 EnumLiteral::EnumLiteral(AstResource &resource,
00876 IdentifierInfo *name, Location loc, unsigned index,
00877 EnumerationType *type, EnumerationDecl *parent)
00878 : FunctionDecl(AST_EnumLiteral, resource, name, loc, type, parent),
00879 index(index)
00880 {
00881 setAsPrimitive(PO::ENUM_op);
00882 }
00883
00884
00885
00886 EnumerationDecl::EnumerationDecl(AstResource &resource,
00887 IdentifierInfo *name, Location loc,
00888 std::pair<IdentifierInfo*, Location> *elems,
00889 unsigned numElems, DeclRegion *parent)
00890 : TypeDecl(AST_EnumerationDecl, name, loc, parent),
00891 DeclRegion(AST_EnumerationDecl, parent),
00892 numLiterals(numElems)
00893 {
00894
00895 EnumerationType *root = resource.createEnumType(this);
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 EnumerationType *base = root->getBaseSubtype();
00916 Expr *lower = new FirstAE(base, 0);
00917 Expr *upper = new LastAE(base, 0);
00918
00919
00920 EnumerationType *subtype;
00921 subtype = resource.createEnumSubtype(root, lower, upper);
00922 CorrespondingType = subtype;
00923
00924
00925
00926 for (unsigned i = 0; i < numElems; ++i) {
00927 IdentifierInfo *name = elems[i].first;
00928 Location loc = elems[i].second;
00929 EnumLiteral *elem =
00930 new EnumLiteral(resource, name, loc, i, subtype, this);
00931 addDecl(elem);
00932 }
00933
00934
00935
00936 posAttribute = PosAD::create(resource, this);
00937 valAttribute = ValAD::create(resource, this);
00938 }
00939
00940 EnumerationDecl::EnumerationDecl(AstResource &resource, IdentifierInfo *name,
00941 Location loc,
00942 EnumerationType *subtype, DeclRegion *region)
00943 : TypeDecl(AST_EnumerationDecl, name, loc, region),
00944 DeclRegion(AST_EnumerationDecl, region),
00945 numLiterals(0)
00946 {
00947 bits |= Subtype_FLAG;
00948 CorrespondingType = resource.createEnumSubtype(subtype, this);
00949 posAttribute = PosAD::create(resource, this);
00950 valAttribute = ValAD::create(resource, this);
00951 }
00952
00953 EnumerationDecl::EnumerationDecl(AstResource &resource, IdentifierInfo *name,
00954 Location loc,
00955 EnumerationType *subtype,
00956 Expr *lower, Expr *upper, DeclRegion *region)
00957 : TypeDecl(AST_EnumerationDecl, name, loc, region),
00958 DeclRegion(AST_EnumerationDecl, region),
00959 numLiterals(0)
00960 {
00961 bits |= Subtype_FLAG;
00962 CorrespondingType = resource.createEnumSubtype(subtype, lower, upper, this);
00963 posAttribute = PosAD::create(resource, this);
00964 valAttribute = ValAD::create(resource, this);
00965 }
00966
00967 void EnumerationDecl::generateImplicitDeclarations(AstResource &resource)
00968 {
00969
00970 if (isSubtypeDeclaration())
00971 return;
00972
00973 EnumerationType *type = getType();
00974 Location loc = getLocation();
00975
00976 addDecl(resource.createPrimitiveDecl(PO::EQ_op, loc, type, this));
00977 addDecl(resource.createPrimitiveDecl(PO::NE_op, loc, type, this));
00978 addDecl(resource.createPrimitiveDecl(PO::LT_op, loc, type, this));
00979 addDecl(resource.createPrimitiveDecl(PO::LE_op, loc, type, this));
00980 addDecl(resource.createPrimitiveDecl(PO::GT_op, loc, type, this));
00981 addDecl(resource.createPrimitiveDecl(PO::GE_op, loc, type, this));
00982 }
00983
00984 void EnumerationDecl::generateBooleanDeclarations(AstResource &resource)
00985 {
00986
00987
00988 generateImplicitDeclarations(resource);
00989
00990 EnumerationType *type = getType();
00991 Location loc = getLocation();
00992
00993 addDecl(resource.createPrimitiveDecl(PO::LNOT_op, loc, type, this));
00994 addDecl(resource.createPrimitiveDecl(PO::LAND_op, loc, type, this));
00995 addDecl(resource.createPrimitiveDecl(PO::LXOR_op, loc, type, this));
00996 addDecl(resource.createPrimitiveDecl(PO::LOR_op, loc, type, this));
00997 }
00998
00999 EnumLiteral *EnumerationDecl::findLiteral(IdentifierInfo *name)
01000 {
01001 PredRange range = findDecls(name);
01002
01003 if (range.first != range.second)
01004 return cast<EnumLiteral>(*range.first);
01005 return 0;
01006 }
01007
01008 const EnumLiteral *EnumerationDecl::findCharacterLiteral(char ch) const
01009 {
01010 char target[] = { '\'', ch, '\'', 0 };
01011
01012
01013
01014 for (ConstDeclIter I = beginDecls(); I != endDecls(); ++I) {
01015 if (EnumLiteral *lit = dyn_cast<EnumLiteral>(*I)) {
01016 const char *name = lit->getIdInfo()->getString();
01017 if (strcmp(name, target) == 0)
01018 return lit;
01019 }
01020 }
01021 return 0;
01022 }
01023
01024 const EnumLiteral *EnumerationDecl::getFirstLiteral() const
01025 {
01026 return const_cast<EnumerationDecl*>(this)->getFirstLiteral();
01027 }
01028
01029 EnumLiteral *EnumerationDecl::getFirstLiteral() {
01030 for (DeclIter I = beginDecls(); I != endDecls(); ++I) {
01031 if (EnumLiteral *lit = dyn_cast<EnumLiteral>(*I))
01032 return lit;
01033 }
01034 assert(false && "Enumeration decl does not contain any literals!");
01035 return 0;
01036 }
01037
01038 const EnumLiteral *EnumerationDecl::getLastLiteral() const
01039 {
01040 return const_cast<EnumerationDecl*>(this)->getLastLiteral();
01041 }
01042
01043 EnumLiteral *EnumerationDecl::getLastLiteral()
01044 {
01045 for (reverse_decl_iter I = rbegin_decls(); I != rend_decls(); ++I) {
01046 if (EnumLiteral *lit = dyn_cast<EnumLiteral>(*I))
01047 return lit;
01048 }
01049 assert(false && "Enumeration decl does not contain any literals!");
01050 return 0;
01051 }
01052
01053 FunctionAttribDecl *EnumerationDecl::getAttribute(attrib::AttributeID ID)
01054 {
01055 FunctionAttribDecl *attrib = 0;
01056
01057 switch (ID) {
01058
01059 default:
01060 assert(false && "Invalid attribute for enumeration type!");
01061 attrib = 0;
01062 break;
01063
01064 case attrib::Pos:
01065 attrib = getPosAttribute();
01066 break;
01067
01068 case attrib::Val:
01069 attrib = getValAttribute();
01070 }
01071
01072 return attrib;
01073 }
01074
01075
01076
01077
01078 IntegerDecl::IntegerDecl(AstResource &resource,
01079 IdentifierInfo *name, Location loc,
01080 Expr *lower, Expr *upper,
01081 DeclRegion *parent)
01082 : TypeDecl(AST_IntegerDecl, name, loc, parent),
01083 DeclRegion(AST_IntegerDecl, parent),
01084 lowExpr(lower), highExpr(upper)
01085 {
01086 llvm::APInt lowVal;
01087 llvm::APInt highVal;
01088
01089 assert(lower->isStaticDiscreteExpr());
01090 assert(upper->isStaticDiscreteExpr());
01091
01092 lower->staticDiscreteValue(lowVal);
01093 upper->staticDiscreteValue(highVal);
01094
01095 IntegerType *base = resource.createIntegerType(this, lowVal, highVal);
01096 CorrespondingType = resource.createIntegerSubtype(base, lowVal, highVal);
01097
01098
01099
01100 posAttribute = PosAD::create(resource, this);
01101 valAttribute = ValAD::create(resource, this);
01102 }
01103
01104
01105 IntegerDecl::IntegerDecl(AstResource &resource,
01106 IdentifierInfo *name, Location loc,
01107 IntegerType *subtype, DeclRegion *parent)
01108 : TypeDecl(AST_IntegerDecl, name, loc, parent),
01109 DeclRegion(AST_IntegerDecl, parent),
01110 lowExpr(0), highExpr(0)
01111 {
01112 bits = true;
01113 CorrespondingType = resource.createIntegerSubtype(subtype, this);
01114 posAttribute = PosAD::create(resource, this);
01115 valAttribute = ValAD::create(resource, this);
01116 }
01117
01118 IntegerDecl::IntegerDecl(AstResource &resource,
01119 IdentifierInfo *name, Location loc,
01120 IntegerType *subtype,
01121 Expr *lower, Expr *upper, DeclRegion *parent)
01122 : TypeDecl(AST_IntegerDecl, name, loc, parent),
01123 DeclRegion(AST_IntegerDecl, parent),
01124 lowExpr(lower), highExpr(upper)
01125 {
01126 bits = true;
01127 CorrespondingType = resource.createIntegerSubtype
01128 (subtype, lower, upper, this);
01129 posAttribute = PosAD::create(resource, this);
01130 valAttribute = ValAD::create(resource, this);
01131 }
01132
01133
01134
01135
01136 void IntegerDecl::generateImplicitDeclarations(AstResource &resource)
01137 {
01138
01139 if (isSubtypeDeclaration())
01140 return;
01141
01142 IntegerType *type = getBaseSubtype();
01143 Location loc = getLocation();
01144
01145 addDecl(resource.createPrimitiveDecl(PO::EQ_op, loc, type, this));
01146 addDecl(resource.createPrimitiveDecl(PO::NE_op, loc, type, this));
01147 addDecl(resource.createPrimitiveDecl(PO::LT_op, loc, type, this));
01148 addDecl(resource.createPrimitiveDecl(PO::GT_op, loc, type, this));
01149 addDecl(resource.createPrimitiveDecl(PO::LE_op, loc, type, this));
01150 addDecl(resource.createPrimitiveDecl(PO::GE_op, loc, type, this));
01151 addDecl(resource.createPrimitiveDecl(PO::ADD_op, loc, type, this));
01152 addDecl(resource.createPrimitiveDecl(PO::SUB_op, loc, type, this));
01153 addDecl(resource.createPrimitiveDecl(PO::MUL_op, loc, type, this));
01154 addDecl(resource.createPrimitiveDecl(PO::DIV_op, loc, type, this));
01155 addDecl(resource.createPrimitiveDecl(PO::MOD_op, loc, type, this));
01156 addDecl(resource.createPrimitiveDecl(PO::REM_op, loc, type, this));
01157 addDecl(resource.createPrimitiveDecl(PO::POW_op, loc, type, this));
01158 addDecl(resource.createPrimitiveDecl(PO::NEG_op, loc, type, this));
01159 addDecl(resource.createPrimitiveDecl(PO::POS_op, loc, type, this));
01160 }
01161
01162 FunctionAttribDecl *IntegerDecl::getAttribute(attrib::AttributeID ID)
01163 {
01164 FunctionAttribDecl *attrib = 0;
01165
01166 switch (ID) {
01167
01168 default:
01169 assert(false && "Invalid attribute for integer type!");
01170 attrib = 0;
01171 break;
01172
01173 case attrib::Pos:
01174 attrib = getPosAttribute();
01175 break;
01176
01177 case attrib::Val:
01178 attrib = getValAttribute();
01179 }
01180
01181 return attrib;
01182 }
01183
01184
01185
01186 ArrayDecl::ArrayDecl(AstResource &resource,
01187 IdentifierInfo *name, Location loc,
01188 unsigned rank, DSTDefinition **indices,
01189 Type *component, bool isConstrained, DeclRegion *parent)
01190 : TypeDecl(AST_ArrayDecl, name, loc, parent),
01191 DeclRegion(AST_ArrayDecl, parent),
01192 indices(indices, indices + rank)
01193 {
01194 assert(rank != 0 && "Missing indices!");
01195
01196
01197 llvm::SmallVector<DiscreteType*, 8> indexTypes(rank);
01198 for (unsigned i = 0; i < rank; ++i)
01199 indexTypes[i] = indices[0]->getType();
01200
01201 ArrayType *base = resource.createArrayType(
01202 this, rank, &indexTypes[0], component, isConstrained);
01203
01204
01205 CorrespondingType = resource.createArraySubtype(name, base);
01206 }
01207
01208
01209
01210 RecordDecl::RecordDecl(AstResource &resource, IdentifierInfo *name,
01211 Location loc, DeclRegion *parent)
01212 : TypeDecl(AST_RecordDecl, name, loc, parent),
01213 DeclRegion(AST_RecordDecl, parent), componentCount(0)
01214 {
01215 RecordType *base = resource.createRecordType(this);
01216 CorrespondingType = resource.createRecordSubtype(name, base);
01217 }
01218
01219 ComponentDecl *RecordDecl::addComponent(IdentifierInfo *name, Location loc,
01220 Type *type)
01221 {
01222 ComponentDecl *component;
01223 component = new ComponentDecl(name, loc, type, componentCount, this);
01224 componentCount++;
01225 addDecl(component);
01226 return component;
01227 }
01228
01229 ComponentDecl *RecordDecl::getComponent(unsigned i)
01230 {
01231
01232 return cast<ComponentDecl>(getDecl(i));
01233 }
01234
01235 ComponentDecl *RecordDecl::getComponent(IdentifierInfo *name)
01236 {
01237 PredRange range = findDecls(name);
01238 if (range.first == range.second)
01239 return 0;
01240 return cast<ComponentDecl>(*range.first);
01241 }
01242
01243
01244
01245 AccessDecl::AccessDecl(AstResource &resource, IdentifierInfo *name, Location loc,
01246 Type *targetType, DeclRegion *parent)
01247 : TypeDecl(AST_AccessDecl, name, loc, parent),
01248 DeclRegion(AST_AccessDecl, parent)
01249 {
01250 AccessType *base = resource.createAccessType(this, targetType);
01251 CorrespondingType = resource.createAccessSubtype(name, base);
01252 }
01253
01254 void AccessDecl::generateImplicitDeclarations(AstResource &resource)
01255 {
01256
01257
01258 AccessType *type = getType();
01259 Location loc = getLocation();
01260
01261 addDecl(resource.createPrimitiveDecl(PO::EQ_op, loc, type, this));
01262 addDecl(resource.createPrimitiveDecl(PO::NE_op, loc, type, this));
01263 }