clang API Documentation
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 "llvm/ADT/PointerIntPair.h" 00018 #include "llvm/Support/Casting.h" 00019 #include <iterator> 00020 00021 namespace clang { 00022 00023 /// \brief Provides common interface for the Decls that can be redeclared. 00024 template<typename decl_type> 00025 class Redeclarable { 00026 00027 protected: 00028 // FIXME: PointerIntPair is a value class that should not be inherited from. 00029 // This should change to using containment. 00030 struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> { 00031 DeclLink(decl_type *D, bool isLatest) 00032 : llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { } 00033 00034 typedef llvm::PointerIntPair<decl_type *, 1, bool> base_type; 00035 00036 bool NextIsPrevious() const { return base_type::getInt() == false; } 00037 bool NextIsLatest() const { return base_type::getInt() == true; } 00038 decl_type *getNext() const { return base_type::getPointer(); } 00039 }; 00040 00041 struct PreviousDeclLink : public DeclLink { 00042 PreviousDeclLink(decl_type *D) : DeclLink(D, false) { } 00043 }; 00044 00045 struct LatestDeclLink : public DeclLink { 00046 LatestDeclLink(decl_type *D) : DeclLink(D, true) { } 00047 }; 00048 00049 /// \brief Points to the next redeclaration in the chain. 00050 /// 00051 /// If NextIsPrevious() is true, this is a link to the previous declaration 00052 /// of this same Decl. If NextIsLatest() is true, this is the first 00053 /// declaration and Link points to the latest declaration. For example: 00054 /// 00055 /// #1 int f(int x, int y = 1); // <pointer to #3, true> 00056 /// #2 int f(int x = 0, int y); // <pointer to #1, false> 00057 /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false> 00058 /// 00059 /// If there is only one declaration, it is <pointer to self, true> 00060 DeclLink RedeclLink; 00061 00062 public: 00063 Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { } 00064 00065 /// \brief Return the previous declaration of this declaration or NULL if this 00066 /// is the first declaration. 00067 decl_type *getPreviousDecl() { 00068 if (RedeclLink.NextIsPrevious()) 00069 return RedeclLink.getNext(); 00070 return 0; 00071 } 00072 const decl_type *getPreviousDecl() const { 00073 return const_cast<decl_type *>( 00074 static_cast<const decl_type*>(this))->getPreviousDecl(); 00075 } 00076 00077 /// \brief Return the first declaration of this declaration or itself if this 00078 /// is the only declaration. 00079 decl_type *getFirstDeclaration() { 00080 decl_type *D = static_cast<decl_type*>(this); 00081 while (D->getPreviousDecl()) 00082 D = D->getPreviousDecl(); 00083 return D; 00084 } 00085 00086 /// \brief Return the first declaration of this declaration or itself if this 00087 /// is the only declaration. 00088 const decl_type *getFirstDeclaration() const { 00089 const decl_type *D = static_cast<const decl_type*>(this); 00090 while (D->getPreviousDecl()) 00091 D = D->getPreviousDecl(); 00092 return D; 00093 } 00094 00095 /// \brief Returns true if this is the first declaration. 00096 bool isFirstDeclaration() const { 00097 return RedeclLink.NextIsLatest(); 00098 } 00099 00100 /// \brief Returns the most recent (re)declaration of this declaration. 00101 decl_type *getMostRecentDecl() { 00102 return getFirstDeclaration()->RedeclLink.getNext(); 00103 } 00104 00105 /// \brief Returns the most recent (re)declaration of this declaration. 00106 const decl_type *getMostRecentDecl() const { 00107 return getFirstDeclaration()->RedeclLink.getNext(); 00108 } 00109 00110 /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the 00111 /// first and only declaration. 00112 void setPreviousDeclaration(decl_type *PrevDecl); 00113 00114 /// \brief Iterates through all the redeclarations of the same decl. 00115 class redecl_iterator { 00116 /// Current - The current declaration. 00117 decl_type *Current; 00118 decl_type *Starter; 00119 bool PassedFirst; 00120 00121 public: 00122 typedef decl_type* value_type; 00123 typedef decl_type* reference; 00124 typedef decl_type* pointer; 00125 typedef std::forward_iterator_tag iterator_category; 00126 typedef std::ptrdiff_t difference_type; 00127 00128 redecl_iterator() : Current(0) { } 00129 explicit redecl_iterator(decl_type *C) 00130 : Current(C), Starter(C), PassedFirst(false) { } 00131 00132 reference operator*() const { return Current; } 00133 pointer operator->() const { return Current; } 00134 00135 redecl_iterator& operator++() { 00136 assert(Current && "Advancing while iterator has reached end"); 00137 // Sanity check to avoid infinite loop on invalid redecl chain. 00138 if (Current->isFirstDeclaration()) { 00139 if (PassedFirst) { 00140 assert(0 && "Passed first decl twice, invalid redecl chain!"); 00141 Current = 0; 00142 return *this; 00143 } 00144 PassedFirst = true; 00145 } 00146 00147 // Get either previous decl or latest decl. 00148 decl_type *Next = Current->RedeclLink.getNext(); 00149 Current = (Next != Starter ? Next : 0); 00150 return *this; 00151 } 00152 00153 redecl_iterator operator++(int) { 00154 redecl_iterator tmp(*this); 00155 ++(*this); 00156 return tmp; 00157 } 00158 00159 friend bool operator==(redecl_iterator x, redecl_iterator y) { 00160 return x.Current == y.Current; 00161 } 00162 friend bool operator!=(redecl_iterator x, redecl_iterator y) { 00163 return x.Current != y.Current; 00164 } 00165 }; 00166 00167 /// \brief Returns iterator for all the redeclarations of the same decl. 00168 /// It will iterate at least once (when this decl is the only one). 00169 redecl_iterator redecls_begin() const { 00170 return redecl_iterator(const_cast<decl_type*>( 00171 static_cast<const decl_type*>(this))); 00172 } 00173 redecl_iterator redecls_end() const { return redecl_iterator(); } 00174 00175 friend class ASTDeclReader; 00176 friend class ASTDeclWriter; 00177 }; 00178 00179 } 00180 00181 #endif