 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
77.4% |
48 / 62 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
96.8% |
60 / 62 |
| |
|
Line Coverage: |
94.0% |
94 / 100 |
| |
 |
|
 |
1 : //===- IdentifierResolver.cpp - 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 implements the IdentifierResolver class, which is used for lexical
11 : // scoped lookup, based on declaration names.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "IdentifierResolver.h"
16 : #include "clang/Basic/LangOptions.h"
17 : #include <list>
18 : #include <vector>
19 :
20 : using namespace clang;
21 :
22 : //===----------------------------------------------------------------------===//
23 : // IdDeclInfoMap class
24 : //===----------------------------------------------------------------------===//
25 :
26 : /// IdDeclInfoMap - Associates IdDeclInfos with declaration names.
27 : /// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
28 : /// individual IdDeclInfo to heap.
29 2236: class IdentifierResolver::IdDeclInfoMap {
30 : static const unsigned int VECTOR_SIZE = 512;
31 : // Holds vectors of IdDeclInfos that serve as 'pools'.
32 : // New vectors are added when the current one is full.
33 : std::list< std::vector<IdDeclInfo> > IDIVecs;
34 : unsigned int CurIndex;
35 :
36 : public:
37 2236: IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {}
38 :
39 : /// Returns the IdDeclInfo associated to the DeclarationName.
40 : /// It creates a new IdDeclInfo if one was not created before for this id.
41 : IdDeclInfo &operator[](DeclarationName Name);
42 : };
43 :
44 :
45 : //===----------------------------------------------------------------------===//
46 : // IdDeclInfo Implementation
47 : //===----------------------------------------------------------------------===//
48 :
49 : /// RemoveDecl - Remove the decl from the scope chain.
50 : /// The decl must already be part of the decl chain.
51 6600: void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
7283: branch 2 taken
0: branch 3 not taken
52 7283: for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
6600: branch 0 taken
683: branch 1 taken
53 7283: if (D == *(I-1)) {
54 6600: Decls.erase(I-1);
55 : return;
56 : }
57 : }
58 :
59 0: assert(0 && "Didn't find this decl on its identifier's chain!");
60 : }
61 :
62 : bool
63 3: IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
4: branch 2 taken
0: branch 3 not taken
64 4: for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
3: branch 0 taken
1: branch 1 taken
65 4: if (Old == *(I-1)) {
66 3: *(I - 1) = New;
67 3: return true;
68 : }
69 : }
70 :
71 0: return false;
72 : }
73 :
74 :
75 : //===----------------------------------------------------------------------===//
76 : // IdentifierResolver Implementation
77 : //===----------------------------------------------------------------------===//
78 :
79 2236: IdentifierResolver::IdentifierResolver(const LangOptions &langOpt)
80 2236: : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) {
81 2236: }
82 2236: IdentifierResolver::~IdentifierResolver() {
2236: branch 0 taken
0: branch 1 not taken
2236: branch 4 taken
2236: branch 5 taken
83 2236: delete IdDeclInfos;
84 2236: }
85 :
86 : /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
87 : /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
88 : /// true if 'D' belongs to the given declaration context.
89 : bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
90 3122: ASTContext &Context, Scope *S) const {
91 3122: Ctx = Ctx->getLookupContext();
92 :
229: branch 1 taken
2893: branch 2 taken
93 3122: if (Ctx->isFunctionOrMethod()) {
94 : // Ignore the scopes associated within transparent declaration contexts.
164: branch 1 taken
65: branch 2 taken
0: branch 5 not taken
164: branch 6 taken
0: branch 7 not taken
229: branch 8 taken
95 458: while (S->getEntity() &&
96 : ((DeclContext *)S->getEntity())->isTransparentContext())
97 0: S = S->getParent();
98 :
26: branch 2 taken
203: branch 3 taken
99 229: if (S->isDeclScope(Action::DeclPtrTy::make(D)))
100 26: return true;
87: branch 0 taken
116: branch 1 taken
101 203: if (LangOpt.CPlusPlus) {
102 : // C++ 3.3.2p3:
103 : // The name declared in a catch exception-declaration is local to the
104 : // handler and shall not be redeclared in the outermost block of the
105 : // handler.
106 : // C++ 3.3.2p4:
107 : // Names declared in the for-init-statement, and in the condition of if,
108 : // while, for, and switch statements are local to the if, while, for, or
109 : // switch statement (including the controlled statement), and shall not be
110 : // redeclared in a subsequent condition of that statement nor in the
111 : // outermost block (or, for the if statement, any of the outermost blocks)
112 : // of the controlled statement.
113 : //
87: branch 1 taken
0: branch 2 not taken
114 87: assert(S->getParent() && "No TUScope?");
11: branch 2 taken
76: branch 3 taken
115 87: if (S->getParent()->getFlags() & Scope::ControlScope)
116 11: return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D));
117 : }
118 192: return false;
119 : }
120 :
121 2893: return D->getDeclContext()->getLookupContext()->Equals(Ctx);
122 : }
123 :
124 : /// AddDecl - Link the decl to its shadowed decl chain.
125 73964: void IdentifierResolver::AddDecl(NamedDecl *D) {
126 73964: DeclarationName Name = D->getDeclName();
127 73964: void *Ptr = Name.getFETokenInfo<void>();
128 :
67373: branch 0 taken
6591: branch 1 taken
129 73964: if (!Ptr) {
130 67373: Name.setFETokenInfo(D);
131 67373: return;
132 : }
133 :
134 : IdDeclInfo *IDI;
135 :
4591: branch 1 taken
2000: branch 2 taken
136 6591: if (isDeclPtr(Ptr)) {
137 4591: Name.setFETokenInfo(NULL);
138 4591: IDI = &(*IdDeclInfos)[Name];
139 4591: NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
140 4591: IDI->AddDecl(PrevD);
141 : } else
142 2000: IDI = toIdDeclInfo(Ptr);
143 :
144 6591: IDI->AddDecl(D);
145 : }
146 :
147 : /// RemoveDecl - Unlink the decl from its shadowed decl chain.
148 : /// The decl must already be part of the decl chain.
149 42911: void IdentifierResolver::RemoveDecl(NamedDecl *D) {
0: branch 0 not taken
42911: branch 1 taken
150 42911: assert(D && "null param passed");
151 42911: DeclarationName Name = D->getDeclName();
152 42911: void *Ptr = Name.getFETokenInfo<void>();
153 :
0: branch 0 not taken
42911: branch 1 taken
154 42911: assert(Ptr && "Didn't find this decl on its identifier's chain!");
155 :
36311: branch 1 taken
6600: branch 2 taken
156 42911: if (isDeclPtr(Ptr)) {
0: branch 0 not taken
36311: branch 1 taken
157 36311: assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
158 36311: Name.setFETokenInfo(NULL);
159 36311: return;
160 : }
161 :
162 6600: return toIdDeclInfo(Ptr)->RemoveDecl(D);
163 : }
164 :
165 19: bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
166 : assert(Old->getDeclName() == New->getDeclName() &&
19: branch 3 taken
0: branch 4 not taken
167 19: "Cannot replace a decl with another decl of a different name");
168 :
169 19: DeclarationName Name = Old->getDeclName();
170 19: void *Ptr = Name.getFETokenInfo<void>();
171 :
0: branch 0 not taken
19: branch 1 taken
172 19: if (!Ptr)
173 0: return false;
174 :
16: branch 1 taken
3: branch 2 taken
175 19: if (isDeclPtr(Ptr)) {
16: branch 0 taken
0: branch 1 not taken
176 16: if (Ptr == Old) {
177 16: Name.setFETokenInfo(New);
178 16: return true;
179 : }
180 0: return false;
181 : }
182 :
183 3: return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New);
184 : }
185 :
186 : /// begin - Returns an iterator for decls with name 'Name'.
187 : IdentifierResolver::iterator
188 261295: IdentifierResolver::begin(DeclarationName Name) {
189 261295: void *Ptr = Name.getFETokenInfo<void>();
182500: branch 0 taken
78795: branch 1 taken
190 261295: if (!Ptr) return end();
191 :
64494: branch 1 taken
14301: branch 2 taken
192 78795: if (isDeclPtr(Ptr))
193 64494: return iterator(static_cast<NamedDecl*>(Ptr));
194 :
195 14301: IdDeclInfo *IDI = toIdDeclInfo(Ptr);
196 :
197 14301: IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
11398: branch 1 taken
2903: branch 2 taken
198 14301: if (I != IDI->decls_begin())
199 11398: return iterator(I-1);
200 : // No decls found.
201 2903: return end();
202 : }
203 :
204 : void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
205 168: NamedDecl *D) {
206 168: void *Ptr = II->getFETokenInfo<void>();
207 :
163: branch 0 taken
5: branch 1 taken
208 168: if (!Ptr) {
209 163: II->setFETokenInfo(D);
210 163: return;
211 : }
212 :
213 : IdDeclInfo *IDI;
214 :
5: branch 1 taken
0: branch 2 not taken
215 5: if (isDeclPtr(Ptr)) {
216 5: II->setFETokenInfo(NULL);
217 5: IDI = &(*IdDeclInfos)[II];
218 5: NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
219 5: IDI->AddDecl(PrevD);
220 : } else
221 0: IDI = toIdDeclInfo(Ptr);
222 :
223 5: IDI->AddDecl(D);
224 : }
225 :
226 : //===----------------------------------------------------------------------===//
227 : // IdDeclInfoMap Implementation
228 : //===----------------------------------------------------------------------===//
229 :
230 : /// Returns the IdDeclInfo associated to the DeclarationName.
231 : /// It creates a new IdDeclInfo if one was not created before for this id.
232 : IdentifierResolver::IdDeclInfo &
233 4596: IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
234 4596: void *Ptr = Name.getFETokenInfo<void>();
235 :
0: branch 0 not taken
4596: branch 1 taken
236 4596: if (Ptr) return *toIdDeclInfo(Ptr);
237 :
1269: branch 0 taken
3327: branch 1 taken
238 4596: if (CurIndex == VECTOR_SIZE) {
239 : // Add a IdDeclInfo vector 'pool'
240 1269: IDIVecs.push_back(std::vector<IdDeclInfo>());
241 : // Fill the vector
242 1269: IDIVecs.back().resize(VECTOR_SIZE);
243 1269: CurIndex = 0;
244 : }
245 4596: IdDeclInfo *IDI = &IDIVecs.back()[CurIndex];
246 : Name.setFETokenInfo(reinterpret_cast<void*>(
247 : reinterpret_cast<uintptr_t>(IDI) | 0x1)
248 4596: );
249 4596: ++CurIndex;
250 4596: return *IDI;
251 : }
Generated: 2010-02-10 01:31 by zcov