This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- ast/DeclRegion.h -------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 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 // DeclRegion 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 // Sets the parent of this region. This function can only be called if the 00041 // parent of this region has not yet been set. 00042 void setParent(DeclRegion *parentRegion) { 00043 assert(!parent && "Cannot reset the parent of a DeclRegion!"); 00044 parent = parentRegion; 00045 } 00046 00047 // Adds the given decl to this region. If a decl with the same name already 00048 // exists in this region that previous decl is unconditionally overwritten. 00049 // It is the responsibility of the caller to ensure that this operation is 00050 // semantically valid. 00051 void addDecl(Decl *decl); 00052 00053 // Returns the number of declarations in this region. 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 // PredIter 00086 // 00087 // FIXME: This class should be lifted out to its own header, likely 00088 // generalized to a template. We leave it here for now until it is proved 00089 // generally useful/desirable. 00090 // 00091 // A PredIter is a trivial forward iterator which skips certain elements of 00092 // the underlying sequence according to a supplied predicate object. 00093 // 00094 // Most implementations of such "filter" iterators use templates to forward 00095 // the predicate and underlying iterator types. This implementation relies 00096 // on the PredIter::Predicate structure to supply a generic interface to the 00097 // predicate object thru a virtual operator (). PredIter::Predicate is 00098 // itself a subclass of llvm::RefCountedBaseVPTR, meaning that instances of 00099 // this predicate class are managed by an internal reference count. When a 00100 // PredIter is constructed, the ownership of the supplied Predicate object 00101 // is released to the PredIter. 00102 // 00103 // This organization simplifies the type interface by eliminating template 00104 // parameters for each predicate yet permits arbitrary filtering strategies 00105 // to be implemented. 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 // Returns true if the given iterator points to the same element as this 00139 // iterator. Equality is indifferent to the particular predicate. 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 // Returns true if this region contains a declaration with the given name. 00173 bool containsDecl(IdentifierInfo *name) const { 00174 PredRange range = findDecls(name); 00175 return range.first != range.second; 00176 } 00177 00178 // Returns true if this region contains the given declaration. 00179 bool containsDecl(const Decl *decl) const; 00180 00181 // Returns the declaration with the given name and type in this region if 00182 // one is present, else 0. 00183 Decl *findDecl(IdentifierInfo *name, Type *type); 00184 00185 // Removes the given decl. Returns true if the decl existed and was 00186 // removed, false otherwise. 00187 bool removeDecl(Decl *decl); 00188 00189 // Looks up all function declaration nodes in this region with the given 00190 // name, pushing the results onto the supplied vector. Returns true if any 00191 // declarations were found and false otherwise. 00192 bool collectFunctionDecls(IdentifierInfo *name, 00193 llvm::SmallVectorImpl<SubroutineDecl*> &dst); 00194 00195 // Looks up all procedure declaration nodes in this region with the given 00196 // name, pushing the results onto the supplied vector. Returns true if any 00197 // declarations were found and false otherwise. 00198 bool collectProcedureDecls(IdentifierInfo *name, 00199 llvm::SmallVectorImpl<SubroutineDecl*> &dst); 00200 00201 // Converts this DeclRegion into a raw Ast node. 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 } // End comma namespace. 00270 00271 namespace llvm { 00272 00273 // Specialize isa_impl_wrap to test if a DeclRegion is a specific Ast. 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 // Ast to DeclRegion conversions. 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 // DeclRegion to Ast conversions. 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 } // End llvm namespace. 00351 00352 #endif