00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/ast/AstRewriter.h"
00010 #include "comma/ast/DeclRegion.h"
00011 #include "comma/ast/Decl.h"
00012 #include "comma/ast/Stmt.h"
00013 #include "llvm/Support/Casting.h"
00014 #include <algorithm>
00015 #include <cstring>
00016 #include <cassert>
00017
00018 using namespace comma;
00019 using llvm::dyn_cast;
00020 using llvm::cast;
00021 using llvm::isa;
00022
00023 void DeclRegion::addDecl(Decl *decl) {
00024 declarations.push_back(decl);
00025 notifyObserversOfAddition(decl);
00026 }
00027
00028 void DeclRegion::addDeclarationUsingRewrites(const AstRewriter &rewrites,
00029 Decl *decl)
00030 {
00031 Decl *newDecl = 0;
00032
00033 switch (decl->getKind()) {
00034
00035 default:
00036 assert(false && "Bad type of declaration!");
00037 break;
00038
00039 case Ast::AST_FunctionDecl: {
00040 FunctionDecl *fdecl = cast<FunctionDecl>(decl);
00041 FunctionType *ftype = rewrites.rewrite(fdecl->getType());
00042 FunctionDecl *p = new FunctionDecl(decl->getIdInfo(), 0, ftype, this);
00043 p->setOrigin(fdecl);
00044 newDecl = p;
00045 break;
00046 }
00047
00048 case Ast::AST_ProcedureDecl: {
00049 ProcedureDecl *pdecl = cast<ProcedureDecl>(decl);
00050 ProcedureType *ptype = rewrites.rewrite(pdecl->getType());
00051 ProcedureDecl *p = new ProcedureDecl(decl->getIdInfo(), 0, ptype, this);
00052 p->setOrigin(pdecl);
00053 newDecl = p;
00054 break;
00055 }
00056
00057 case Ast::AST_EnumerationDecl:
00058
00059
00060 newDecl = decl;
00061 break;
00062 }
00063 if (newDecl)
00064 this->addDecl(newDecl);
00065 }
00066
00067 void
00068 DeclRegion::addDeclarationsUsingRewrites(const AstRewriter &rewrites,
00069 const DeclRegion *region)
00070 {
00071 ConstDeclIter iter;
00072 ConstDeclIter endIter = region->endDecls();
00073
00074 for (iter = region->beginDecls(); iter != endIter; ++iter)
00075 addDeclarationUsingRewrites(rewrites, *iter);
00076 }
00077
00078 Decl *DeclRegion::findDecl(IdentifierInfo *name, Type *type)
00079 {
00080 DeclIter endIter = endDecls();
00081 for (DeclIter iter = beginDecls(); iter != endIter; ++iter) {
00082 Decl *decl = *iter;
00083 if (decl->getIdInfo() == name) {
00084 Type *candidate = 0;
00085 if (TypeDecl *TD = dyn_cast<TypeDecl>(decl))
00086 candidate = TD->getType();
00087 else if (SubroutineDecl *SD = dyn_cast<SubroutineDecl>(decl))
00088 candidate = SD->getType();
00089 else if (EnumLiteral *EL = dyn_cast<EnumLiteral>(decl))
00090 candidate = EL->getType();
00091
00092 if (candidate && type->equals(candidate))
00093 return decl;
00094 }
00095 }
00096 return 0;
00097 }
00098
00099 DeclRegion::PredRange
00100 DeclRegion::findDecls(IdentifierInfo *name) const
00101 {
00102 struct Pred : public PredIter::Predicate {
00103 Pred(IdentifierInfo *name) : name(name) { }
00104 bool operator()(const Decl *decl) {
00105 return decl->getIdInfo() == name;
00106 }
00107 IdentifierInfo *name;
00108 };
00109 ConstDeclIter begin = beginDecls();
00110 ConstDeclIter end = endDecls();
00111 Pred *pred = new Pred(name);
00112 return PredRange(PredIter(pred, begin, end), PredIter(end));
00113 }
00114
00115 bool DeclRegion::removeDecl(Decl *decl)
00116 {
00117 DeclIter result = std::find(beginDecls(), endDecls(), decl);
00118 if (result != endDecls()) {
00119 declarations.erase(result);
00120 return true;
00121 }
00122 return false;
00123 }
00124
00125 bool DeclRegion::collectFunctionDecls(IdentifierInfo *name,
00126 unsigned arity,
00127 std::vector<SubroutineDecl*> &dst)
00128 {
00129 PredRange range = findDecls(name);
00130 size_t size = dst.size();
00131
00132 for (PredIter iter = range.first; iter != range.second; ++iter) {
00133 if (FunctionDecl *decl = dyn_cast<FunctionDecl>(*iter)) {
00134 if (decl->getArity() == arity)
00135 dst.push_back(decl);
00136 }
00137 }
00138 return size != dst.size();
00139 }
00140
00141 bool DeclRegion::collectProcedureDecls(IdentifierInfo *name,
00142 unsigned arity,
00143 std::vector<SubroutineDecl*> &dst)
00144 {
00145 PredRange range = findDecls(name);
00146 size_t size = dst.size();
00147
00148 for (PredIter iter = range.first; iter != range.second; ++iter) {
00149 if (ProcedureDecl *decl = dyn_cast<ProcedureDecl>(*iter)) {
00150 if (decl->getArity() == arity)
00151 dst.push_back(decl);
00152 }
00153 }
00154 return size != dst.size();
00155 }
00156
00157 const Ast *DeclRegion::asAst() const
00158 {
00159 switch (regionKind) {
00160 default:
00161 assert(false && "Unknown delcarative region kind!");
00162 return 0;
00163 case Ast::AST_SignatureDecl:
00164 return static_cast<const SignatureDecl*>(this);
00165 case Ast::AST_VarietyDecl:
00166 return static_cast<const VarietyDecl*>(this);
00167 case Ast::AST_DomainDecl:
00168 return static_cast<const DomainDecl*>(this);
00169 case Ast::AST_FunctorDecl:
00170 return static_cast<const FunctorDecl*>(this);
00171 case Ast::AST_FunctionDecl:
00172 return static_cast<const FunctionDecl*>(this);
00173 case Ast::AST_ProcedureDecl:
00174 return static_cast<const ProcedureDecl*>(this);
00175 case Ast::AST_AbstractDomainDecl:
00176 return static_cast<const AbstractDomainDecl*>(this);
00177 case Ast::AST_DomainInstanceDecl:
00178 return static_cast<const DomainInstanceDecl*>(this);
00179 case Ast::AST_AddDecl:
00180 return static_cast<const AddDecl*>(this);
00181 case Ast::AST_EnumerationDecl:
00182 return static_cast<const EnumerationDecl*>(this);
00183 case Ast::AST_BlockStmt:
00184 return static_cast<const BlockStmt*>(this);
00185 case Ast::AST_IntegerDecl:
00186 return static_cast<const IntegerDecl*>(this);
00187 }
00188 }
00189
00190 Ast *DeclRegion::asAst()
00191 {
00192 return const_cast<Ast*>(
00193 const_cast<const DeclRegion *>(this)->asAst());
00194 }
00195
00196
00197 void DeclRegion::notifyAddDecl(Decl *decl) { }
00198
00199
00200 void DeclRegion::notifyRemoveDecl(Decl *decl) { }
00201
00202 void DeclRegion::notifyObserversOfAddition(Decl *decl)
00203 {
00204 for (ObserverList::iterator iter = observers.begin();
00205 iter != observers.end(); ++iter)
00206 (*iter)->notifyAddDecl(decl);
00207 }
00208
00209 void DeclRegion::notifyObserversOfRemoval(Decl *decl)
00210 {
00211 for (ObserverList::iterator iter = observers.begin();
00212 iter != observers.end(); ++iter)
00213 (*iter)->notifyRemoveDecl(decl);
00214 }