zcov: / include/clang/AST/Redeclarable.h


Files: 1 Branches Taken: 75.0% 18 / 24
Generated: 2010-02-10 01:31 Branches Executed: 83.3% 20 / 24
Line Coverage: 100.0% 48 / 48


Programs: 28 Runs 45028


       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           115884:     DeclLink(decl_type *D, bool isLatest)
      32           115884:       : llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { }
      33                 : 
      34                 :     typedef llvm::PointerIntPair<decl_type *, 1, bool> base_type;
      35                 : 
      36           202207:     bool NextIsPrevious() const { return base_type::getInt() == false; }
      37             5932:     bool NextIsLatest() const { return base_type::getInt() == true; }
      38            47633:     decl_type *getNext() const { return base_type::getPointer(); }
      39                 :   };
      40                 : 
      41                 :   struct PreviousDeclLink : public DeclLink {
      42             5932:     PreviousDeclLink(decl_type *D) : DeclLink(D, false) { }
      43                 :   };
      44                 : 
      45                 :   struct LatestDeclLink : public DeclLink {
      46           109952:     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            95536:   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           202207:   decl_type *getPreviousDeclaration() {
                     2029: branch 1 taken
                    59293: branch 2 taken
                     6967: branch 4 taken
                   128996: branch 5 taken
                       52: branch 7 taken
                     4870: branch 8 taken
                        0: branch 11 not taken
      68           202207:     if (RedeclLink.NextIsPrevious())
      69             9048:       return RedeclLink.getNext();
      70           193159:     return 0;
      71                 :   }
      72            42885:   const decl_type *getPreviousDeclaration() const {
      73                 :     return const_cast<decl_type *>(
      74            42885:                  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           147288:   decl_type *getFirstDeclaration() {
      80           147288:     decl_type *D = static_cast<decl_type*>(this);
                      964: branch 1 taken
                    54311: branch 2 taken
                    84612: branch 5 taken
                     9339: branch 7 taken
                        0: branch 8 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
      81           297579:     while (D->getPreviousDeclaration())
      82             3003:       D = D->getPreviousDeclaration();
      83           147288:     return D;
      84                 :   }
      85                 : 
      86                 :   /// \brief Return the first declaration of this declaration or itself if this
      87                 :   /// is the only declaration.
      88            13570:   const decl_type *getFirstDeclaration() const {
      89            13570:     const decl_type *D = static_cast<const decl_type*>(this);
                      608: branch 1 taken
                    13570: branch 2 taken
      90            27748:     while (D->getPreviousDeclaration())
      91              608:       D = D->getPreviousDeclaration();
      92            13570:     return D;
      93                 :   }
      94                 : 
      95                 :   /// \brief Returns the most recent (re)declaration of this declaration.
      96             5932:   decl_type *getMostRecentDeclaration() {
      97             5932:     return getFirstDeclaration()->RedeclLink.getNext();
      98                 :   }
      99                 : 
     100                 :   /// \brief Returns the most recent (re)declaration of this declaration.
     101                 :   const decl_type *getMostRecentDeclaration() const {
     102                 :     return getFirstDeclaration()->RedeclLink.getNext();
     103                 :   }
     104                 :   
     105                 :   /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
     106                 :   /// first and only declaration.
     107            14416:   void setPreviousDeclaration(decl_type *PrevDecl) {
     108                 :     decl_type *First;
     109                 : 
                      198: branch 3 taken
                     4884: branch 2 taken
                     8286: branch 3 taken
     110            14416:     if (PrevDecl) {
     111                 :       // Point to previous. Make sure that this is actually the most recent
     112                 :       // redeclaration, or we can build invalid chains. If the most recent
     113                 :       // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
     114             5932:       RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
     115                 :                                       PrevDecl->getMostRecentDeclaration()));
     116             5932:       First = PrevDecl->getFirstDeclaration();
                      244: branch 1 taken
                        0: branch 2 not taken
                     4884: branch 6 taken
                        0: branch 6 not taken
     117             5932:       assert(First->RedeclLink.NextIsLatest() && "Expected first");
     118                 :     } else {
     119                 :       // Make this first.
     120             8484:       First = static_cast<decl_type*>(this);
     121                 :     }
     122                 : 
     123                 :     // First one will point to this one as latest.
     124            14416:     First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
     125            14416:   }
     126                 : 
     127                 :   /// \brief Iterates through all the redeclarations of the same decl.
     128                 :   class redecl_iterator {
     129                 :     /// Current - The current declaration.
     130                 :     decl_type *Current;
     131                 :     decl_type *Starter;
     132                 : 
     133                 :   public:
     134                 :     typedef decl_type*                value_type;
     135                 :     typedef decl_type*                reference;
     136                 :     typedef decl_type*                pointer;
     137                 :     typedef std::forward_iterator_tag iterator_category;
     138                 :     typedef std::ptrdiff_t            difference_type;
     139                 : 
     140            52540:     redecl_iterator() : Current(0) { }
     141            52540:     explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) { }
     142                 : 
     143            32330:     reference operator*() const { return Current; }
     144            66286:     pointer operator->() const { return Current; }
     145                 : 
     146            32653:     redecl_iterator& operator++() {
                    28638: branch 1 taken
     147            32653:       assert(Current && "Advancing while iterator has reached end");
     148                 :       // Get either previous decl or latest decl.
     149            32653:       decl_type *Next = Current->RedeclLink.getNext();
     150            32653:       Current = (Next != Starter ? Next : 0);
     151            32653:       return *this;
     152                 :     }
     153                 : 
     154                 :     redecl_iterator operator++(int) {
     155                 :       redecl_iterator tmp(*this);
     156                 :       ++(*this);
     157                 :       return tmp;
     158                 :     }
     159                 : 
     160                 :     friend bool operator==(redecl_iterator x, redecl_iterator y) {
     161                 :       return x.Current == y.Current;
     162                 :     }
     163            87600:     friend bool operator!=(redecl_iterator x, redecl_iterator y) {
     164            87600:       return x.Current != y.Current;
     165                 :     }
     166                 :   };
     167                 : 
     168                 :   /// \brief Returns iterator for all the redeclarations of the same decl.
     169                 :   /// It will iterate at least once (when this decl is the only one).
     170            52540:   redecl_iterator redecls_begin() const {
     171                 :     return redecl_iterator(const_cast<decl_type*>(
     172            52540:                                           static_cast<const decl_type*>(this)));
     173                 :   }
     174            52540:   redecl_iterator redecls_end() const { return redecl_iterator(); }
     175                 : };
     176                 : 
     177                 : }
     178                 : 
     179                 : #endif

Generated: 2010-02-10 01:31 by zcov