00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_AST_DECLREGION_HDR_GUARD
00010 #define COMMA_AST_DECLREGION_HDR_GUARD
00011
00012 #include "comma/ast/AstBase.h"
00013 #include "llvm/ADT/IntrusiveRefCntPtr.h"
00014 #include <list>
00015 #include <vector>
00016
00017 namespace comma {
00018
00019
00020
00021 class DeclRegion {
00022
00023 protected:
00024 DeclRegion(Ast::AstKind kind)
00025 : regionKind(kind), parent(0) { }
00026
00027 DeclRegion(Ast::AstKind kind, DeclRegion *parent)
00028 : regionKind(kind), parent(parent) { }
00029
00030 typedef std::vector<Decl*> DeclarationTable;
00031 DeclarationTable declarations;
00032
00033 public:
00034 DeclRegion *getParent() { return parent; }
00035 const DeclRegion *getParent() const { return parent; }
00036
00037
00038
00039 void setParent(DeclRegion *parentRegion) {
00040 assert(!parent && "Cannot reset the parent of a DeclRegion!");
00041 parent = parentRegion;
00042 }
00043
00044
00045
00046
00047
00048 void addDecl(Decl *decl);
00049
00050
00051
00052 void addDeclarationUsingRewrites(const AstRewriter &rewrites,
00053 Decl *decl);
00054
00055
00056
00057 void addDeclarationsUsingRewrites(const AstRewriter &rewrites,
00058 const DeclRegion *region);
00059
00060 typedef DeclarationTable::iterator DeclIter;
00061 DeclIter beginDecls() { return declarations.begin(); }
00062 DeclIter endDecls() { return declarations.end(); }
00063
00064 typedef DeclarationTable::const_iterator ConstDeclIter;
00065 ConstDeclIter beginDecls() const { return declarations.begin(); }
00066 ConstDeclIter endDecls() const { return declarations.end(); }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 class PredIter {
00091 friend class DeclRegion;
00092
00093 typedef DeclRegion::ConstDeclIter DeclIter;
00094
00095 struct Predicate : public llvm::RefCountedBaseVPTR<Predicate> {
00096 virtual bool operator()(const Decl*) = 0;
00097 };
00098
00099 typedef llvm::IntrusiveRefCntPtr<Predicate> IntrusivePtr;
00100 IntrusivePtr predicate;
00101 DeclIter cursor;
00102 DeclIter end;
00103
00104 bool predCall(const Decl *decl) {
00105 return predicate->operator()(decl);
00106 }
00107
00108 PredIter(Predicate *pred,
00109 DeclIter begin,
00110 DeclIter end)
00111 : predicate(pred), cursor(begin), end(end) {
00112 while (cursor != end) {
00113 if (predCall(*cursor)) break;
00114 ++cursor;
00115 }
00116 }
00117
00118 PredIter(DeclIter end)
00119 : predicate(0), cursor(end), end(end) { }
00120
00121 public:
00122
00123
00124 bool operator ==(const PredIter& iter) {
00125 return cursor == iter.cursor;
00126 }
00127
00128 bool operator !=(const PredIter& iter) {
00129 return cursor != iter.cursor;
00130 }
00131
00132 PredIter &operator++() {
00133 if (cursor != end)
00134 while (++cursor != end) {
00135 if (predCall(*cursor)) break;
00136 }
00137 return *this;
00138 }
00139
00140 PredIter operator++(int) {
00141 PredIter res = *this;
00142 if (cursor != end)
00143 while (++cursor != end) {
00144 if (predCall(*cursor)) break;
00145 }
00146 return res;
00147 }
00148
00149 Decl *operator*() { return *cursor; }
00150 };
00151
00152 typedef std::pair<PredIter, PredIter> PredRange;
00153
00154 PredRange findDecls(IdentifierInfo *name) const;
00155
00156
00157 bool containsDecl(IdentifierInfo *name) const {
00158 PredRange range = findDecls(name);
00159 return range.first != range.second;
00160 }
00161
00162
00163
00164 Decl *findDecl(IdentifierInfo *name, Type *type);
00165
00166
00167
00168 bool removeDecl(Decl *decl);
00169
00170
00171
00172
00173 bool collectFunctionDecls(IdentifierInfo *name,
00174 unsigned arity,
00175 std::vector<SubroutineDecl*> &dst);
00176
00177
00178
00179
00180
00181 bool collectProcedureDecls(IdentifierInfo *name,
00182 unsigned arity,
00183 std::vector<SubroutineDecl*> &dst);
00184
00185
00186 Ast *asAst();
00187 const Ast *asAst() const;
00188
00189 void addObserver(DeclRegion *region) { observers.push_front(region); }
00190
00191 static bool classof(const Ast *node) {
00192 switch (node->getKind()) {
00193 default:
00194 return false;
00195 case Ast::AST_DomainDecl:
00196 case Ast::AST_SignatureDecl:
00197 case Ast::AST_VarietyDecl:
00198 case Ast::AST_FunctorDecl:
00199 case Ast::AST_DomainInstanceDecl:
00200 case Ast::AST_AbstractDomainDecl:
00201 case Ast::AST_AddDecl:
00202 case Ast::AST_ProcedureDecl:
00203 case Ast::AST_FunctionDecl:
00204 case Ast::AST_EnumerationDecl:
00205 case Ast::AST_IntegerDecl:
00206 case Ast::AST_BlockStmt:
00207 return true;
00208 }
00209 }
00210
00211 static bool classof(const DomainDecl *node) { return true; }
00212 static bool classof(const SignatureDecl *node) { return true; }
00213 static bool classof(const VarietyDecl *node) { return true; }
00214 static bool classof(const FunctorDecl *node) { return true; }
00215 static bool classof(const AddDecl *node) { return true; }
00216 static bool classof(const ProcedureDecl *node) { return true; }
00217 static bool classof(const FunctionDecl *node) { return true; }
00218 static bool classof(const BlockStmt *node) { return true; }
00219 static bool classof(const IntegerDecl *node) { return true; }
00220 static bool classof(const DomainInstanceDecl *node) { return true; }
00221 static bool classof(const AbstractDomainDecl *node) { return true; }
00222 static bool classof(const EnumerationDecl *node) { return true; }
00223
00224 protected:
00225 virtual void notifyAddDecl(Decl *decl);
00226 virtual void notifyRemoveDecl(Decl *decl);
00227
00228 private:
00229 Ast::AstKind regionKind;
00230 DeclRegion *parent;
00231
00232 typedef std::list<DeclRegion*> ObserverList;
00233 ObserverList observers;
00234
00235 void notifyObserversOfAddition(Decl *decl);
00236 void notifyObserversOfRemoval(Decl *decl);
00237 };
00238
00239 }
00240
00241 namespace llvm {
00242
00243
00244 template<class To>
00245 struct isa_impl_wrap<To,
00246 const comma::DeclRegion, const comma::DeclRegion> {
00247 static bool doit(const comma::DeclRegion &val) {
00248 return To::classof(val.asAst());
00249 }
00250 };
00251
00252 template<class To>
00253 struct isa_impl_wrap<To, comma::DeclRegion, comma::DeclRegion>
00254 : public isa_impl_wrap<To,
00255 const comma::DeclRegion,
00256 const comma::DeclRegion> { };
00257
00258
00259 template<class From>
00260 struct cast_convert_val<comma::DeclRegion, From, From> {
00261 static comma::DeclRegion &doit(const From &val) {
00262 return *val.asDeclRegion();
00263 }
00264 };
00265
00266 template<class From>
00267 struct cast_convert_val<comma::DeclRegion, From*, From*> {
00268 static comma::DeclRegion *doit(const From *val) {
00269 return val->asDeclRegion();
00270 }
00271 };
00272
00273 template<class From>
00274 struct cast_convert_val<const comma::DeclRegion, From, From> {
00275 static const comma::DeclRegion &doit(const From &val) {
00276 return *val.asDeclRegion();
00277 }
00278 };
00279
00280 template<class From>
00281 struct cast_convert_val<const comma::DeclRegion, From*, From*> {
00282 static const comma::DeclRegion *doit(const From *val) {
00283 return val->asDeclRegion();
00284 }
00285 };
00286
00287
00288 template<class To>
00289 struct cast_convert_val<To,
00290 const comma::DeclRegion,
00291 const comma::DeclRegion> {
00292 static To &doit(const comma::DeclRegion &val) {
00293 return *reinterpret_cast<To*>(
00294 const_cast<comma::Ast*>(val.asAst()));
00295 }
00296 };
00297
00298 template<class To>
00299 struct cast_convert_val<To, comma::DeclRegion, comma::DeclRegion>
00300 : public cast_convert_val<To,
00301 const comma::DeclRegion,
00302 const comma::DeclRegion> { };
00303
00304 template<class To>
00305 struct cast_convert_val<To,
00306 const comma::DeclRegion*,
00307 const comma::DeclRegion*> {
00308 static To *doit(const comma::DeclRegion *val) {
00309 return reinterpret_cast<To*>(
00310 const_cast<comma::Ast*>(val->asAst()));
00311 }
00312 };
00313
00314 template<class To>
00315 struct cast_convert_val<To, comma::DeclRegion*, comma::DeclRegion*>
00316 : public cast_convert_val<To,
00317 const comma::DeclRegion*,
00318 const comma::DeclRegion*> { };
00319
00320 }
00321
00322 #endif