LCOV - code coverage report
Current view: top level - clang/AST - Redeclarable.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 0 36 0.0 %
Date: 2016-01-31 12:01:00 Functions: 0 40 0.0 %

          Line data    Source code
       1             : //===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : //  This file defines the Redeclarable interface.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_CLANG_AST_REDECLARABLE_H
      15             : #define LLVM_CLANG_AST_REDECLARABLE_H
      16             : 
      17             : #include "clang/AST/ExternalASTSource.h"
      18             : #include "llvm/ADT/PointerIntPair.h"
      19             : #include "llvm/Support/Casting.h"
      20             : #include <iterator>
      21             : 
      22             : namespace clang {
      23             : 
      24             : /// \brief Provides common interface for the Decls that can be redeclared.
      25             : template<typename decl_type>
      26             : class Redeclarable {
      27             : protected:
      28             :   class DeclLink {
      29             :     /// A pointer to a known latest declaration, either statically known or
      30             :     /// generationally updated as decls are added by an external source.
      31             :     typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
      32             :                                       &ExternalASTSource::CompleteRedeclChain>
      33             :                                           KnownLatest;
      34             : 
      35             :     typedef const ASTContext *UninitializedLatest;
      36             :     typedef Decl *Previous;
      37             : 
      38             :     /// A pointer to either an uninitialized latest declaration (where either
      39             :     /// we've not yet set the previous decl or there isn't one), or to a known
      40             :     /// previous declaration.
      41             :     typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
      42             : 
      43             :     mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
      44             : 
      45             :   public:
      46             :     enum PreviousTag { PreviousLink };
      47             :     enum LatestTag { LatestLink };
      48             : 
      49             :     DeclLink(LatestTag, const ASTContext &Ctx)
      50             :         : Next(NotKnownLatest(&Ctx)) {}
      51             :     DeclLink(PreviousTag, decl_type *D)
      52             :         : Next(NotKnownLatest(Previous(D))) {}
      53             : 
      54             :     bool NextIsPrevious() const {
      55           0 :       return Next.is<NotKnownLatest>() &&
      56             :              // FIXME: 'template' is required on the next line due to an
      57             :              // apparent clang bug.
      58           0 :              Next.get<NotKnownLatest>().template is<Previous>();
      59             :     }
      60             : 
      61           0 :     bool NextIsLatest() const { return !NextIsPrevious(); }
      62             : 
      63             :     decl_type *getNext(const decl_type *D) const {
      64           0 :       if (Next.is<NotKnownLatest>()) {
      65           0 :         NotKnownLatest NKL = Next.get<NotKnownLatest>();
      66           0 :         if (NKL.is<Previous>())
      67           0 :           return static_cast<decl_type*>(NKL.get<Previous>());
      68             : 
      69             :         // Allocate the generational 'most recent' cache now, if needed.
      70           0 :         Next = KnownLatest(*NKL.get<UninitializedLatest>(),
      71           0 :                            const_cast<decl_type *>(D));
      72           0 :       }
      73             : 
      74           0 :       return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
      75           0 :     }
      76             : 
      77             :     void setPrevious(decl_type *D) {
      78             :       assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
      79             :       Next = Previous(D);
      80             :     }
      81             : 
      82             :     void setLatest(decl_type *D) {
      83             :       assert(NextIsLatest() && "decl became canonical unexpectedly");
      84             :       if (Next.is<NotKnownLatest>()) {
      85             :         NotKnownLatest NKL = Next.get<NotKnownLatest>();
      86             :         Next = KnownLatest(*NKL.get<UninitializedLatest>(), D);
      87             :       } else {
      88             :         auto Latest = Next.get<KnownLatest>();
      89             :         Latest.set(D);
      90             :         Next = Latest;
      91             :       }
      92             :     }
      93             : 
      94             :     void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
      95             : 
      96             :     Decl *getLatestNotUpdated() const {
      97             :       assert(NextIsLatest() && "expected a canonical decl");
      98             :       if (Next.is<NotKnownLatest>())
      99             :         return nullptr;
     100             :       return Next.get<KnownLatest>().getNotUpdated();
     101             :     }
     102             :   };
     103             : 
     104             :   static DeclLink PreviousDeclLink(decl_type *D) {
     105             :     return DeclLink(DeclLink::PreviousLink, D);
     106             :   }
     107             : 
     108             :   static DeclLink LatestDeclLink(const ASTContext &Ctx) {
     109             :     return DeclLink(DeclLink::LatestLink, Ctx);
     110             :   }
     111             : 
     112             :   /// \brief Points to the next redeclaration in the chain.
     113             :   ///
     114             :   /// If NextIsPrevious() is true, this is a link to the previous declaration
     115             :   /// of this same Decl. If NextIsLatest() is true, this is the first
     116             :   /// declaration and Link points to the latest declaration. For example:
     117             :   ///
     118             :   ///  #1 int f(int x, int y = 1); // <pointer to #3, true>
     119             :   ///  #2 int f(int x = 0, int y); // <pointer to #1, false>
     120             :   ///  #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
     121             :   ///
     122             :   /// If there is only one declaration, it is <pointer to self, true>
     123             :   DeclLink RedeclLink;
     124             :   decl_type *First;
     125             : 
     126             :   decl_type *getNextRedeclaration() const {
     127           0 :     return RedeclLink.getNext(static_cast<const decl_type *>(this));
     128             :   }
     129             : 
     130             : public:
     131             :  Redeclarable(const ASTContext &Ctx)
     132             :      : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
     133             : 
     134             :   /// \brief Return the previous declaration of this declaration or NULL if this
     135             :   /// is the first declaration.
     136             :   decl_type *getPreviousDecl() {
     137           0 :     if (RedeclLink.NextIsPrevious())
     138           0 :       return getNextRedeclaration();
     139           0 :     return nullptr;
     140           0 :   }
     141             :   const decl_type *getPreviousDecl() const {
     142             :     return const_cast<decl_type *>(
     143             :                  static_cast<const decl_type*>(this))->getPreviousDecl();
     144             :   }
     145             : 
     146             :   /// \brief Return the first declaration of this declaration or itself if this
     147             :   /// is the only declaration.
     148           0 :   decl_type *getFirstDecl() { return First; }
     149             : 
     150             :   /// \brief Return the first declaration of this declaration or itself if this
     151             :   /// is the only declaration.
     152             :   const decl_type *getFirstDecl() const { return First; }
     153             : 
     154             :   /// \brief True if this is the first declaration in its redeclaration chain.
     155           0 :   bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
     156             : 
     157             :   /// \brief Returns the most recent (re)declaration of this declaration.
     158             :   decl_type *getMostRecentDecl() {
     159           0 :     return getFirstDecl()->getNextRedeclaration();
     160             :   }
     161             : 
     162             :   /// \brief Returns the most recent (re)declaration of this declaration.
     163             :   const decl_type *getMostRecentDecl() const {
     164             :     return getFirstDecl()->getNextRedeclaration();
     165             :   }
     166             : 
     167             :   /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
     168             :   /// first and only declaration.
     169             :   void setPreviousDecl(decl_type *PrevDecl);
     170             : 
     171             :   /// \brief Iterates through all the redeclarations of the same decl.
     172             :   class redecl_iterator {
     173             :     /// Current - The current declaration.
     174             :     decl_type *Current;
     175             :     decl_type *Starter;
     176             :     bool PassedFirst;
     177             : 
     178             :   public:
     179             :     typedef decl_type*                value_type;
     180             :     typedef decl_type*                reference;
     181             :     typedef decl_type*                pointer;
     182             :     typedef std::forward_iterator_tag iterator_category;
     183             :     typedef std::ptrdiff_t            difference_type;
     184             : 
     185           0 :     redecl_iterator() : Current(nullptr) { }
     186             :     explicit redecl_iterator(decl_type *C)
     187           0 :       : Current(C), Starter(C), PassedFirst(false) { }
     188             : 
     189           0 :     reference operator*() const { return Current; }
     190             :     pointer operator->() const { return Current; }
     191             : 
     192             :     redecl_iterator& operator++() {
     193           0 :       assert(Current && "Advancing while iterator has reached end");
     194             :       // Sanity check to avoid infinite loop on invalid redecl chain.
     195           0 :       if (Current->isFirstDecl()) {
     196           0 :         if (PassedFirst) {
     197           0 :           assert(0 && "Passed first decl twice, invalid redecl chain!");
     198             :           Current = nullptr;
     199             :           return *this;
     200             :         }
     201           0 :         PassedFirst = true;
     202           0 :       }
     203             : 
     204             :       // Get either previous decl or latest decl.
     205           0 :       decl_type *Next = Current->getNextRedeclaration();
     206           0 :       Current = (Next != Starter) ? Next : nullptr;
     207           0 :       return *this;
     208             :     }
     209             : 
     210             :     redecl_iterator operator++(int) {
     211             :       redecl_iterator tmp(*this);
     212             :       ++(*this);
     213             :       return tmp;
     214             :     }
     215             : 
     216             :     friend bool operator==(redecl_iterator x, redecl_iterator y) {
     217             :       return x.Current == y.Current;
     218             :     }
     219             :     friend bool operator!=(redecl_iterator x, redecl_iterator y) {
     220           0 :       return x.Current != y.Current;
     221             :     }
     222             :   };
     223             : 
     224             :   typedef llvm::iterator_range<redecl_iterator> redecl_range;
     225             : 
     226             :   /// \brief Returns an iterator range for all the redeclarations of the same
     227             :   /// decl. It will iterate at least once (when this decl is the only one).
     228             :   redecl_range redecls() const {
     229           0 :     return redecl_range(redecl_iterator(const_cast<decl_type *>(
     230           0 :                             static_cast<const decl_type *>(this))),
     231           0 :                         redecl_iterator());
     232             :   }
     233             : 
     234             :   redecl_iterator redecls_begin() const { return redecls().begin(); }
     235             :   redecl_iterator redecls_end() const { return redecls().end(); }
     236             : 
     237             :   friend class ASTDeclReader;
     238             :   friend class ASTDeclWriter;
     239             : };
     240             : 
     241             : /// \brief Get the primary declaration for a declaration from an AST file. That
     242             : /// will be the first-loaded declaration.
     243             : Decl *getPrimaryMergedDecl(Decl *D);
     244             : 
     245             : /// \brief Provides common interface for the Decls that cannot be redeclared,
     246             : /// but can be merged if the same declaration is brought in from multiple
     247             : /// modules.
     248             : template<typename decl_type>
     249             : class Mergeable {
     250             : public:
     251             :   Mergeable() {}
     252             : 
     253             :   /// \brief Return the first declaration of this declaration or itself if this
     254             :   /// is the only declaration.
     255             :   decl_type *getFirstDecl() {
     256             :     decl_type *D = static_cast<decl_type*>(this);
     257             :     if (!D->isFromASTFile())
     258             :       return D;
     259             :     return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
     260             :   }
     261             : 
     262             :   /// \brief Return the first declaration of this declaration or itself if this
     263             :   /// is the only declaration.
     264             :   const decl_type *getFirstDecl() const {
     265             :     const decl_type *D = static_cast<const decl_type*>(this);
     266             :     if (!D->isFromASTFile())
     267             :       return D;
     268             :     return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
     269             :   }
     270             : 
     271             :   /// \brief Returns true if this is the first declaration.
     272             :   bool isFirstDecl() const { return getFirstDecl() == this; }
     273             : };
     274             : 
     275             : }
     276             : 
     277             : #endif

Generated by: LCOV version 1.11