This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- ast/Decl.cpp ------------------------------------------ -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 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 // Decl 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 // ModelDecl 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 // Rewrite % nodes of the signature to the % nodes of this model and map any 00093 // formal arguments to the actuals. 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 // SignatureDecl 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 // VarietyDecl 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 // Domoid 00214 00215 Domoid::Domoid(AstResource &resource, 00216 AstKind kind, IdentifierInfo *idInfo, Location loc) 00217 : ModelDecl(resource, kind, idInfo, loc) { } 00218 00219 //===----------------------------------------------------------------------===// 00220 // AddDecl 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 // DomainDecl 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 // FIXME: This is a temporary solution to the problem of initializing domain 00271 // instances before the corresponding DomDecl is fully initialized. In 00272 // particular, we need a machanism similar to the observer failcility in 00273 // DeclRegion but for signature sets. 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 // Construct (if needed) and notify our one and only instance that this 00284 // domain is finished. 00285 getInstance()->finalize(); 00286 00287 // Mark this domain a finalized. 00288 bits = 1; 00289 } 00290 00291 bool DomainDecl::isFinalized() const 00292 { 00293 return bits == 1; 00294 } 00295 00296 //===----------------------------------------------------------------------===// 00297 // FunctorDecl 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 // Notify any instances that this functor is finished. 00332 InstanceSet::iterator I = instances.begin(); 00333 InstanceSet::iterator E = instances.end(); 00334 for ( ; I != E; ++I) 00335 I->finalize(); 00336 00337 // Mark this functor as finalized. 00338 bits = 1; 00339 } 00340 00341 bool FunctorDecl::isFinalized() const 00342 { 00343 return bits == 1; 00344 } 00345 00346 //===----------------------------------------------------------------------===// 00347 // SigInstanceDecl 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 // SubroutineDecl 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 // Check that we are not reseting the link, and that the given subroutine if 00509 // of a compatible kind. 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 // Check that the defining declaration does not already have its link set. 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 // ProcedureDecl 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 // Construct our type. 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 // FunctionDecl 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 // IncompleteTypeDecl 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 // Create the root and first subtype defined by this incomplete type 00610 // declaration. 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 // DomainTypeDecl 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 // AbstractDomainDecl 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 // Establish a mapping from the % node of the signature to the type of this 00673 // abstract domain. 00674 rewriter.addTypeRewrite(sigoid->getPercentType(), getType()); 00675 00676 // Establish mappings from the formal parameters of the signature to the 00677 // actual parameters of the given instance (this is a no-op if the signature 00678 // is not parametrized). 00679 rewriter.installRewrites(sig); 00680 00681 sigset.addDirectSignature(sig, rewriter); 00682 addDeclarationsUsingRewrites(rewriter, percent); 00683 } 00684 00685 //===----------------------------------------------------------------------===// 00686 // DomainInstanceDecl 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 // Ensure that we are notified if the declarations provided by the percent 00695 // node of the defining domoid change. 00696 percent->addObserver(this); 00697 00698 // Initialize the available declarations. 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 // Ensure that we are notified if the declarations provided by percent 00715 // change. 00716 PercentDecl *percent = functor->getPercent(); 00717 percent->addObserver(this); 00718 00719 // Initialize the available declarations. 00720 initializeInstance(functor); 00721 } 00722 00723 void DomainInstanceDecl::initializeInstance(Domoid *definition) 00724 { 00725 AstResource &resource = definition->getAstResource(); 00726 PercentDecl *percent = definition->getPercent(); 00727 00728 // Obtain a rewritten version of the public exports provided by percent. 00729 DeclRewriter *rewriter = new DeclRewriter(resource, this, percent); 00730 rewriter->addTypeRewrite(definition->getPercentType(), getType()); 00731 rewriter->installRewrites(getType()); 00732 addDeclarationsUsingRewrites(*rewriter, percent); 00733 00734 // Populate our signature set with a rewritten version. 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 // Initialize the body if the defining domoid is finalized. Otherwise hold 00740 // onto the rewriter untill we are in a finalized state. 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 // If we have not yet initialized the representation of this instance 00754 // compute it now. 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 // Set the origin of the rewriter to the add declaration of our 00768 // implementation. This ensures that if the representation of this domain 00769 // depends on additional declarations, only those appearing in the "add" are 00770 // rewritten. Also note that the context of the rewriter remains associated 00771 // with this instance, resulting in all new declaration nodes being declared 00772 // "inside" this instance (but are otherwise invisible since they are not 00773 // added to the region via a call to addDecl). 00774 assert(rewriter.getContext() == this && "Inconsistent rewrite context!"); 00775 rewriter.setOrigin(orig); 00776 00777 // FIXME: No need for the conditional when it is guaranteed that a finalized 00778 // domain defines a carrier. 00779 if (orig->hasCarrier()) { 00780 decl = rewriter.rewriteCarrierDecl(orig->getCarrier()); 00781 00782 // Resolve the representation type of this domain. 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 // FIXME: Implement. 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 // PercentDecl 00840 00841 PercentDecl::PercentDecl(AstResource &resource, ModelDecl *model) 00842 : DomainTypeDecl(AST_PercentDecl, resource, 00843 resource.getIdentifierInfo("%"), model->getLocation()), 00844 underlyingModel(model) { } 00845 00846 //===----------------------------------------------------------------------===// 00847 // ParamValueDecl 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 // EnumLiteral 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 // EnumerationDecl 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 // Build the root type corresponding to this declaration. 00895 EnumerationType *root = resource.createEnumType(this); 00896 00897 // Now, we have a bootstrap issue here to contend with. We need to perform 00898 // the following sequence of actions: 00899 // 00900 // - Build the root type of this declaration. 00901 // 00902 // - Build the first constrained subtype of the root type. 00903 // 00904 // - Build the set of EnumLiteral's associated with this declaration, 00905 // each of which has the first constrained subtype as type. 00906 // 00907 // However, in order to construct the first subtype we need the literals to 00908 // be available so that we may form the constraint, but we also need the 00909 // first subtype available to construct the literals. 00910 // 00911 // The solution to this circularity is to specify the constraint of the 00912 // first subtype as attribute expressions over the base subtype. In source 00913 // code, the constraint would be similar to "E'Base'First .. E'Base'Last". 00914 // Note that these attributes are static expressions. 00915 EnumerationType *base = root->getBaseSubtype(); 00916 Expr *lower = new FirstAE(base, 0); 00917 Expr *upper = new LastAE(base, 0); 00918 00919 // Construct the subtype. 00920 EnumerationType *subtype; 00921 subtype = resource.createEnumSubtype(root, lower, upper); 00922 CorrespondingType = subtype; 00923 00924 // Construct enumeration literals for each Id/Location pair and add them to 00925 // this decls declarative region. 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 // Now that the type is in place initialize the required attribute 00935 // declarations. 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; // Mark this as a subtype. 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; // Mark this as a subtype. 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 // Subtype declarations do not provide any additional operations. 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 // Boolean exports all of the operations a standard enumeration type does, 00987 // plus the logical operations "and", "or", and "not". 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 // Traverse the declarative region and do a case by case comparison of the 01013 // literal names and the target string. 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 // IntegerDecl 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 // Initialize the required attribute declarations now that the type is in 01099 // place. 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; // Mark this as a subtype. 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; // Mark this as a subtype. 01127 CorrespondingType = resource.createIntegerSubtype 01128 (subtype, lower, upper, this); 01129 posAttribute = PosAD::create(resource, this); 01130 valAttribute = ValAD::create(resource, this); 01131 } 01132 01133 // Note that we could perform these initializations in the constructor, but it 01134 // would cause difficulties when the language primitive types are first being 01135 // declared. For now this is a separate method which called separately. 01136 void IntegerDecl::generateImplicitDeclarations(AstResource &resource) 01137 { 01138 // Subtype declarations do not provide any additional operations. 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 // ArrayDecl 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 // Extract the type nodes of the DSTDefinitions. 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 // Create the first subtype. 01205 CorrespondingType = resource.createArraySubtype(name, base); 01206 } 01207 01208 //===----------------------------------------------------------------------===// 01209 // RecordDecl 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 // FIXME: Compensate for the presence of an equality operator when present. 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 // AccessDecl 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 // FIXME: We will eventually need to specify the operand type specifically 01257 // as an unconstrained access type. 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 }