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/SubroutineRef.h ----------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 //===----------------------------------------------------------------------===// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef COMMA_AST_SUBROUTINE_REF_HDR_GUARD 00016 #define COMMA_AST_SUBROUTINE_REF_HDR_GUARD 00017 00018 #include "comma/ast/Decl.h" 00019 00020 namespace comma { 00021 00029 class SubroutineRef : public Ast { 00030 00031 // The type used to represent the collection of referenced declarations. 00032 // 00033 // We use the smallest SmallVector we can since all SubroutineRefs are 00034 // eventually resolved to a single decl (when the program is well formed). 00035 typedef llvm::SmallVector<SubroutineDecl*, 1> DeclVector; 00036 00037 public: 00039 SubroutineRef(Location loc, SubroutineDecl *decl) 00040 : Ast(AST_SubroutineRef), loc(loc) { 00041 decls.push_back(decl); 00042 } 00043 00048 SubroutineRef(Location loc, SubroutineDecl **decls, unsigned numDecls) 00049 : Ast(AST_SubroutineRef), 00050 decls(decls, decls + numDecls), loc(loc) { 00051 verify(); 00052 } 00053 00059 template <class I> 00060 SubroutineRef(Location loc, I begin, I end) 00061 : Ast(AST_SubroutineRef), 00062 decls(begin, end), loc(loc) { 00063 verify(); 00064 } 00065 00067 IdentifierInfo *getIdInfo() const { 00068 assert(!empty() && "Empty SubroutineRef!"); 00069 return decls[0]->getIdInfo(); 00070 } 00071 00073 const char *getString() const { return getIdInfo()->getString(); } 00074 00076 Location getLocation() const { return loc; } 00077 00079 void addDeclaration(SubroutineDecl *srDecl); 00080 00083 template <class Iter> 00084 void addDeclarations(Iter I, Iter E) { 00085 for ( ; I != E; ++I) 00086 addDeclaration(*I); 00087 } 00088 00090 bool isOverloaded() const { return numDeclarations() > 1; } 00091 00093 bool empty() const { return numDeclarations() == 0; } 00094 00096 bool referencesFunctions() const { 00097 return empty() ? false : llvm::isa<FunctionDecl>(decls[0]); 00098 } 00099 00101 bool referencesProcedures() const { 00102 return empty() ? false : llvm::isa<ProcedureDecl>(decls[0]); 00103 } 00104 00106 unsigned numDeclarations() const { return decls.size(); } 00107 00109 00110 const SubroutineDecl *getDeclaration(unsigned i) const { 00111 assert(i < numDeclarations() && "Index out of range!"); 00112 return decls[i]; 00113 } 00114 00115 SubroutineDecl *getDeclaration(unsigned i) { 00116 assert(i < numDeclarations() && "Index out of range!"); 00117 return decls[i]; 00118 } 00120 00122 00123 00124 const SubroutineDecl *getDeclaration() const { 00125 return isResolved() ? decls[0] : 0; 00126 } 00127 00128 SubroutineDecl *getDeclaration() { 00129 return isResolved() ? decls[0] : 0; 00130 } 00132 00135 bool contains(const SubroutineDecl *srDecl) const; 00136 00139 bool contains(const SubroutineType *srType) const; 00140 00146 bool keepSubroutinesWithArity(unsigned arity); 00147 00153 void resolve(SubroutineDecl *srDecl) { 00154 decls.clear(); 00155 decls.push_back(srDecl); 00156 } 00157 00159 bool isResolved() const { return numDeclarations() == 1; } 00160 00162 00163 typedef DeclVector::iterator iterator; 00164 iterator begin() { return decls.begin(); } 00165 iterator end() { return decls.end(); } 00166 00167 typedef DeclVector::const_iterator const_iterator; 00168 const_iterator begin() const { return decls.begin(); } 00169 const_iterator end() const { return decls.end(); } 00171 00172 private: 00175 template <class T> 00176 class SubroutineDeclIter { 00177 00178 mutable SubroutineRef::iterator I; 00179 00180 SubroutineDeclIter(SubroutineRef::iterator I) 00181 : I(I) { } 00182 00184 SubroutineRef::iterator getIterator() const { return I; } 00185 00186 friend class SubroutineRef; 00187 00188 public: 00189 SubroutineDeclIter(const SubroutineDeclIter<T> &iter) 00190 : I(iter.I) { } 00191 00192 T *operator *() { 00193 return llvm::cast<T>(*I); 00194 } 00195 00196 const T *operator *() const { 00197 return llvm::cast<T>(*I); 00198 } 00199 00200 bool operator ==(const SubroutineDeclIter &iter) const { 00201 return this->I == iter.I; 00202 } 00203 00204 bool operator !=(const SubroutineDeclIter &iter) const { 00205 return !this->operator==(iter); 00206 } 00207 00208 SubroutineDeclIter &operator ++() { 00209 ++I; 00210 return *this; 00211 } 00212 00213 const SubroutineDeclIter &operator ++() const { 00214 ++I; 00215 return *this; 00216 } 00217 00218 SubroutineDeclIter operator ++(int) const { 00219 SubroutineDeclIter tmp = *this; 00220 this->operator++(); 00221 return tmp; 00222 } 00223 }; 00224 00225 public: 00227 00228 00229 00230 00231 00232 00233 typedef SubroutineDeclIter<FunctionDecl> fun_iterator; 00234 fun_iterator begin_functions() { 00235 if (this->referencesFunctions()) 00236 return fun_iterator(begin()); 00237 else 00238 return fun_iterator(end()); 00239 } 00240 fun_iterator end_functions() { 00241 return fun_iterator(end()); 00242 } 00243 00244 typedef const SubroutineDeclIter<FunctionDecl> const_fun_iterator; 00245 const_fun_iterator begin_functions() const { 00246 SubroutineRef *ref = const_cast<SubroutineRef*>(this); 00247 if (this->referencesFunctions()) 00248 return const_fun_iterator(ref->begin()); 00249 else 00250 return const_fun_iterator(ref->end()); 00251 } 00252 const_fun_iterator end_functions() const { 00253 SubroutineRef *ref = const_cast<SubroutineRef*>(this); 00254 return const_fun_iterator(ref->end()); 00255 } 00256 00257 typedef SubroutineDeclIter<ProcedureDecl> proc_iterator; 00258 proc_iterator begin_procedures() { 00259 if (this->referencesProcedures()) 00260 return proc_iterator(begin()); 00261 else 00262 return proc_iterator(end()); 00263 } 00264 proc_iterator end_procedures() { 00265 return proc_iterator(end()); 00266 } 00267 00268 typedef const SubroutineDeclIter<ProcedureDecl> const_proc_iterator; 00269 const_proc_iterator begin_procedures() const { 00270 SubroutineRef *ref = const_cast<SubroutineRef*>(this); 00271 if (this->referencesProcedures()) 00272 return const_proc_iterator(ref->begin()); 00273 else 00274 return const_proc_iterator(ref->end()); 00275 } 00276 const_proc_iterator end_procedures() const { 00277 SubroutineRef *ref = const_cast<SubroutineRef*>(this); 00278 return const_proc_iterator(ref->end()); 00279 } 00281 00288 00289 iterator erase(iterator I) { return decls.erase(I); } 00290 00291 template <class T> 00292 SubroutineDeclIter<T> erase(SubroutineDeclIter<T> SDI) { 00293 iterator I = SDI.getIterator(); 00294 I = decls.erase(I); 00295 return SubroutineDeclIter<T>(I); 00296 } 00298 00299 static bool classof(const SubroutineRef *node) { return true; } 00300 static bool classof(const Ast *node) { 00301 return node->getKind() == AST_SubroutineRef; 00302 } 00303 00304 private: 00305 DeclVector decls; 00306 Location loc; 00307 00310 void verify(); 00311 00315 void verify(SubroutineDecl *decl, IdentifierInfo *name, bool isaFunction); 00316 }; 00317 00318 } // end comma namespace. 00319 00320 #endif