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