00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_DECLARATIVEREGION_HDR_GUARD
00010 #define COMMA_DECLARATIVEREGION_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 DeclarativeRegion {
00022
00023 protected:
00024 DeclarativeRegion(Ast::AstKind kind)
00025 : regionKind(kind), parent(0) { }
00026
00027 DeclarativeRegion(Ast::AstKind kind, DeclarativeRegion *parent)
00028 : regionKind(kind), parent(parent) { }
00029
00030 typedef std::vector<Decl*> DeclarationTable;
00031 DeclarationTable declarations;
00032
00033 public:
00034 DeclarativeRegion *getParent() { return parent; }
00035 const DeclarativeRegion *getParent() const { return parent; }
00036
00037
00038
00039 void setParent(DeclarativeRegion *parentRegion) {
00040 assert(!parent && "Cannot reset the parent of a DeclarativeRegion!");
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 DeclarativeRegion *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 DeclarativeRegion;
00092
00093 typedef DeclarativeRegion::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(DeclarativeRegion *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_BlockStmt:
00206 return true;
00207 }
00208 }
00209
00210 static bool classof(const DomainDecl *node) { return true; }
00211 static bool classof(const SignatureDecl *node) { return true; }
00212 static bool classof(const VarietyDecl *node) { return true; }
00213 static bool classof(const FunctorDecl *node) { return true; }
00214 static bool classof(const AddDecl *node) { return true; }
00215 static bool classof(const ProcedureDecl *node) { return true; }
00216 static bool classof(const FunctionDecl *node) { return true; }
00217 static bool classof(const BlockStmt *node) { return true; }
00218 static bool classof(const DomainInstanceDecl *node) { return true; }
00219 static bool classof(const AbstractDomainDecl *node) { return true; }
00220 static bool classof(const EnumerationDecl *node) { return true; }
00221
00222 protected:
00223 virtual void notifyAddDecl(Decl *decl);
00224 virtual void notifyRemoveDecl(Decl *decl);
00225
00226 private:
00227 Ast::AstKind regionKind;
00228 DeclarativeRegion *parent;
00229
00230 typedef std::list<DeclarativeRegion*> ObserverList;
00231 ObserverList observers;
00232
00233 void notifyObserversOfAddition(Decl *decl);
00234 void notifyObserversOfRemoval(Decl *decl);
00235 };
00236
00237 }
00238
00239 namespace llvm {
00240
00241
00242 template<class To>
00243 struct isa_impl_wrap<To,
00244 const comma::DeclarativeRegion, const comma::DeclarativeRegion> {
00245 static bool doit(const comma::DeclarativeRegion &val) {
00246 return To::classof(val.asAst());
00247 }
00248 };
00249
00250 template<class To>
00251 struct isa_impl_wrap<To, comma::DeclarativeRegion, comma::DeclarativeRegion>
00252 : public isa_impl_wrap<To,
00253 const comma::DeclarativeRegion,
00254 const comma::DeclarativeRegion> { };
00255
00256
00257 template<class From>
00258 struct cast_convert_val<comma::DeclarativeRegion, From, From> {
00259 static comma::DeclarativeRegion &doit(const From &val) {
00260 return *val.asDeclarativeRegion();
00261 }
00262 };
00263
00264 template<class From>
00265 struct cast_convert_val<comma::DeclarativeRegion, From*, From*> {
00266 static comma::DeclarativeRegion *doit(const From *val) {
00267 return val->asDeclarativeRegion();
00268 }
00269 };
00270
00271 template<class From>
00272 struct cast_convert_val<const comma::DeclarativeRegion, From, From> {
00273 static const comma::DeclarativeRegion &doit(const From &val) {
00274 return *val.asDeclarativeRegion();
00275 }
00276 };
00277
00278 template<class From>
00279 struct cast_convert_val<const comma::DeclarativeRegion, From*, From*> {
00280 static const comma::DeclarativeRegion *doit(const From *val) {
00281 return val->asDeclarativeRegion();
00282 }
00283 };
00284
00285
00286 template<class To>
00287 struct cast_convert_val<To,
00288 const comma::DeclarativeRegion,
00289 const comma::DeclarativeRegion> {
00290 static To &doit(const comma::DeclarativeRegion &val) {
00291 return *reinterpret_cast<To*>(
00292 const_cast<comma::Ast*>(val.asAst()));
00293 }
00294 };
00295
00296 template<class To>
00297 struct cast_convert_val<To, comma::DeclarativeRegion, comma::DeclarativeRegion>
00298 : public cast_convert_val<To,
00299 const comma::DeclarativeRegion,
00300 const comma::DeclarativeRegion> { };
00301
00302 template<class To>
00303 struct cast_convert_val<To,
00304 const comma::DeclarativeRegion*,
00305 const comma::DeclarativeRegion*> {
00306 static To *doit(const comma::DeclarativeRegion *val) {
00307 return reinterpret_cast<To*>(
00308 const_cast<comma::Ast*>(val->asAst()));
00309 }
00310 };
00311
00312 template<class To>
00313 struct cast_convert_val<To, comma::DeclarativeRegion*, comma::DeclarativeRegion*>
00314 : public cast_convert_val<To,
00315 const comma::DeclarativeRegion*,
00316 const comma::DeclarativeRegion*> { };
00317
00318 }
00319
00320 #endif