Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:41

0001 //===- Redeclarable.h - Base for Decls that can be redeclared --*- C++ -*-====//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the Redeclarable interface.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_REDECLARABLE_H
0014 #define LLVM_CLANG_AST_REDECLARABLE_H
0015 
0016 #include "clang/AST/ExternalASTSource.h"
0017 #include "llvm/ADT/DenseMapInfo.h"
0018 #include "llvm/ADT/PointerUnion.h"
0019 #include "llvm/ADT/iterator_range.h"
0020 #include "llvm/Support/Casting.h"
0021 #include <cassert>
0022 #include <cstddef>
0023 #include <iterator>
0024 
0025 namespace clang {
0026 
0027 class ASTContext;
0028 class Decl;
0029 
0030 // Some notes on redeclarables:
0031 //
0032 //  - Every redeclarable is on a circular linked list.
0033 //
0034 //  - Every decl has a pointer to the first element of the chain _and_ a
0035 //    DeclLink that may point to one of 3 possible states:
0036 //      - the "previous" (temporal) element in the chain
0037 //      - the "latest" (temporal) element in the chain
0038 //      - the "uninitialized-latest" value (when newly-constructed)
0039 //
0040 //  - The first element is also often called the canonical element. Every
0041 //    element has a pointer to it so that "getCanonical" can be fast.
0042 //
0043 //  - Most links in the chain point to previous, except the link out of
0044 //    the first; it points to latest.
0045 //
0046 //  - Elements are called "first", "previous", "latest" or
0047 //    "most-recent" when referring to temporal order: order of addition
0048 //    to the chain.
0049 //
0050 //  - It's easiest to just ignore the implementation of DeclLink when making
0051 //    sense of the redeclaration chain.
0052 //
0053 //  - There's also a "definition" link for several types of
0054 //    redeclarable, where only one definition should exist at any given
0055 //    time (and the defn pointer is stored in the decl's "data" which
0056 //    is copied to every element on the chain when it's changed).
0057 //
0058 //    Here is some ASCII art:
0059 //
0060 //      "first"                                     "latest"
0061 //      "canonical"                                 "most recent"
0062 //      +------------+         first                +--------------+
0063 //      |            | <--------------------------- |              |
0064 //      |            |                              |              |
0065 //      |            |                              |              |
0066 //      |            |       +--------------+       |              |
0067 //      |            | first |              |       |              |
0068 //      |            | <---- |              |       |              |
0069 //      |            |       |              |       |              |
0070 //      | @class A   |  link | @interface A |  link | @class A     |
0071 //      | seen first | <---- | seen second  | <---- | seen third   |
0072 //      |            |       |              |       |              |
0073 //      +------------+       +--------------+       +--------------+
0074 //      | data       | defn  | data         |  defn | data         |
0075 //      |            | ----> |              | <---- |              |
0076 //      +------------+       +--------------+       +--------------+
0077 //        |                     |     ^                  ^
0078 //        |                     |defn |                  |
0079 //        | link                +-----+                  |
0080 //        +-->-------------------------------------------+
0081 
0082 /// Provides common interface for the Decls that can be redeclared.
0083 template<typename decl_type>
0084 class Redeclarable {
0085 protected:
0086   class DeclLink {
0087     /// A pointer to a known latest declaration, either statically known or
0088     /// generationally updated as decls are added by an external source.
0089     using KnownLatest =
0090         LazyGenerationalUpdatePtr<const Decl *, Decl *,
0091                                   &ExternalASTSource::CompleteRedeclChain>;
0092 
0093     /// We store a pointer to the ASTContext in the UninitializedLatest
0094     /// pointer, but to avoid circular type dependencies when we steal the low
0095     /// bits of this pointer, we use a raw void* here.
0096     using UninitializedLatest = const void *;
0097 
0098     using Previous = Decl *;
0099 
0100     /// A pointer to either an uninitialized latest declaration (where either
0101     /// we've not yet set the previous decl or there isn't one), or to a known
0102     /// previous declaration.
0103     using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
0104 
0105     mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Link;
0106 
0107   public:
0108     enum PreviousTag { PreviousLink };
0109     enum LatestTag { LatestLink };
0110 
0111     DeclLink(LatestTag, const ASTContext &Ctx)
0112         : Link(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
0113     DeclLink(PreviousTag, decl_type *D) : Link(NotKnownLatest(Previous(D))) {}
0114 
0115     bool isFirst() const {
0116       return isa<KnownLatest>(Link) ||
0117              // FIXME: 'template' is required on the next line due to an
0118              // apparent clang bug.
0119              isa<UninitializedLatest>(cast<NotKnownLatest>(Link));
0120     }
0121 
0122     decl_type *getPrevious(const decl_type *D) const {
0123       if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
0124         if (auto *Prev = dyn_cast<Previous>(NKL))
0125           return static_cast<decl_type *>(Prev);
0126 
0127         // Allocate the generational 'most recent' cache now, if needed.
0128         Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
0129                                cast<UninitializedLatest>(NKL)),
0130                            const_cast<decl_type *>(D));
0131       }
0132 
0133       return static_cast<decl_type *>(cast<KnownLatest>(Link).get(D));
0134     }
0135 
0136     void setPrevious(decl_type *D) {
0137       assert(!isFirst() && "decl became non-canonical unexpectedly");
0138       Link = Previous(D);
0139     }
0140 
0141     void setLatest(decl_type *D) {
0142       assert(isFirst() && "decl became canonical unexpectedly");
0143       if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
0144         Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
0145                                cast<UninitializedLatest>(NKL)),
0146                            D);
0147       } else {
0148         auto Latest = cast<KnownLatest>(Link);
0149         Latest.set(D);
0150         Link = Latest;
0151       }
0152     }
0153 
0154     void markIncomplete() { cast<KnownLatest>(Link).markIncomplete(); }
0155 
0156     Decl *getLatestNotUpdated() const {
0157       assert(isFirst() && "expected a canonical decl");
0158       if (isa<NotKnownLatest>(Link))
0159         return nullptr;
0160       return cast<KnownLatest>(Link).getNotUpdated();
0161     }
0162   };
0163 
0164   static DeclLink PreviousDeclLink(decl_type *D) {
0165     return DeclLink(DeclLink::PreviousLink, D);
0166   }
0167 
0168   static DeclLink LatestDeclLink(const ASTContext &Ctx) {
0169     return DeclLink(DeclLink::LatestLink, Ctx);
0170   }
0171 
0172   /// Points to the next redeclaration in the chain.
0173   ///
0174   /// If isFirst() is false, this is a link to the previous declaration
0175   /// of this same Decl. If isFirst() is true, this is the first
0176   /// declaration and Link points to the latest declaration. For example:
0177   ///
0178   ///  #1 int f(int x, int y = 1); // <pointer to #3, true>
0179   ///  #2 int f(int x = 0, int y); // <pointer to #1, false>
0180   ///  #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
0181   ///
0182   /// If there is only one declaration, it is <pointer to self, true>
0183   DeclLink RedeclLink;
0184 
0185   decl_type *First;
0186 
0187   decl_type *getNextRedeclaration() const {
0188     return RedeclLink.getPrevious(static_cast<const decl_type *>(this));
0189   }
0190 
0191 public:
0192   friend class ASTDeclMerger;
0193   friend class ASTDeclReader;
0194   friend class ASTDeclWriter;
0195   friend class IncrementalParser;
0196 
0197   Redeclarable(const ASTContext &Ctx)
0198       : RedeclLink(LatestDeclLink(Ctx)),
0199         First(static_cast<decl_type *>(this)) {}
0200 
0201   /// Return the previous declaration of this declaration or NULL if this
0202   /// is the first declaration.
0203   decl_type *getPreviousDecl() {
0204     if (!RedeclLink.isFirst())
0205       return getNextRedeclaration();
0206     return nullptr;
0207   }
0208   const decl_type *getPreviousDecl() const {
0209     return const_cast<decl_type *>(
0210                  static_cast<const decl_type*>(this))->getPreviousDecl();
0211   }
0212 
0213   /// Return the first declaration of this declaration or itself if this
0214   /// is the only declaration.
0215   decl_type *getFirstDecl() { return First; }
0216 
0217   /// Return the first declaration of this declaration or itself if this
0218   /// is the only declaration.
0219   const decl_type *getFirstDecl() const { return First; }
0220 
0221   /// True if this is the first declaration in its redeclaration chain.
0222   bool isFirstDecl() const { return RedeclLink.isFirst(); }
0223 
0224   /// Returns the most recent (re)declaration of this declaration.
0225   decl_type *getMostRecentDecl() {
0226     return getFirstDecl()->getNextRedeclaration();
0227   }
0228 
0229   /// Returns the most recent (re)declaration of this declaration.
0230   const decl_type *getMostRecentDecl() const {
0231     return getFirstDecl()->getNextRedeclaration();
0232   }
0233 
0234   /// Set the previous declaration. If PrevDecl is NULL, set this as the
0235   /// first and only declaration.
0236   void setPreviousDecl(decl_type *PrevDecl);
0237 
0238   /// Iterates through all the redeclarations of the same decl.
0239   class redecl_iterator {
0240     /// Current - The current declaration.
0241     decl_type *Current = nullptr;
0242     decl_type *Starter = nullptr;
0243     bool PassedFirst = false;
0244 
0245   public:
0246     using value_type = decl_type *;
0247     using reference = decl_type *;
0248     using pointer = decl_type *;
0249     using iterator_category = std::forward_iterator_tag;
0250     using difference_type = std::ptrdiff_t;
0251 
0252     redecl_iterator() = default;
0253     explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) {}
0254 
0255     reference operator*() const { return Current; }
0256     pointer operator->() const { return Current; }
0257 
0258     redecl_iterator& operator++() {
0259       assert(Current && "Advancing while iterator has reached end");
0260       // Make sure we don't infinitely loop on an invalid redecl chain. This
0261       // should never happen.
0262       if (Current->isFirstDecl()) {
0263         if (PassedFirst) {
0264           assert(0 && "Passed first decl twice, invalid redecl chain!");
0265           Current = nullptr;
0266           return *this;
0267         }
0268         PassedFirst = true;
0269       }
0270 
0271       // Get either previous decl or latest decl.
0272       decl_type *Next = Current->getNextRedeclaration();
0273       Current = (Next != Starter) ? Next : nullptr;
0274       return *this;
0275     }
0276 
0277     redecl_iterator operator++(int) {
0278       redecl_iterator tmp(*this);
0279       ++(*this);
0280       return tmp;
0281     }
0282 
0283     friend bool operator==(const redecl_iterator &x, const redecl_iterator &y) {
0284       return x.Current == y.Current;
0285     }
0286     friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y) {
0287       return x.Current != y.Current;
0288     }
0289   };
0290 
0291   using redecl_range = llvm::iterator_range<redecl_iterator>;
0292 
0293   /// Returns an iterator range for all the redeclarations of the same
0294   /// decl. It will iterate at least once (when this decl is the only one).
0295   redecl_range redecls() const {
0296     return redecl_range(redecl_iterator(const_cast<decl_type *>(
0297                             static_cast<const decl_type *>(this))),
0298                         redecl_iterator());
0299   }
0300 
0301   redecl_iterator redecls_begin() const { return redecls().begin(); }
0302   redecl_iterator redecls_end() const { return redecls().end(); }
0303 };
0304 
0305 /// Get the primary declaration for a declaration from an AST file. That
0306 /// will be the first-loaded declaration.
0307 Decl *getPrimaryMergedDecl(Decl *D);
0308 
0309 /// Provides common interface for the Decls that cannot be redeclared,
0310 /// but can be merged if the same declaration is brought in from multiple
0311 /// modules.
0312 template<typename decl_type>
0313 class Mergeable {
0314 public:
0315   Mergeable() = default;
0316 
0317   /// Return the first declaration of this declaration or itself if this
0318   /// is the only declaration.
0319   decl_type *getFirstDecl() {
0320     auto *D = static_cast<decl_type *>(this);
0321     if (!D->isFromASTFile())
0322       return D;
0323     return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
0324   }
0325 
0326   /// Return the first declaration of this declaration or itself if this
0327   /// is the only declaration.
0328   const decl_type *getFirstDecl() const {
0329     const auto *D = static_cast<const decl_type *>(this);
0330     if (!D->isFromASTFile())
0331       return D;
0332     return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
0333   }
0334 
0335   /// Returns true if this is the first declaration.
0336   bool isFirstDecl() const { return getFirstDecl() == this; }
0337 };
0338 
0339 /// A wrapper class around a pointer that always points to its canonical
0340 /// declaration.
0341 ///
0342 /// CanonicalDeclPtr<decl_type> behaves just like decl_type*, except we call
0343 /// decl_type::getCanonicalDecl() on construction.
0344 ///
0345 /// This is useful for hashtables that you want to be keyed on a declaration's
0346 /// canonical decl -- if you use CanonicalDeclPtr as the key, you don't need to
0347 /// remember to call getCanonicalDecl() everywhere.
0348 template <typename decl_type> class CanonicalDeclPtr {
0349 public:
0350   CanonicalDeclPtr() = default;
0351   CanonicalDeclPtr(decl_type *Ptr)
0352       : Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
0353   CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
0354   CanonicalDeclPtr &operator=(const CanonicalDeclPtr &) = default;
0355 
0356   operator decl_type *() { return Ptr; }
0357   operator const decl_type *() const { return Ptr; }
0358 
0359   decl_type *operator->() { return Ptr; }
0360   const decl_type *operator->() const { return Ptr; }
0361 
0362   decl_type &operator*() { return *Ptr; }
0363   const decl_type &operator*() const { return *Ptr; }
0364 
0365   friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS) {
0366     return LHS.Ptr == RHS.Ptr;
0367   }
0368   friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS) {
0369     return LHS.Ptr != RHS.Ptr;
0370   }
0371 
0372 private:
0373   friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
0374   friend struct llvm::PointerLikeTypeTraits<CanonicalDeclPtr<decl_type>>;
0375 
0376   decl_type *Ptr = nullptr;
0377 };
0378 
0379 } // namespace clang
0380 
0381 namespace llvm {
0382 
0383 template <typename decl_type>
0384 struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
0385   using CanonicalDeclPtr = clang::CanonicalDeclPtr<decl_type>;
0386   using BaseInfo = DenseMapInfo<decl_type *>;
0387 
0388   static CanonicalDeclPtr getEmptyKey() {
0389     // Construct our CanonicalDeclPtr this way because the regular constructor
0390     // would dereference P.Ptr, which is not allowed.
0391     CanonicalDeclPtr P;
0392     P.Ptr = BaseInfo::getEmptyKey();
0393     return P;
0394   }
0395 
0396   static CanonicalDeclPtr getTombstoneKey() {
0397     CanonicalDeclPtr P;
0398     P.Ptr = BaseInfo::getTombstoneKey();
0399     return P;
0400   }
0401 
0402   static unsigned getHashValue(const CanonicalDeclPtr &P) {
0403     return BaseInfo::getHashValue(P);
0404   }
0405 
0406   static bool isEqual(const CanonicalDeclPtr &LHS,
0407                       const CanonicalDeclPtr &RHS) {
0408     return BaseInfo::isEqual(LHS, RHS);
0409   }
0410 };
0411 
0412 template <typename decl_type>
0413 struct PointerLikeTypeTraits<clang::CanonicalDeclPtr<decl_type>> {
0414   static inline void *getAsVoidPointer(clang::CanonicalDeclPtr<decl_type> P) {
0415     return P.Ptr;
0416   }
0417   static inline clang::CanonicalDeclPtr<decl_type> getFromVoidPointer(void *P) {
0418     clang::CanonicalDeclPtr<decl_type> C;
0419     C.Ptr = PointerLikeTypeTraits<decl_type *>::getFromVoidPtr(P);
0420     return C;
0421   }
0422   static constexpr int NumLowBitsAvailable =
0423       PointerLikeTypeTraits<decl_type *>::NumLowBitsAvailable;
0424 };
0425 
0426 } // namespace llvm
0427 
0428 #endif // LLVM_CLANG_AST_REDECLARABLE_H