 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
71.4% |
10 / 14 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
14 / 14 |
| |
|
Line Coverage: |
100.0% |
41 / 41 |
| |
 |
|
 |
1 : //===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 IdentifierResolver class, which is used for lexical
11 : // scoped lookup, based on declaration names.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
16 : #define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
17 :
18 : #include "clang/Basic/IdentifierTable.h"
19 : #include "clang/Parse/Scope.h"
20 : #include "clang/AST/Decl.h"
21 : #include "clang/AST/DeclarationName.h"
22 : #include "clang/AST/DeclCXX.h"
23 :
24 : namespace clang {
25 :
26 : /// IdentifierResolver - Keeps track of shadowed decls on enclosing
27 : /// scopes. It manages the shadowing chains of declaration names and
28 : /// implements efficent decl lookup based on a declaration name.
29 : class IdentifierResolver {
30 :
31 : /// IdDeclInfo - Keeps track of information about decls associated
32 : /// to a particular declaration name. IdDeclInfos are lazily
33 : /// constructed and assigned to a declaration name the first time a
34 : /// decl with that declaration name is shadowed in some scope.
35 1301994: class IdDeclInfo {
36 : public:
37 : typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy;
38 :
39 27172: inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
40 14301: inline DeclsTy::iterator decls_end() { return Decls.end(); }
41 :
42 11192: void AddDecl(NamedDecl *D) { Decls.push_back(D); }
43 :
44 : /// RemoveDecl - Remove the decl from the scope chain.
45 : /// The decl must already be part of the decl chain.
46 : void RemoveDecl(NamedDecl *D);
47 :
48 : /// Replaces the Old declaration with the New declaration. If the
49 : /// replacement is successful, returns true. If the old
50 : /// declaration was not found, returns false.
51 : bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
52 :
53 : private:
54 : DeclsTy Decls;
55 : };
56 :
57 : public:
58 :
59 : /// iterator - Iterate over the decls of a specified declaration name.
60 : /// It will walk or not the parent declaration contexts depending on how
61 : /// it was instantiated.
62 : class iterator {
63 : public:
64 : typedef NamedDecl * value_type;
65 : typedef NamedDecl * reference;
66 : typedef NamedDecl * pointer;
67 : typedef std::input_iterator_tag iterator_category;
68 : typedef std::ptrdiff_t difference_type;
69 :
70 : /// Ptr - There are 3 forms that 'Ptr' represents:
71 : /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
72 : /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
73 : /// same declaration context. (Ptr & 0x3 == 0x1)
74 : /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
75 : /// declaration contexts too. (Ptr & 0x3 == 0x3)
76 : uintptr_t Ptr;
77 : typedef IdDeclInfo::DeclsTy::iterator BaseIter;
78 :
79 : /// A single NamedDecl. (Ptr & 0x1 == 0)
80 64494: iterator(NamedDecl *D) {
81 64494: Ptr = reinterpret_cast<uintptr_t>(D);
0: branch 0 not taken
64494: branch 1 taken
82 64494: assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
83 64494: }
84 : /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
85 : /// contexts depending on 'LookInParentCtx'.
86 17130: iterator(BaseIter I) {
87 17130: Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
88 17130: }
89 :
90 363731: bool isIterator() const { return (Ptr & 0x1); }
91 :
92 72531: BaseIter getIterator() const {
72531: branch 1 taken
0: branch 2 not taken
93 72531: assert(isIterator() && "Ptr not an iterator!");
94 72531: return reinterpret_cast<BaseIter>(Ptr & ~0x3);
95 : }
96 :
97 : friend class IdentifierResolver;
98 : public:
99 453837: iterator() : Ptr(0) {}
100 :
101 255703: NamedDecl *operator*() const {
59660: branch 1 taken
196043: branch 2 taken
102 255703: if (isIterator())
103 59660: return *getIterator();
104 : else
105 196043: return reinterpret_cast<NamedDecl*>(Ptr);
106 : }
107 :
108 : bool operator==(const iterator &RHS) const {
109 : return Ptr == RHS.Ptr;
110 : }
111 371175: bool operator!=(const iterator &RHS) const {
112 371175: return Ptr != RHS.Ptr;
113 : }
114 :
115 : // Preincrement.
116 35497: iterator& operator++() {
22626: branch 1 taken
12871: branch 2 taken
117 35497: if (!isIterator()) // common case.
118 22626: Ptr = 0;
119 : else {
120 12871: NamedDecl *D = **this;
121 12871: void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
12871: branch 1 taken
0: branch 2 not taken
122 12871: assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
123 12871: IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
124 :
125 12871: BaseIter I = getIterator();
5732: branch 1 taken
7139: branch 2 taken
126 12871: if (I != Info->decls_begin())
127 5732: *this = iterator(I-1);
128 : else // No more decls.
129 7139: *this = iterator();
130 : }
131 35497: return *this;
132 : }
133 :
134 : uintptr_t getAsOpaqueValue() const { return Ptr; }
135 :
136 : static iterator getFromOpaqueValue(uintptr_t P) {
137 : iterator Result;
138 : Result.Ptr = P;
139 : return Result;
140 : }
141 : };
142 :
143 : /// begin - Returns an iterator for decls with the name 'Name'.
144 : static iterator begin(DeclarationName Name);
145 :
146 : /// end - Returns an iterator that has 'finished'.
147 446698: static iterator end() {
148 446698: return iterator();
149 : }
150 :
151 : /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
152 : /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
153 : /// true if 'D' belongs to the given declaration context.
154 : bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
155 : Scope *S = 0) const;
156 :
157 : /// AddDecl - Link the decl to its shadowed decl chain.
158 : void AddDecl(NamedDecl *D);
159 :
160 : /// RemoveDecl - Unlink the decl from its shadowed decl chain.
161 : /// The decl must already be part of the decl chain.
162 : void RemoveDecl(NamedDecl *D);
163 :
164 : /// Replace the decl Old with the new declaration New on its
165 : /// identifier chain. Returns true if the old declaration was found
166 : /// (and, therefore, replaced).
167 : bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
168 :
169 : /// \brief Link the declaration into the chain of declarations for
170 : /// the given identifier.
171 : ///
172 : /// This is a lower-level routine used by the PCH reader to link a
173 : /// declaration into a specific IdentifierInfo before the
174 : /// declaration actually has a name.
175 : void AddDeclToIdentifierChain(IdentifierInfo *II, NamedDecl *D);
176 :
177 : explicit IdentifierResolver(const LangOptions &LangOpt);
178 : ~IdentifierResolver();
179 :
180 : private:
181 : const LangOptions &LangOpt;
182 :
183 : class IdDeclInfoMap;
184 : IdDeclInfoMap *IdDeclInfos;
185 :
186 : /// FETokenInfo contains a Decl pointer if lower bit == 0.
187 141192: static inline bool isDeclPtr(void *Ptr) {
188 141192: return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
189 : }
190 :
191 : /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
192 35775: static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
193 : assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
0: branch 0 not taken
35775: branch 1 taken
194 35775: && "Ptr not a IdDeclInfo* !");
195 : return reinterpret_cast<IdDeclInfo*>(
196 : reinterpret_cast<uintptr_t>(Ptr) & ~0x1
197 35775: );
198 : }
199 : };
200 :
201 : } // end namespace clang
202 :
203 : #endif
Generated: 2010-02-10 01:31 by zcov