clang API Documentation

Redeclarable.h
Go to the documentation of this file.
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