00001
00002
00003
00004
00005
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
00170 void DeclRegion::notifyAddDecl(Decl *decl) { }
00171
00172
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 }