00001
00002
00003
00004
00005
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
00032
00033
00034
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 }
00319
00320 #endif