summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/Redeclarable.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Redeclarable.h')
-rw-r--r--include/clang/AST/Redeclarable.h285
1 files changed, 0 insertions, 285 deletions
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
deleted file mode 100644
index eaa22f8..0000000
--- a/include/clang/AST/Redeclarable.h
+++ /dev/null
@@ -1,285 +0,0 @@
-//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Redeclarable interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_REDECLARABLE_H
-#define LLVM_CLANG_AST_REDECLARABLE_H
-
-#include "clang/AST/ExternalASTSource.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Casting.h"
-#include <iterator>
-
-namespace clang {
-class ASTContext;
-
-/// \brief Provides common interface for the Decls that can be redeclared.
-template<typename decl_type>
-class Redeclarable {
-protected:
- class DeclLink {
- /// A pointer to a known latest declaration, either statically known or
- /// generationally updated as decls are added by an external source.
- typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
- &ExternalASTSource::CompleteRedeclChain>
- KnownLatest;
-
- /// We store a pointer to the ASTContext in the UninitializedLatest
- /// pointer, but to avoid circular type dependencies when we steal the low
- /// bits of this pointer, we use a raw void* here.
- typedef const void *UninitializedLatest;
-
- typedef Decl *Previous;
-
- /// A pointer to either an uninitialized latest declaration (where either
- /// we've not yet set the previous decl or there isn't one), or to a known
- /// previous declaration.
- typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
-
- mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
-
- public:
- enum PreviousTag { PreviousLink };
- enum LatestTag { LatestLink };
-
- DeclLink(LatestTag, const ASTContext &Ctx)
- : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
- DeclLink(PreviousTag, decl_type *D)
- : Next(NotKnownLatest(Previous(D))) {}
-
- bool NextIsPrevious() const {
- return Next.is<NotKnownLatest>() &&
- // FIXME: 'template' is required on the next line due to an
- // apparent clang bug.
- Next.get<NotKnownLatest>().template is<Previous>();
- }
-
- bool NextIsLatest() const { return !NextIsPrevious(); }
-
- decl_type *getNext(const decl_type *D) const {
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.get<NotKnownLatest>();
- if (NKL.is<Previous>())
- return static_cast<decl_type*>(NKL.get<Previous>());
-
- // Allocate the generational 'most recent' cache now, if needed.
- Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
- NKL.get<UninitializedLatest>()),
- const_cast<decl_type *>(D));
- }
-
- return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
- }
-
- void setPrevious(decl_type *D) {
- assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
- Next = Previous(D);
- }
-
- void setLatest(decl_type *D) {
- assert(NextIsLatest() && "decl became canonical unexpectedly");
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.get<NotKnownLatest>();
- Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
- NKL.get<UninitializedLatest>()),
- D);
- } else {
- auto Latest = Next.get<KnownLatest>();
- Latest.set(D);
- Next = Latest;
- }
- }
-
- void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
-
- Decl *getLatestNotUpdated() const {
- assert(NextIsLatest() && "expected a canonical decl");
- if (Next.is<NotKnownLatest>())
- return nullptr;
- return Next.get<KnownLatest>().getNotUpdated();
- }
- };
-
- static DeclLink PreviousDeclLink(decl_type *D) {
- return DeclLink(DeclLink::PreviousLink, D);
- }
-
- static DeclLink LatestDeclLink(const ASTContext &Ctx) {
- return DeclLink(DeclLink::LatestLink, Ctx);
- }
-
- /// \brief Points to the next redeclaration in the chain.
- ///
- /// If NextIsPrevious() is true, this is a link to the previous declaration
- /// of this same Decl. If NextIsLatest() is true, this is the first
- /// declaration and Link points to the latest declaration. For example:
- ///
- /// #1 int f(int x, int y = 1); // <pointer to #3, true>
- /// #2 int f(int x = 0, int y); // <pointer to #1, false>
- /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
- ///
- /// If there is only one declaration, it is <pointer to self, true>
- DeclLink RedeclLink;
- decl_type *First;
-
- decl_type *getNextRedeclaration() const {
- return RedeclLink.getNext(static_cast<const decl_type *>(this));
- }
-
-public:
- Redeclarable(const ASTContext &Ctx)
- : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
-
- /// \brief Return the previous declaration of this declaration or NULL if this
- /// is the first declaration.
- decl_type *getPreviousDecl() {
- if (RedeclLink.NextIsPrevious())
- return getNextRedeclaration();
- return nullptr;
- }
- const decl_type *getPreviousDecl() const {
- return const_cast<decl_type *>(
- static_cast<const decl_type*>(this))->getPreviousDecl();
- }
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- decl_type *getFirstDecl() { return First; }
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- const decl_type *getFirstDecl() const { return First; }
-
- /// \brief True if this is the first declaration in its redeclaration chain.
- bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
-
- /// \brief Returns the most recent (re)declaration of this declaration.
- decl_type *getMostRecentDecl() {
- return getFirstDecl()->getNextRedeclaration();
- }
-
- /// \brief Returns the most recent (re)declaration of this declaration.
- const decl_type *getMostRecentDecl() const {
- return getFirstDecl()->getNextRedeclaration();
- }
-
- /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
- /// first and only declaration.
- void setPreviousDecl(decl_type *PrevDecl);
-
- /// \brief Iterates through all the redeclarations of the same decl.
- class redecl_iterator {
- /// Current - The current declaration.
- decl_type *Current;
- decl_type *Starter;
- bool PassedFirst;
-
- public:
- typedef decl_type* value_type;
- typedef decl_type* reference;
- typedef decl_type* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(decl_type *C)
- : Current(C), Starter(C), PassedFirst(false) { }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- redecl_iterator& operator++() {
- assert(Current && "Advancing while iterator has reached end");
- // Sanity check to avoid infinite loop on invalid redecl chain.
- if (Current->isFirstDecl()) {
- if (PassedFirst) {
- assert(0 && "Passed first decl twice, invalid redecl chain!");
- Current = nullptr;
- return *this;
- }
- PassedFirst = true;
- }
-
- // Get either previous decl or latest decl.
- decl_type *Next = Current->getNextRedeclaration();
- Current = (Next != Starter) ? Next : nullptr;
- return *this;
- }
-
- redecl_iterator operator++(int) {
- redecl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(redecl_iterator x, redecl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(redecl_iterator x, redecl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
-
- /// \brief Returns an iterator range for all the redeclarations of the same
- /// decl. It will iterate at least once (when this decl is the only one).
- redecl_range redecls() const {
- return redecl_range(redecl_iterator(const_cast<decl_type *>(
- static_cast<const decl_type *>(this))),
- redecl_iterator());
- }
-
- redecl_iterator redecls_begin() const { return redecls().begin(); }
- redecl_iterator redecls_end() const { return redecls().end(); }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Get the primary declaration for a declaration from an AST file. That
-/// will be the first-loaded declaration.
-Decl *getPrimaryMergedDecl(Decl *D);
-
-/// \brief Provides common interface for the Decls that cannot be redeclared,
-/// but can be merged if the same declaration is brought in from multiple
-/// modules.
-template<typename decl_type>
-class Mergeable {
-public:
- Mergeable() {}
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- decl_type *getFirstDecl() {
- decl_type *D = static_cast<decl_type*>(this);
- if (!D->isFromASTFile())
- return D;
- return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
- }
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- const decl_type *getFirstDecl() const {
- const decl_type *D = static_cast<const decl_type*>(this);
- if (!D->isFromASTFile())
- return D;
- return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
- }
-
- /// \brief Returns true if this is the first declaration.
- bool isFirstDecl() const { return getFirstDecl() == this; }
-};
-
-}
-
-#endif
OpenPOWER on IntegriCloud