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/DeclRegion.cpp ------------------------------------ -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 00010 #include "comma/ast/AstResource.h" 00011 #include "comma/ast/AstRewriter.h" 00012 #include "comma/ast/Decl.h" 00013 #include "comma/ast/DeclRegion.h" 00014 #include "comma/ast/DeclRewriter.h" 00015 #include "comma/ast/Stmt.h" 00016 #include "comma/ast/Type.h" 00017 00018 #include "llvm/Support/Casting.h" 00019 00020 #include <algorithm> 00021 #include <cstring> 00022 #include <cassert> 00023 00024 using namespace comma; 00025 using llvm::dyn_cast; 00026 using llvm::cast; 00027 using llvm::isa; 00028 00029 void DeclRegion::addDecl(Decl *decl) { 00030 declarations.push_back(decl); 00031 notifyObserversOfAddition(decl); 00032 } 00033 00034 void DeclRegion::addDeclarationUsingRewrites(DeclRewriter &rewrites, 00035 Decl *decl) 00036 { 00037 addDecl(rewrites.rewriteDecl(decl)); 00038 } 00039 00040 void 00041 DeclRegion::addDeclarationsUsingRewrites(DeclRewriter &rewrites, 00042 const DeclRegion *region) 00043 { 00044 ConstDeclIter E = region->endDecls(); 00045 for (ConstDeclIter I = region->beginDecls(); I != E; ++I) 00046 addDecl(rewrites.rewriteDecl(*I)); 00047 } 00048 00049 Decl *DeclRegion::findDecl(IdentifierInfo *name, Type *type) 00050 { 00051 DeclIter endIter = endDecls(); 00052 for (DeclIter iter = beginDecls(); iter != endIter; ++iter) { 00053 Decl *decl = *iter; 00054 if (decl->getIdInfo() == name) { 00055 Type *candidate = 0; 00056 if (TypeDecl *TD = dyn_cast<TypeDecl>(decl)) 00057 candidate = TD->getType(); 00058 else if (SubroutineDecl *SD = dyn_cast<SubroutineDecl>(decl)) 00059 candidate = SD->getType(); 00060 else if (ValueDecl *VD = dyn_cast<ValueDecl>(decl)) 00061 candidate = VD->getType(); 00062 00063 if (candidate && type == candidate) 00064 return decl; 00065 } 00066 } 00067 return 0; 00068 } 00069 00070 DeclRegion::PredRange 00071 DeclRegion::findDecls(IdentifierInfo *name) const 00072 { 00073 struct Pred : public PredIter::Predicate { 00074 Pred(IdentifierInfo *name) : name(name) { } 00075 bool operator()(const Decl *decl) { 00076 return decl->getIdInfo() == name; 00077 } 00078 IdentifierInfo *name; 00079 }; 00080 ConstDeclIter begin = beginDecls(); 00081 ConstDeclIter end = endDecls(); 00082 Pred *pred = new Pred(name); 00083 return PredRange(PredIter(pred, begin, end), PredIter(end)); 00084 } 00085 00086 bool DeclRegion::removeDecl(Decl *decl) 00087 { 00088 DeclIter result = std::find(beginDecls(), endDecls(), decl); 00089 if (result != endDecls()) { 00090 declarations.erase(result); 00091 return true; 00092 } 00093 return false; 00094 } 00095 00096 bool DeclRegion::containsDecl(const Decl *decl) const 00097 { 00098 ConstDeclIter I = beginDecls(); 00099 ConstDeclIter E = endDecls(); 00100 ConstDeclIter P = std::find(I, E, decl); 00101 return P != E; 00102 } 00103 00104 bool DeclRegion::collectFunctionDecls( 00105 IdentifierInfo *name, llvm::SmallVectorImpl<SubroutineDecl*> &dst) 00106 { 00107 PredRange range = findDecls(name); 00108 size_t size = dst.size(); 00109 00110 for (PredIter iter = range.first; iter != range.second; ++iter) { 00111 if (FunctionDecl *decl = dyn_cast<FunctionDecl>(*iter)) 00112 dst.push_back(decl); 00113 } 00114 return size != dst.size(); 00115 } 00116 00117 bool DeclRegion::collectProcedureDecls( 00118 IdentifierInfo *name, llvm::SmallVectorImpl<SubroutineDecl*> &dst) 00119 { 00120 PredRange range = findDecls(name); 00121 size_t size = dst.size(); 00122 00123 for (PredIter iter = range.first; iter != range.second; ++iter) { 00124 if (ProcedureDecl *decl = dyn_cast<ProcedureDecl>(*iter)) 00125 dst.push_back(decl); 00126 } 00127 return size != dst.size(); 00128 } 00129 00130 const Ast *DeclRegion::asAst() const 00131 { 00132 switch (regionKind) { 00133 default: 00134 assert(false && "Unknown delcarative region kind!"); 00135 return 0; 00136 case Ast::AST_PercentDecl: 00137 return static_cast<const PercentDecl*>(this); 00138 case Ast::AST_FunctionDecl: 00139 return static_cast<const FunctionDecl*>(this); 00140 case Ast::AST_ProcedureDecl: 00141 return static_cast<const ProcedureDecl*>(this); 00142 case Ast::AST_AbstractDomainDecl: 00143 return static_cast<const AbstractDomainDecl*>(this); 00144 case Ast::AST_DomainInstanceDecl: 00145 return static_cast<const DomainInstanceDecl*>(this); 00146 case Ast::AST_AddDecl: 00147 return static_cast<const AddDecl*>(this); 00148 case Ast::AST_EnumerationDecl: 00149 return static_cast<const EnumerationDecl*>(this); 00150 case Ast::AST_BlockStmt: 00151 return static_cast<const BlockStmt*>(this); 00152 case Ast::AST_IntegerDecl: 00153 return static_cast<const IntegerDecl*>(this); 00154 case Ast::AST_RecordDecl: 00155 return static_cast<const RecordDecl*>(this); 00156 case Ast::AST_ArrayDecl: 00157 return static_cast<const ArrayDecl*>(this); 00158 case Ast::AST_AccessDecl: 00159 return static_cast<const AccessDecl*>(this); 00160 } 00161 } 00162 00163 Ast *DeclRegion::asAst() 00164 { 00165 return const_cast<Ast*>( 00166 const_cast<const DeclRegion *>(this)->asAst()); 00167 } 00168 00169 // Default implementation -- do nothing. 00170 void DeclRegion::notifyAddDecl(Decl *decl) { } 00171 00172 // Default implementation -- do nothing. 00173 void DeclRegion::notifyRemoveDecl(Decl *decl) { } 00174 00175 void DeclRegion::notifyObserversOfAddition(Decl *decl) 00176 { 00177 for (ObserverList::iterator iter = observers.begin(); 00178 iter != observers.end(); ++iter) 00179 (*iter)->notifyAddDecl(decl); 00180 } 00181 00182 void DeclRegion::notifyObserversOfRemoval(Decl *decl) 00183 { 00184 for (ObserverList::iterator iter = observers.begin(); 00185 iter != observers.end(); ++iter) 00186 (*iter)->notifyRemoveDecl(decl); 00187 }