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 }