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