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 "llvm/ADT/PointerIntPair.h" 18 #include "llvm/Support/Casting.h" 19 #include <iterator> 20 21 namespace clang { 22 23 /// \brief Provides common interface for the Decls that can be redeclared. 24 template<typename decl_type> 25 class Redeclarable { 26 27 protected: 28 // FIXME: PointerIntPair is a value class that should not be inherited from. 29 // This should change to using containment. 30 struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> { 31 DeclLink(decl_type *D, bool isLatest) 32 : llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { } 33 34 typedef llvm::PointerIntPair<decl_type *, 1, bool> base_type; 35 36 bool NextIsPrevious() const { return base_type::getInt() == false; } 37 bool NextIsLatest() const { return base_type::getInt() == true; } 38 decl_type *getNext() const { return base_type::getPointer(); } 39 }; 40 41 struct PreviousDeclLink : public DeclLink { 42 PreviousDeclLink(decl_type *D) : DeclLink(D, false) { } 43 }; 44 45 struct LatestDeclLink : public DeclLink { 46 LatestDeclLink(decl_type *D) : DeclLink(D, true) { } 47 }; 48 49 /// \brief Points to the next redeclaration in the chain. 50 /// 51 /// If NextIsPrevious() is true, this is a link to the previous declaration 52 /// of this same Decl. If NextIsLatest() is true, this is the first 53 /// declaration and Link points to the latest declaration. For example: 54 /// 55 /// #1 int f(int x, int y = 1); // <pointer to #3, true> 56 /// #2 int f(int x = 0, int y); // <pointer to #1, false> 57 /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false> 58 /// 59 /// If there is only one declaration, it is <pointer to self, true> 60 DeclLink RedeclLink; 61 62 public: 63 Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { } 64 65 /// \brief Return the previous declaration of this declaration or NULL if this 66 /// is the first declaration. 67 decl_type *getPreviousDeclaration() { 68 if (RedeclLink.NextIsPrevious()) 69 return RedeclLink.getNext(); 70 return 0; 71 } 72 const decl_type *getPreviousDeclaration() const { 73 return const_cast<decl_type *>( 74 static_cast<const decl_type*>(this))->getPreviousDeclaration(); 75 } 76 77 /// \brief Return the first declaration of this declaration or itself if this 78 /// is the only declaration. 79 decl_type *getFirstDeclaration() { 80 decl_type *D = static_cast<decl_type*>(this); 81 while (D->getPreviousDeclaration()) 82 D = D->getPreviousDeclaration(); 83 return D; 84 } 85 86 /// \brief Return the first declaration of this declaration or itself if this 87 /// is the only declaration. 88 const decl_type *getFirstDeclaration() const { 89 const decl_type *D = static_cast<const decl_type*>(this); 90 while (D->getPreviousDeclaration()) 91 D = D->getPreviousDeclaration(); 92 return D; 93 } 94 95 /// \brief Returns true if this is the first declaration. 96 bool isFirstDeclaration() const { 97 return RedeclLink.NextIsLatest(); 98 } 99 100 /// \brief Returns the most recent (re)declaration of this declaration. 101 decl_type *getMostRecentDeclaration() { 102 return getFirstDeclaration()->RedeclLink.getNext(); 103 } 104 105 /// \brief Returns the most recent (re)declaration of this declaration. 106 const decl_type *getMostRecentDeclaration() const { 107 return getFirstDeclaration()->RedeclLink.getNext(); 108 } 109 110 /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the 111 /// first and only declaration. 112 void setPreviousDeclaration(decl_type *PrevDecl); 113 114 /// \brief Iterates through all the redeclarations of the same decl. 115 class redecl_iterator { 116 /// Current - The current declaration. 117 decl_type *Current; 118 decl_type *Starter; 119 120 public: 121 typedef decl_type* value_type; 122 typedef decl_type* reference; 123 typedef decl_type* pointer; 124 typedef std::forward_iterator_tag iterator_category; 125 typedef std::ptrdiff_t difference_type; 126 127 redecl_iterator() : Current(0) { } 128 explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) { } 129 130 reference operator*() const { return Current; } 131 pointer operator->() const { return Current; } 132 133 redecl_iterator& operator++() { 134 assert(Current && "Advancing while iterator has reached end"); 135 // Get either previous decl or latest decl. 136 decl_type *Next = Current->RedeclLink.getNext(); 137 Current = (Next != Starter ? Next : 0); 138 return *this; 139 } 140 141 redecl_iterator operator++(int) { 142 redecl_iterator tmp(*this); 143 ++(*this); 144 return tmp; 145 } 146 147 friend bool operator==(redecl_iterator x, redecl_iterator y) { 148 return x.Current == y.Current; 149 } 150 friend bool operator!=(redecl_iterator x, redecl_iterator y) { 151 return x.Current != y.Current; 152 } 153 }; 154 155 /// \brief Returns iterator for all the redeclarations of the same decl. 156 /// It will iterate at least once (when this decl is the only one). 157 redecl_iterator redecls_begin() const { 158 return redecl_iterator(const_cast<decl_type*>( 159 static_cast<const decl_type*>(this))); 160 } 161 redecl_iterator redecls_end() const { return redecl_iterator(); } 162 163 friend class ASTDeclReader; 164 friend class ASTDeclWriter; 165 }; 166 167 } 168 169 #endif 170