clang API Documentation

Redeclarable.h
Go to the documentation of this file.
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