 |
|
 |
|
| 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 |
| |
 |
|
 |
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