clang API Documentation
00001 //===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the Redeclarable interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_REDECLARABLE_H 00015 #define LLVM_CLANG_AST_REDECLARABLE_H 00016 00017 #include "clang/AST/ExternalASTSource.h" 00018 #include "llvm/ADT/PointerIntPair.h" 00019 #include "llvm/Support/Casting.h" 00020 #include <iterator> 00021 00022 namespace clang { 00023 00024 /// \brief Provides common interface for the Decls that can be redeclared. 00025 template<typename decl_type> 00026 class Redeclarable { 00027 protected: 00028 class DeclLink { 00029 /// A pointer to a known latest declaration, either statically known or 00030 /// generationally updated as decls are added by an external source. 00031 typedef LazyGenerationalUpdatePtr<const Decl*, Decl*, 00032 &ExternalASTSource::CompleteRedeclChain> 00033 KnownLatest; 00034 00035 typedef const ASTContext *UninitializedLatest; 00036 typedef Decl *Previous; 00037 00038 /// A pointer to either an uninitialized latest declaration (where either 00039 /// we've not yet set the previous decl or there isn't one), or to a known 00040 /// previous declaration. 00041 typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest; 00042 00043 mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next; 00044 00045 public: 00046 enum PreviousTag { PreviousLink }; 00047 enum LatestTag { LatestLink }; 00048 00049 DeclLink(LatestTag, const ASTContext &Ctx) 00050 : Next(NotKnownLatest(&Ctx)) {} 00051 DeclLink(PreviousTag, decl_type *D) 00052 : Next(NotKnownLatest(Previous(D))) {} 00053 00054 bool NextIsPrevious() const { 00055 return Next.is<NotKnownLatest>() && 00056 // FIXME: 'template' is required on the next line due to an 00057 // apparent clang bug. 00058 Next.get<NotKnownLatest>().template is<Previous>(); 00059 } 00060 00061 bool NextIsLatest() const { return !NextIsPrevious(); } 00062 00063 decl_type *getNext(const decl_type *D) const { 00064 if (Next.is<NotKnownLatest>()) { 00065 NotKnownLatest NKL = Next.get<NotKnownLatest>(); 00066 if (NKL.is<Previous>()) 00067 return static_cast<decl_type*>(NKL.get<Previous>()); 00068 00069 // Allocate the generational 'most recent' cache now, if needed. 00070 Next = KnownLatest(*NKL.get<UninitializedLatest>(), 00071 const_cast<decl_type *>(D)); 00072 } 00073 00074 return static_cast<decl_type*>(Next.get<KnownLatest>().get(D)); 00075 } 00076 00077 void setPrevious(decl_type *D) { 00078 assert(NextIsPrevious() && "decl became non-canonical unexpectedly"); 00079 Next = Previous(D); 00080 } 00081 00082 void setLatest(decl_type *D) { 00083 assert(NextIsLatest() && "decl became canonical unexpectedly"); 00084 if (Next.is<NotKnownLatest>()) { 00085 NotKnownLatest NKL = Next.get<NotKnownLatest>(); 00086 Next = KnownLatest(*NKL.get<UninitializedLatest>(), D); 00087 } else { 00088 auto Latest = Next.get<KnownLatest>(); 00089 Latest.set(D); 00090 Next = Latest; 00091 } 00092 } 00093 00094 void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); } 00095 }; 00096 00097 static DeclLink PreviousDeclLink(decl_type *D) { 00098 return DeclLink(DeclLink::PreviousLink, D); 00099 } 00100 00101 static DeclLink LatestDeclLink(const ASTContext &Ctx) { 00102 return DeclLink(DeclLink::LatestLink, Ctx); 00103 } 00104 00105 /// \brief Points to the next redeclaration in the chain. 00106 /// 00107 /// If NextIsPrevious() is true, this is a link to the previous declaration 00108 /// of this same Decl. If NextIsLatest() is true, this is the first 00109 /// declaration and Link points to the latest declaration. For example: 00110 /// 00111 /// #1 int f(int x, int y = 1); // <pointer to #3, true> 00112 /// #2 int f(int x = 0, int y); // <pointer to #1, false> 00113 /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false> 00114 /// 00115 /// If there is only one declaration, it is <pointer to self, true> 00116 DeclLink RedeclLink; 00117 00118 decl_type *getNextRedeclaration() const { 00119 return RedeclLink.getNext(static_cast<const decl_type *>(this)); 00120 } 00121 00122 public: 00123 Redeclarable(const ASTContext &Ctx) 00124 : RedeclLink(LatestDeclLink(Ctx)) {} 00125 00126 /// \brief Return the previous declaration of this declaration or NULL if this 00127 /// is the first declaration. 00128 decl_type *getPreviousDecl() { 00129 if (RedeclLink.NextIsPrevious()) 00130 return getNextRedeclaration(); 00131 return nullptr; 00132 } 00133 const decl_type *getPreviousDecl() const { 00134 return const_cast<decl_type *>( 00135 static_cast<const decl_type*>(this))->getPreviousDecl(); 00136 } 00137 00138 /// \brief Return the first declaration of this declaration or itself if this 00139 /// is the only declaration. 00140 decl_type *getFirstDecl() { 00141 decl_type *D = static_cast<decl_type*>(this); 00142 while (D->getPreviousDecl()) 00143 D = D->getPreviousDecl(); 00144 return D; 00145 } 00146 00147 /// \brief Return the first declaration of this declaration or itself if this 00148 /// is the only declaration. 00149 const decl_type *getFirstDecl() const { 00150 const decl_type *D = static_cast<const decl_type*>(this); 00151 while (D->getPreviousDecl()) 00152 D = D->getPreviousDecl(); 00153 return D; 00154 } 00155 00156 /// \brief True if this is the first declaration in its redeclaration chain. 00157 bool isFirstDecl() const { return RedeclLink.NextIsLatest(); } 00158 00159 /// \brief Returns the most recent (re)declaration of this declaration. 00160 decl_type *getMostRecentDecl() { 00161 return getFirstDecl()->getNextRedeclaration(); 00162 } 00163 00164 /// \brief Returns the most recent (re)declaration of this declaration. 00165 const decl_type *getMostRecentDecl() const { 00166 return getFirstDecl()->getNextRedeclaration(); 00167 } 00168 00169 /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the 00170 /// first and only declaration. 00171 void setPreviousDecl(decl_type *PrevDecl); 00172 00173 /// \brief Iterates through all the redeclarations of the same decl. 00174 class redecl_iterator { 00175 /// Current - The current declaration. 00176 decl_type *Current; 00177 decl_type *Starter; 00178 bool PassedFirst; 00179 00180 public: 00181 typedef decl_type* value_type; 00182 typedef decl_type* reference; 00183 typedef decl_type* pointer; 00184 typedef std::forward_iterator_tag iterator_category; 00185 typedef std::ptrdiff_t difference_type; 00186 00187 redecl_iterator() : Current(nullptr) { } 00188 explicit redecl_iterator(decl_type *C) 00189 : Current(C), Starter(C), PassedFirst(false) { } 00190 00191 reference operator*() const { return Current; } 00192 pointer operator->() const { return Current; } 00193 00194 redecl_iterator& operator++() { 00195 assert(Current && "Advancing while iterator has reached end"); 00196 // Sanity check to avoid infinite loop on invalid redecl chain. 00197 if (Current->isFirstDecl()) { 00198 if (PassedFirst) { 00199 assert(0 && "Passed first decl twice, invalid redecl chain!"); 00200 Current = nullptr; 00201 return *this; 00202 } 00203 PassedFirst = true; 00204 } 00205 00206 // Get either previous decl or latest decl. 00207 decl_type *Next = Current->getNextRedeclaration(); 00208 Current = (Next != Starter) ? Next : nullptr; 00209 return *this; 00210 } 00211 00212 redecl_iterator operator++(int) { 00213 redecl_iterator tmp(*this); 00214 ++(*this); 00215 return tmp; 00216 } 00217 00218 friend bool operator==(redecl_iterator x, redecl_iterator y) { 00219 return x.Current == y.Current; 00220 } 00221 friend bool operator!=(redecl_iterator x, redecl_iterator y) { 00222 return x.Current != y.Current; 00223 } 00224 }; 00225 00226 typedef llvm::iterator_range<redecl_iterator> redecl_range; 00227 00228 /// \brief Returns an iterator range for all the redeclarations of the same 00229 /// decl. It will iterate at least once (when this decl is the only one). 00230 redecl_range redecls() const { 00231 return redecl_range(redecl_iterator(const_cast<decl_type *>( 00232 static_cast<const decl_type *>(this))), 00233 redecl_iterator()); 00234 } 00235 00236 redecl_iterator redecls_begin() const { return redecls().begin(); } 00237 redecl_iterator redecls_end() const { return redecls().end(); } 00238 00239 friend class ASTDeclReader; 00240 friend class ASTDeclWriter; 00241 }; 00242 00243 /// \brief Get the primary declaration for a declaration from an AST file. That 00244 /// will be the first-loaded declaration. 00245 Decl *getPrimaryMergedDecl(Decl *D); 00246 00247 /// \brief Provides common interface for the Decls that cannot be redeclared, 00248 /// but can be merged if the same declaration is brought in from multiple 00249 /// modules. 00250 template<typename decl_type> 00251 class Mergeable { 00252 public: 00253 Mergeable() {} 00254 00255 /// \brief Return the first declaration of this declaration or itself if this 00256 /// is the only declaration. 00257 decl_type *getFirstDecl() { 00258 decl_type *D = static_cast<decl_type*>(this); 00259 if (!D->isFromASTFile()) 00260 return D; 00261 return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D))); 00262 } 00263 00264 /// \brief Return the first declaration of this declaration or itself if this 00265 /// is the only declaration. 00266 const decl_type *getFirstDecl() const { 00267 const decl_type *D = static_cast<const decl_type*>(this); 00268 if (!D->isFromASTFile()) 00269 return D; 00270 return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D))); 00271 } 00272 00273 /// \brief Returns true if this is the first declaration. 00274 bool isFirstDecl() const { return getFirstDecl() == this; } 00275 }; 00276 00277 } 00278 00279 #endif