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