 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
51.6% |
249 / 483 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
80.3% |
388 / 483 |
| |
|
Line Coverage: |
82.2% |
314 / 382 |
| |
 |
|
 |
1 : //===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
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 Decl and DeclContext classes.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/AST/DeclBase.h"
15 : #include "clang/AST/Decl.h"
16 : #include "clang/AST/DeclContextInternals.h"
17 : #include "clang/AST/DeclCXX.h"
18 : #include "clang/AST/DeclObjC.h"
19 : #include "clang/AST/DeclTemplate.h"
20 : #include "clang/AST/ExternalASTSource.h"
21 : #include "clang/AST/ASTContext.h"
22 : #include "clang/AST/Type.h"
23 : #include "clang/AST/Stmt.h"
24 : #include "clang/AST/StmtCXX.h"
25 : #include "llvm/ADT/DenseMap.h"
26 : #include "llvm/Support/raw_ostream.h"
27 : #include <algorithm>
28 : #include <cstdio>
29 : #include <vector>
30 : using namespace clang;
31 :
32 : //===----------------------------------------------------------------------===//
33 : // Statistics
34 : //===----------------------------------------------------------------------===//
35 :
36 : #define DECL(Derived, Base) static int n##Derived##s = 0;
37 : #include "clang/AST/DeclNodes.def"
38 :
39 : static bool StatSwitch = false;
40 :
41 0: const char *Decl::getDeclKindName() const {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
0: branch 15 not taken
0: branch 16 not taken
0: branch 17 not taken
0: branch 18 not taken
0: branch 19 not taken
0: branch 20 not taken
0: branch 21 not taken
0: branch 22 not taken
0: branch 23 not taken
0: branch 24 not taken
0: branch 25 not taken
0: branch 26 not taken
0: branch 27 not taken
0: branch 28 not taken
0: branch 29 not taken
0: branch 30 not taken
0: branch 31 not taken
0: branch 32 not taken
0: branch 33 not taken
0: branch 34 not taken
0: branch 35 not taken
0: branch 36 not taken
0: branch 37 not taken
0: branch 38 not taken
0: branch 39 not taken
0: branch 40 not taken
0: branch 41 not taken
0: branch 42 not taken
0: branch 43 not taken
0: branch 44 not taken
0: branch 45 not taken
0: branch 46 not taken
0: branch 47 not taken
0: branch 48 not taken
0: branch 49 not taken
0: branch 50 not taken
42 0: switch (DeclKind) {
43 0: default: assert(0 && "Declaration not in DeclNodes.def!");
44 : #define DECL(Derived, Base) case Derived: return #Derived;
45 : #include "clang/AST/DeclNodes.def"
46 : }
47 : }
48 :
49 26: const char *DeclContext::getDeclKindName() const {
0: branch 0 not taken
1: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
1: branch 7 taken
7: branch 8 taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
17: branch 15 taken
0: branch 16 not taken
0: branch 17 not taken
0: branch 18 not taken
0: branch 19 not taken
0: branch 20 not taken
0: branch 21 not taken
0: branch 22 not taken
0: branch 23 not taken
0: branch 24 not taken
0: branch 25 not taken
0: branch 26 not taken
0: branch 27 not taken
0: branch 28 not taken
0: branch 29 not taken
0: branch 30 not taken
0: branch 31 not taken
0: branch 32 not taken
0: branch 33 not taken
0: branch 34 not taken
0: branch 35 not taken
0: branch 36 not taken
0: branch 37 not taken
0: branch 38 not taken
0: branch 39 not taken
0: branch 40 not taken
0: branch 41 not taken
0: branch 42 not taken
0: branch 43 not taken
0: branch 44 not taken
0: branch 45 not taken
0: branch 46 not taken
0: branch 47 not taken
0: branch 48 not taken
0: branch 49 not taken
0: branch 50 not taken
50 26: switch (DeclKind) {
51 0: default: assert(0 && "Declaration context not in DeclNodes.def!");
52 : #define DECL(Derived, Base) case Decl::Derived: return #Derived;
53 : #include "clang/AST/DeclNodes.def"
54 : }
55 : }
56 :
57 120410: bool Decl::CollectingStats(bool Enable) {
2: branch 0 taken
120408: branch 1 taken
58 120410: if (Enable) StatSwitch = true;
59 120410: return StatSwitch;
60 : }
61 :
62 2: void Decl::PrintStats() {
63 2: fprintf(stderr, "*** Decl Stats:\n");
64 :
65 2: int totalDecls = 0;
66 : #define DECL(Derived, Base) totalDecls += n##Derived##s;
67 : #include "clang/AST/DeclNodes.def"
68 2: fprintf(stderr, " %d decls total.\n", totalDecls);
69 :
70 2: int totalBytes = 0;
71 : #define DECL(Derived, Base) \
72 : if (n##Derived##s > 0) { \
73 : totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl)); \
74 : fprintf(stderr, " %d " #Derived " decls, %d each (%d bytes)\n", \
75 : n##Derived##s, (int)sizeof(Derived##Decl), \
76 : (int)(n##Derived##s * sizeof(Derived##Decl))); \
77 : }
78 : #include "clang/AST/DeclNodes.def"
79 :
80 2: fprintf(stderr, "Total bytes = %d\n", totalBytes);
81 2: }
82 :
83 6: void Decl::addDeclKind(Kind k) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
5: branch 5 taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
0: branch 15 not taken
0: branch 16 not taken
0: branch 17 not taken
0: branch 18 not taken
0: branch 19 not taken
0: branch 20 not taken
0: branch 21 not taken
0: branch 22 not taken
0: branch 23 not taken
0: branch 24 not taken
0: branch 25 not taken
0: branch 26 not taken
0: branch 27 not taken
0: branch 28 not taken
0: branch 29 not taken
0: branch 30 not taken
0: branch 31 not taken
0: branch 32 not taken
0: branch 33 not taken
0: branch 34 not taken
0: branch 35 not taken
0: branch 36 not taken
1: branch 37 taken
0: branch 38 not taken
0: branch 39 not taken
0: branch 40 not taken
0: branch 41 not taken
0: branch 42 not taken
0: branch 43 not taken
0: branch 44 not taken
0: branch 45 not taken
0: branch 46 not taken
0: branch 47 not taken
0: branch 48 not taken
0: branch 49 not taken
0: branch 50 not taken
84 6: switch (k) {
85 0: default: assert(0 && "Declaration not in DeclNodes.def!");
86 : #define DECL(Derived, Base) case Derived: ++n##Derived##s; break;
87 : #include "clang/AST/DeclNodes.def"
88 : }
89 6: }
90 :
91 14025: bool Decl::isTemplateParameterPack() const {
9967: branch 1 taken
4058: branch 2 taken
92 14025: if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
93 9967: return TTP->isParameterPack();
94 :
95 4058: return false;
96 : }
97 :
98 3082: bool Decl::isFunctionOrFunctionTemplate() const {
1: branch 1 taken
3081: branch 2 taken
99 3082: if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
100 1: return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
101 :
1099: branch 1 taken
1982: branch 2 taken
331: branch 4 taken
768: branch 5 taken
102 3081: return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
103 : }
104 :
105 2621: bool Decl::isDefinedOutsideFunctionOrMethod() const {
2588: branch 2 taken
264: branch 3 taken
1554: branch 5 taken
1034: branch 6 taken
1554: branch 7 taken
1298: branch 8 taken
106 2852: for (const DeclContext *DC = getDeclContext();
107 : DC && !DC->isTranslationUnit();
108 : DC = DC->getParent())
1323: branch 1 taken
231: branch 2 taken
109 1554: if (DC->isFunctionOrMethod())
110 1323: return false;
111 :
112 1298: return true;
113 : }
114 :
115 :
116 : //===----------------------------------------------------------------------===//
117 : // PrettyStackTraceDecl Implementation
118 : //===----------------------------------------------------------------------===//
119 :
120 0: void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
121 0: SourceLocation TheLoc = Loc;
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
122 0: if (TheLoc.isInvalid() && TheDecl)
123 0: TheLoc = TheDecl->getLocation();
124 :
0: branch 1 not taken
0: branch 2 not taken
125 0: if (TheLoc.isValid()) {
126 0: TheLoc.print(OS, SM);
127 0: OS << ": ";
128 : }
129 :
130 0: OS << Message;
131 :
0: branch 1 not taken
0: branch 2 not taken
132 0: if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
133 0: OS << " '" << DN->getQualifiedNameAsString() << '\'';
134 0: OS << '\n';
135 0: }
136 :
137 : //===----------------------------------------------------------------------===//
138 : // Decl Implementation
139 : //===----------------------------------------------------------------------===//
140 :
141 : // Out-of-line virtual method providing a home for Decl.
142 1070: Decl::~Decl() {
1070: branch 0 taken
1070: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
1070: branch 7 taken
143 1070: assert(!HasAttrs && "attributes should have been freed by Destroy");
1070: branch 0 taken
1070: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
1070: branch 7 taken
144 1070: }
145 :
146 20922: void Decl::setDeclContext(DeclContext *DC) {
0: branch 1 not taken
20922: branch 2 taken
147 20922: if (isOutOfSemaDC())
148 0: delete getMultipleDC();
149 :
150 20922: DeclCtx = DC;
151 20922: }
152 :
153 35435: void Decl::setLexicalDeclContext(DeclContext *DC) {
33679: branch 1 taken
1756: branch 2 taken
154 35435: if (DC == getLexicalDeclContext())
155 33679: return;
156 :
1755: branch 1 taken
1: branch 2 taken
157 1756: if (isInSemaDC()) {
1755: branch 2 taken
0: branch 3 not taken
158 1755: MultipleDC *MDC = new (getASTContext()) MultipleDC();
159 1755: MDC->SemanticDC = getDeclContext();
160 1755: MDC->LexicalDC = DC;
161 1755: DeclCtx = MDC;
162 : } else {
163 1: getMultipleDC()->LexicalDC = DC;
164 : }
165 : }
166 :
167 59131: bool Decl::isInAnonymousNamespace() const {
168 59131: const DeclContext *DC = getDeclContext();
5337: branch 1 taken
58992: branch 2 taken
169 64329: do {
4066: branch 1 taken
60402: branch 2 taken
170 64468: if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
139: branch 1 taken
3927: branch 2 taken
171 4066: if (ND->isAnonymousNamespace())
172 139: return true;
173 : } while ((DC = DC->getParent()));
174 :
175 58992: return false;
176 : }
177 :
178 319650: TranslationUnitDecl *Decl::getTranslationUnitDecl() {
15248: branch 1 taken
304402: branch 2 taken
179 319650: if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
180 15248: return TUD;
181 :
182 304402: DeclContext *DC = getDeclContext();
0: branch 0 not taken
304402: branch 1 taken
183 304402: assert(DC && "This decl is not contained in a translation unit!");
184 :
90285: branch 1 taken
304402: branch 2 taken
185 699089: while (!DC->isTranslationUnit()) {
186 90285: DC = DC->getParent();
0: branch 0 not taken
90285: branch 1 taken
187 90285: assert(DC && "This decl is not contained in a translation unit!");
188 : }
189 :
190 304402: return cast<TranslationUnitDecl>(DC);
191 : }
192 :
193 319650: ASTContext &Decl::getASTContext() const {
194 319650: return getTranslationUnitDecl()->getASTContext();
195 : }
196 :
197 120408: unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
91582: branch 0 taken
117: branch 1 taken
20: branch 2 taken
114: branch 3 taken
727: branch 4 taken
575: branch 5 taken
279: branch 6 taken
5959: branch 7 taken
13315: branch 8 taken
2371: branch 9 taken
5349: branch 10 taken
0: branch 11 not taken
198 120408: switch (DeclKind) {
199 : case Function:
200 : case CXXMethod:
201 : case CXXConstructor:
202 : case CXXDestructor:
203 : case CXXConversion:
204 : case Typedef:
205 : case EnumConstant:
206 : case Var:
207 : case ImplicitParam:
208 : case ParmVar:
209 : case NonTypeTemplateParm:
210 : case ObjCMethod:
211 : case ObjCContainer:
212 : case ObjCInterface:
213 : case ObjCProperty:
214 : case ObjCCompatibleAlias:
215 91582: return IDNS_Ordinary;
216 :
217 : case UsingShadow:
218 117: return 0; // we'll actually overwrite this later
219 :
220 : case UnresolvedUsingValue:
221 : case UnresolvedUsingTypename:
222 20: return IDNS_Ordinary | IDNS_Using;
223 :
224 : case Using:
225 114: return IDNS_Using;
226 :
227 : case ObjCProtocol:
228 727: return IDNS_ObjCProtocol;
229 :
230 : case ObjCImplementation:
231 575: return IDNS_ObjCImplementation;
232 :
233 : case ObjCCategory:
234 : case ObjCCategoryImpl:
235 279: return IDNS_ObjCCategoryName;
236 :
237 : case Field:
238 : case ObjCAtDefsField:
239 : case ObjCIvar:
240 5959: return IDNS_Member;
241 :
242 : case Record:
243 : case CXXRecord:
244 : case Enum:
245 : case TemplateTypeParm:
246 13315: return IDNS_Tag;
247 :
248 : case Namespace:
249 : case Template:
250 : case FunctionTemplate:
251 : case ClassTemplate:
252 : case TemplateTemplateParm:
253 : case NamespaceAlias:
254 2371: return IDNS_Tag | IDNS_Ordinary;
255 :
256 : // Never have names.
257 : case Friend:
258 : case FriendTemplate:
259 : case LinkageSpec:
260 : case FileScopeAsm:
261 : case StaticAssert:
262 : case ObjCClass:
263 : case ObjCPropertyImpl:
264 : case ObjCForwardProtocol:
265 : case Block:
266 : case TranslationUnit:
267 :
268 : // Aren't looked up?
269 : case UsingDirective:
270 : case ClassTemplateSpecialization:
271 : case ClassTemplatePartialSpecialization:
272 5349: return 0;
273 : }
274 :
275 0: return 0;
276 : }
277 :
278 4981: void Decl::addAttr(Attr *NewAttr) {
279 4981: Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
280 :
281 4981: NewAttr->setNext(ExistingAttr);
282 4981: ExistingAttr = NewAttr;
283 :
284 4981: HasAttrs = true;
285 4981: }
286 :
287 0: void Decl::invalidateAttrs() {
0: branch 0 not taken
0: branch 1 not taken
288 0: if (!HasAttrs) return;
289 :
290 0: HasAttrs = false;
291 0: getASTContext().eraseDeclAttrs(this);
292 : }
293 :
294 25273: const Attr *Decl::getAttrsImpl() const {
0: branch 0 not taken
25273: branch 1 taken
295 25273: assert(HasAttrs && "getAttrs() should verify this!");
296 25273: return getASTContext().getDeclAttrs(this);
297 : }
298 :
299 0: void Decl::swapAttrs(Decl *RHS) {
300 0: bool HasLHSAttr = this->HasAttrs;
301 0: bool HasRHSAttr = RHS->HasAttrs;
302 :
303 : // Usually, neither decl has attrs, nothing to do.
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
304 0: if (!HasLHSAttr && !HasRHSAttr) return;
305 :
306 : // If 'this' has no attrs, swap the other way.
0: branch 0 not taken
0: branch 1 not taken
307 0: if (!HasLHSAttr)
308 0: return RHS->swapAttrs(this);
309 :
310 0: ASTContext &Context = getASTContext();
311 :
312 : // Handle the case when both decls have attrs.
0: branch 0 not taken
0: branch 1 not taken
313 0: if (HasRHSAttr) {
314 0: std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS));
315 0: return;
316 : }
317 :
318 : // Otherwise, LHS has an attr and RHS doesn't.
319 0: Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this);
320 0: Context.eraseDeclAttrs(this);
321 0: this->HasAttrs = false;
322 0: RHS->HasAttrs = true;
323 : }
324 :
325 :
326 2147: void Decl::Destroy(ASTContext &C) {
327 : // Free attributes for this decl.
0: branch 0 not taken
2147: branch 1 taken
328 2147: if (HasAttrs) {
329 0: C.getDeclAttrs(this)->Destroy(C);
330 0: invalidateAttrs();
331 0: HasAttrs = false;
332 : }
333 :
334 : #if 0
335 : // FIXME: Once ownership is fully understood, we can enable this code
336 : if (DeclContext *DC = dyn_cast<DeclContext>(this))
337 : DC->decls_begin()->Destroy(C);
338 :
339 : // Observe the unrolled recursion. By setting N->NextDeclInContext = 0x0
340 : // within the loop, only the Destroy method for the first Decl
341 : // will deallocate all of the Decls in a chain.
342 :
343 : Decl* N = getNextDeclInContext();
344 :
345 : while (N) {
346 : Decl* Tmp = N->getNextDeclInContext();
347 : N->NextDeclInContext = 0;
348 : N->Destroy(C);
349 : N = Tmp;
350 : }
351 :
352 : if (isOutOfSemaDC())
353 : delete (C) getMultipleDC();
354 :
355 : this->~Decl();
356 : C.Deallocate((void *)this);
357 : #endif
358 2147: }
359 :
360 555243: Decl *Decl::castFromDeclContext (const DeclContext *D) {
361 555243: Decl::Kind DK = D->getDeclKind();
82962: branch 0 taken
38934: branch 1 taken
18381: branch 2 taken
4057: branch 3 taken
1605: branch 4 taken
409304: branch 5 taken
362 555243: switch(DK) {
363 : #define DECL_CONTEXT(Name) \
364 : case Decl::Name: \
365 : return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
366 : #define DECL_CONTEXT_BASE(Name)
367 : #include "clang/AST/DeclNodes.def"
368 : default:
369 : #define DECL_CONTEXT_BASE(Name) \
370 : if (DK >= Decl::Name##First && DK <= Decl::Name##Last) \
371 : return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
372 : #include "clang/AST/DeclNodes.def"
373 0: assert(false && "a decl that inherits DeclContext isn't handled");
374 : return 0;
375 : }
376 : }
377 :
378 38716: DeclContext *Decl::castToDeclContext(const Decl *D) {
379 38716: Decl::Kind DK = D->getKind();
763: branch 0 taken
286: branch 1 taken
49: branch 2 taken
3649: branch 3 taken
83: branch 4 taken
33886: branch 5 taken
380 38716: switch(DK) {
381 : #define DECL_CONTEXT(Name) \
382 : case Decl::Name: \
383 : return static_cast<Name##Decl*>(const_cast<Decl*>(D));
384 : #define DECL_CONTEXT_BASE(Name)
385 : #include "clang/AST/DeclNodes.def"
386 : default:
387 : #define DECL_CONTEXT_BASE(Name) \
388 : if (DK >= Decl::Name##First && DK <= Decl::Name##Last) \
389 : return static_cast<Name##Decl*>(const_cast<Decl*>(D));
390 : #include "clang/AST/DeclNodes.def"
391 0: assert(false && "a decl that inherits DeclContext isn't handled");
392 : return 0;
393 : }
394 : }
395 :
396 3091: CompoundStmt* Decl::getCompoundBody() const {
397 3091: return dyn_cast_or_null<CompoundStmt>(getBody());
398 : }
399 :
400 298: SourceLocation Decl::getBodyRBrace() const {
401 298: Stmt *Body = getBody();
0: branch 0 not taken
298: branch 1 taken
402 298: if (!Body)
403 0: return SourceLocation();
298: branch 1 taken
0: branch 2 not taken
404 298: if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
405 298: return CS->getRBracLoc();
406 : assert(isa<CXXTryStmt>(Body) &&
0: branch 1 not taken
0: branch 2 not taken
407 0: "Body can only be CompoundStmt or CXXTryStmt");
408 0: return cast<CXXTryStmt>(Body)->getSourceRange().getEnd();
409 : }
410 :
411 : #ifndef NDEBUG
412 149286: void Decl::CheckAccessDeclContext() const {
413 : // Suppress this check if any of the following hold:
414 : // 1. this is the translation unit (and thus has no parent)
415 : // 2. this is a template parameter (and thus doesn't belong to its context)
416 : // 3. this is a ParmVarDecl (which can be in a record context during
417 : // the brief period between its creation and the creation of the
418 : // FunctionDecl)
419 : // 4. the context is not a record
149196: branch 1 taken
90: branch 2 taken
100172: branch 5 taken
49024: branch 6 taken
49024: branch 7 taken
100262: branch 8 taken
420 149286: if (isa<TranslationUnitDecl>(this) ||
421 : !isa<CXXRecordDecl>(getDeclContext()))
422 100262: return;
423 :
424 : assert(Access != AS_none &&
0: branch 0 not taken
49024: branch 1 taken
425 49024: "Access specifier is AS_none inside a record decl");
426 : }
427 :
428 : #endif
429 :
430 : //===----------------------------------------------------------------------===//
431 : // DeclContext Implementation
432 : //===----------------------------------------------------------------------===//
433 :
434 71559: bool DeclContext::classof(const Decl *D) {
8151: branch 1 taken
63408: branch 2 taken
435 71559: switch (D->getKind()) {
436 : #define DECL_CONTEXT(Name) case Decl::Name:
437 : #define DECL_CONTEXT_BASE(Name)
438 : #include "clang/AST/DeclNodes.def"
439 8151: return true;
440 : default:
441 : #define DECL_CONTEXT_BASE(Name) \
442 : if (D->getKind() >= Decl::Name##First && \
443 : D->getKind() <= Decl::Name##Last) \
444 : return true;
445 : #include "clang/AST/DeclNodes.def"
446 10498: return false;
447 : }
448 : }
449 :
450 0: DeclContext::~DeclContext() {
0: branch 0 not taken
0: branch 1 not taken
0: branch 4 not taken
0: branch 5 not taken
451 0: delete static_cast<StoredDeclsMap*>(LookupPtr);
452 0: }
453 :
454 0: void DeclContext::DestroyDecls(ASTContext &C) {
0: branch 3 not taken
0: branch 4 not taken
455 0: for (decl_iterator D = decls_begin(); D != decls_end(); )
456 0: (*D++)->Destroy(C);
457 0: }
458 :
459 : /// \brief Find the parent context of this context that will be
460 : /// used for unqualified name lookup.
461 : ///
462 : /// Generally, the parent lookup context is the semantic context. However, for
463 : /// a friend function the parent lookup context is the lexical context, which
464 : /// is the class in which the friend is declared.
465 24806: DeclContext *DeclContext::getLookupParent() {
466 : // FIXME: Find a better way to identify friends
11353: branch 1 taken
13453: branch 2 taken
467 24806: if (isa<FunctionDecl>(this))
8782: branch 3 taken
2571: branch 4 taken
7: branch 8 taken
8775: branch 9 taken
7: branch 10 taken
11346: branch 11 taken
468 11353: if (getParent()->getLookupContext()->isFileContext() &&
469 : getLexicalParent()->getLookupContext()->isRecord())
470 7: return getLexicalParent();
471 :
472 24799: return getParent();
473 : }
474 :
475 189918: bool DeclContext::isDependentContext() const {
90276: branch 1 taken
99642: branch 2 taken
476 189918: if (isFileContext())
477 90276: return false;
478 :
676: branch 1 taken
98966: branch 2 taken
479 99642: if (isa<ClassTemplatePartialSpecializationDecl>(this))
480 676: return true;
481 :
55285: branch 1 taken
43681: branch 2 taken
482 98966: if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
9218: branch 1 taken
46067: branch 2 taken
483 55285: if (Record->getDescribedClassTemplate())
484 9218: return true;
485 :
31159: branch 1 taken
58589: branch 2 taken
486 89748: if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this))
410: branch 1 taken
30749: branch 2 taken
487 31159: if (Function->getDescribedFunctionTemplate())
488 410: return true;
489 :
89160: branch 1 taken
178: branch 2 taken
2013: branch 5 taken
87147: branch 6 taken
490 89338: return getParent() && getParent()->isDependentContext();
491 : }
492 :
493 570604: bool DeclContext::isTransparentContext() const {
3313: branch 0 taken
567291: branch 1 taken
494 570604: if (DeclKind == Decl::Enum)
495 3313: return true; // FIXME: Check for C++0x scoped enums
7721: branch 0 taken
559570: branch 1 taken
496 567291: else if (DeclKind == Decl::LinkageSpec)
497 7721: return true;
203406: branch 0 taken
356164: branch 1 taken
82222: branch 2 taken
121184: branch 3 taken
498 559570: else if (DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast)
499 82222: return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
24155: branch 0 taken
453193: branch 1 taken
500 477348: else if (DeclKind == Decl::Namespace)
501 24155: return false; // FIXME: Check for C++0x inline namespaces
502 :
503 453193: return false;
504 : }
505 :
506 3147: bool DeclContext::Encloses(DeclContext *DC) {
22: branch 1 taken
3125: branch 2 taken
507 3147: if (getPrimaryContext() != this)
508 22: return getPrimaryContext()->Encloses(DC);
509 :
4022: branch 1 taken
1286: branch 2 taken
510 5308: for (; DC; DC = DC->getParent())
1839: branch 1 taken
2183: branch 2 taken
511 4022: if (DC->getPrimaryContext() == this)
512 1839: return true;
513 1286: return false;
514 : }
515 :
516 378390: DeclContext *DeclContext::getPrimaryContext() {
196916: branch 0 taken
31727: branch 1 taken
2768: branch 2 taken
17962: branch 3 taken
3758: branch 4 taken
125259: branch 5 taken
517 378390: switch (DeclKind) {
518 : case Decl::TranslationUnit:
519 : case Decl::LinkageSpec:
520 : case Decl::Block:
521 : // There is only one DeclContext for these entities.
522 196916: return this;
523 :
524 : case Decl::Namespace:
525 : // The original namespace is our primary context.
31727: branch 1 taken
0: branch 2 not taken
526 31727: return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
527 :
528 : case Decl::ObjCMethod:
529 2768: return this;
530 :
531 : case Decl::ObjCInterface:
532 : case Decl::ObjCProtocol:
533 : case Decl::ObjCCategory:
534 : // FIXME: Can Objective-C interfaces be forward-declared?
535 17962: return this;
536 :
537 : case Decl::ObjCImplementation:
538 : case Decl::ObjCCategoryImpl:
539 3758: return this;
540 :
541 : default:
125259: branch 0 taken
0: branch 1 not taken
89771: branch 2 taken
35488: branch 3 taken
542 125259: if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
543 : // If this is a tag type that has a definition or is currently
544 : // being defined, that definition is our primary context.
88884: branch 2 taken
887: branch 3 taken
545 89771: if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAs<TagType>())
44202: branch 1 taken
44682: branch 2 taken
44202: branch 4 taken
0: branch 5 not taken
43880: branch 8 taken
322: branch 9 taken
88562: branch 10 taken
322: branch 11 taken
546 88884: if (TagT->isBeingDefined() ||
547 : (TagT->getDecl() && TagT->getDecl()->isDefinition()))
88562: branch 1 taken
0: branch 2 not taken
548 88562: return TagT->getDecl();
549 1209: return this;
550 : }
551 :
552 : assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
35488: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
35488: branch 3 taken
553 35488: "Unknown DeclContext kind");
554 35488: return this;
555 : }
556 : }
557 :
558 21634: DeclContext *DeclContext::getNextContext() {
2558: branch 0 taken
19076: branch 1 taken
559 21634: switch (DeclKind) {
560 : case Decl::Namespace:
561 : // Return the next namespace
64: branch 1 taken
2494: branch 2 taken
562 2558: return static_cast<NamespaceDecl*>(this)->getNextNamespace();
563 :
564 : default:
565 19076: return 0;
566 : }
567 : }
568 :
569 : /// \brief Load the declarations within this lexical storage from an
570 : /// external source.
571 : void
572 36: DeclContext::LoadLexicalDeclsFromExternalStorage() const {
573 36: ExternalASTSource *Source = getParentASTContext().getExternalSource();
36: branch 1 taken
0: branch 2 not taken
36: branch 3 taken
0: branch 4 not taken
574 36: assert(hasExternalLexicalStorage() && Source && "No external storage?");
575 :
576 36: llvm::SmallVector<uint32_t, 64> Decls;
0: branch 1 not taken
36: branch 2 taken
577 36: if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this),
578 : Decls))
579 0: return;
580 :
581 : // There is no longer any lexical storage in this context
582 36: ExternalLexicalStorage = false;
583 :
0: branch 1 not taken
36: branch 2 taken
584 36: if (Decls.empty())
585 : return;
586 :
587 : // Resolve all of the declaration IDs into declarations, building up
588 : // a chain of declarations via the Decl::NextDeclInContext field.
589 36: Decl *FirstNewDecl = 0;
590 36: Decl *PrevDecl = 0;
168: branch 1 taken
36: branch 2 taken
591 204: for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
592 168: Decl *D = Source->GetDecl(Decls[I]);
132: branch 0 taken
36: branch 1 taken
593 168: if (PrevDecl)
594 132: PrevDecl->NextDeclInContext = D;
595 : else
596 36: FirstNewDecl = D;
597 :
598 168: PrevDecl = D;
599 : }
600 :
601 : // Splice the newly-read declarations into the beginning of the list
602 : // of declarations.
603 36: PrevDecl->NextDeclInContext = FirstDecl;
604 36: FirstDecl = FirstNewDecl;
34: branch 0 taken
2: branch 1 taken
605 36: if (!LastDecl)
36: branch 1 taken
0: branch 2 not taken
606 34: LastDecl = PrevDecl;
607 : }
608 :
609 : void
610 6: DeclContext::LoadVisibleDeclsFromExternalStorage() const {
611 6: DeclContext *This = const_cast<DeclContext *>(this);
612 6: ExternalASTSource *Source = getParentASTContext().getExternalSource();
6: branch 1 taken
0: branch 2 not taken
6: branch 3 taken
0: branch 4 not taken
613 6: assert(hasExternalVisibleStorage() && Source && "No external storage?");
614 :
615 6: llvm::SmallVector<VisibleDeclaration, 64> Decls;
0: branch 1 not taken
6: branch 2 taken
616 6: if (Source->ReadDeclsVisibleInContext(This, Decls))
617 0: return;
618 :
619 : // There is no longer any visible storage in this context
620 6: ExternalVisibleStorage = false;
621 :
622 : // Load the declaration IDs for all of the names visible in this
623 : // context.
0: branch 0 not taken
6: branch 1 taken
624 6: assert(!LookupPtr && "Have a lookup map before de-serialization?");
625 6: StoredDeclsMap *Map = new StoredDeclsMap;
626 6: LookupPtr = Map;
19: branch 1 taken
6: branch 2 taken
627 25: for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
628 19: (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
6: branch 1 taken
0: branch 2 not taken
629 6: }
630 : }
631 :
632 85490: DeclContext::decl_iterator DeclContext::decls_begin() const {
34: branch 1 taken
85456: branch 2 taken
633 85490: if (hasExternalLexicalStorage())
634 34: LoadLexicalDeclsFromExternalStorage();
635 :
636 : // FIXME: Check whether we need to load some declarations from
637 : // external storage.
638 85490: return decl_iterator(FirstDecl);
639 : }
640 :
641 88543: DeclContext::decl_iterator DeclContext::decls_end() const {
1: branch 1 taken
88542: branch 2 taken
642 88543: if (hasExternalLexicalStorage())
643 1: LoadLexicalDeclsFromExternalStorage();
644 :
645 88543: return decl_iterator();
646 : }
647 :
648 208: bool DeclContext::decls_empty() const {
1: branch 1 taken
207: branch 2 taken
649 208: if (hasExternalLexicalStorage())
650 1: LoadLexicalDeclsFromExternalStorage();
651 :
652 208: return !FirstDecl;
653 : }
654 :
655 3: void DeclContext::removeDecl(Decl *D) {
656 : assert(D->getLexicalDeclContext() == this &&
3: branch 1 taken
0: branch 2 not taken
657 3: "decl being removed from non-lexical context");
658 : assert((D->NextDeclInContext || D == LastDecl) &&
2: branch 0 taken
1: branch 1 taken
0: branch 2 not taken
2: branch 3 taken
659 5: "decl is not in decls list");
660 :
661 : // Remove D from the decl chain. This is O(n) but hopefully rare.
0: branch 0 not taken
3: branch 1 taken
662 3: if (D == FirstDecl) {
0: branch 0 not taken
0: branch 1 not taken
663 0: if (D == LastDecl)
664 0: FirstDecl = LastDecl = 0;
665 : else
666 0: FirstDecl = D->NextDeclInContext;
667 : } else {
668 9: for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) {
0: branch 0 not taken
9: branch 1 taken
669 9: assert(I && "decl not found in linked list");
3: branch 0 taken
6: branch 1 taken
670 9: if (I->NextDeclInContext == D) {
671 3: I->NextDeclInContext = D->NextDeclInContext;
2: branch 0 taken
1: branch 1 taken
672 3: if (D == LastDecl) LastDecl = I;
673 3: break;
674 : }
675 : }
676 : }
677 :
678 : // Mark that D is no longer in the decl chain.
679 3: D->NextDeclInContext = 0;
680 :
681 : // Remove D from the lookup table if necessary.
3: branch 1 taken
0: branch 2 not taken
682 3: if (isa<NamedDecl>(D)) {
683 3: NamedDecl *ND = cast<NamedDecl>(D);
684 :
685 3: void *OpaqueMap = getPrimaryContext()->LookupPtr;
3: branch 0 taken
0: branch 1 not taken
686 3: if (!OpaqueMap) return;
687 :
688 3: StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(OpaqueMap);
689 3: StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
3: branch 3 taken
0: branch 4 not taken
690 3: assert(Pos != Map->end() && "no lookup entry for decl");
691 3: Pos->second.remove(ND);
692 : }
693 : }
694 :
695 87199: void DeclContext::addHiddenDecl(Decl *D) {
696 : assert(D->getLexicalDeclContext() == this &&
87199: branch 1 taken
0: branch 2 not taken
697 87199: "Decl inserted into wrong lexical context");
698 : assert(!D->getNextDeclInContext() && D != LastDecl &&
87199: branch 1 taken
0: branch 2 not taken
87199: branch 3 taken
0: branch 4 not taken
699 174398: "Decl already inserted into a DeclContext");
700 :
68070: branch 0 taken
19129: branch 1 taken
701 87199: if (FirstDecl) {
702 68070: LastDecl->NextDeclInContext = D;
703 68070: LastDecl = D;
704 : } else {
705 19129: FirstDecl = LastDecl = D;
706 : }
707 87199: }
708 :
709 87199: void DeclContext::addDecl(Decl *D) {
710 87199: addHiddenDecl(D);
711 :
85904: branch 1 taken
1295: branch 2 taken
712 87199: if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
713 85904: ND->getDeclContext()->makeDeclVisibleInContext(ND);
714 87199: }
715 :
716 : /// buildLookup - Build the lookup data structure with all of the
717 : /// declarations in DCtx (and any other contexts linked to it or
718 : /// transparent contexts nested within it).
719 21240: void DeclContext::buildLookup(DeclContext *DCtx) {
21302: branch 1 taken
21240: branch 2 taken
720 42542: for (; DCtx; DCtx = DCtx->getNextContext()) {
19122: branch 3 taken
21302: branch 4 taken
721 61726: for (decl_iterator D = DCtx->decls_begin(),
722 21302: DEnd = DCtx->decls_end();
723 : D != DEnd; ++D) {
724 : // Insert this declaration into the lookup structure, but only
725 : // if it's semantically in its decl context. During non-lazy
726 : // lookup building, this is implicitly enforced by addDecl.
16623: branch 2 taken
2499: branch 3 taken
727 19122: if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
16558: branch 2 taken
65: branch 3 taken
728 16623: if (D->getDeclContext() == DCtx)
729 16558: makeDeclVisibleInContextImpl(ND);
730 :
731 : // Insert any forward-declared Objective-C interfaces into the lookup
732 : // data structure.
0: branch 2 not taken
19122: branch 3 taken
733 19122: if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
0: branch 2 not taken
0: branch 3 not taken
734 0: for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
735 : I != IEnd; ++I)
736 0: makeDeclVisibleInContextImpl(I->getInterface());
737 :
738 : // If this declaration is itself a transparent declaration context,
739 : // add its members (recursively).
11242: branch 2 taken
7880: branch 3 taken
740 19122: if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
446: branch 1 taken
10796: branch 2 taken
741 11242: if (InnerCtx->isTransparentContext())
742 446: buildLookup(InnerCtx->getPrimaryContext());
743 : }
744 : }
745 21240: }
746 :
747 : DeclContext::lookup_result
748 157420: DeclContext::lookup(DeclarationName Name) {
749 157420: DeclContext *PrimaryContext = getPrimaryContext();
798: branch 0 taken
156622: branch 1 taken
750 157420: if (PrimaryContext != this)
751 798: return PrimaryContext->lookup(Name);
752 :
6: branch 1 taken
156616: branch 2 taken
753 156622: if (hasExternalVisibleStorage())
754 6: LoadVisibleDeclsFromExternalStorage();
755 :
756 : /// If there is no lookup data structure, build one now by walking
757 : /// all of the linked DeclContexts (in declaration order!) and
758 : /// inserting their values.
20794: branch 0 taken
135828: branch 1 taken
759 156622: if (!LookupPtr) {
760 20794: buildLookup(this);
761 :
11846: branch 0 taken
8948: branch 1 taken
762 20794: if (!LookupPtr)
763 11846: return lookup_result(0, 0);
764 : }
765 :
766 144776: StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr);
767 144776: StoredDeclsMap::iterator Pos = Map->find(Name);
108241: branch 3 taken
36535: branch 4 taken
768 144776: if (Pos == Map->end())
769 108241: return lookup_result(0, 0);
770 36535: return Pos->second.getLookupResult(getParentASTContext());
771 : }
772 :
773 : DeclContext::lookup_const_result
774 145797: DeclContext::lookup(DeclarationName Name) const {
775 145797: return const_cast<DeclContext*>(this)->lookup(Name);
776 : }
777 :
778 315681: DeclContext *DeclContext::getLookupContext() {
779 315681: DeclContext *Ctx = this;
780 : // Skip through transparent contexts.
3663: branch 1 taken
315681: branch 2 taken
781 635025: while (Ctx->isTransparentContext())
782 3663: Ctx = Ctx->getParent();
783 315681: return Ctx;
784 : }
785 :
786 916: DeclContext *DeclContext::getEnclosingNamespaceContext() {
787 916: DeclContext *Ctx = this;
788 : // Skip through non-namespace, non-translation-unit contexts.
916: branch 1 taken
151: branch 2 taken
0: branch 4 not taken
916: branch 5 taken
151: branch 6 taken
916: branch 7 taken
789 1983: while (!Ctx->isFileContext() || Ctx->isTransparentContext())
790 151: Ctx = Ctx->getParent();
791 916: return Ctx->getPrimaryContext();
792 : }
793 :
794 89847: void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
795 : // FIXME: This feels like a hack. Should DeclarationName support
796 : // template-ids, or is there a better way to keep specializations
797 : // from being visible?
403: branch 1 taken
89444: branch 2 taken
798 89847: if (isa<ClassTemplateSpecializationDecl>(D))
799 403: return;
30321: branch 1 taken
59123: branch 2 taken
800 89444: if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
42: branch 1 taken
30279: branch 2 taken
801 30321: if (FD->isFunctionTemplateSpecialization())
802 42: return;
803 :
804 89402: DeclContext *PrimaryContext = getPrimaryContext();
107: branch 0 taken
89295: branch 1 taken
805 89402: if (PrimaryContext != this) {
806 107: PrimaryContext->makeDeclVisibleInContext(D, Recoverable);
807 107: return;
808 : }
809 :
810 : // If we already have a lookup data structure, perform the insertion
811 : // into it. Otherwise, be lazy and don't build that structure until
812 : // someone asks for it.
60050: branch 0 taken
29245: branch 1 taken
0: branch 2 not taken
60050: branch 3 taken
813 89295: if (LookupPtr || !Recoverable)
814 29245: makeDeclVisibleInContextImpl(D);
815 :
816 : // If we are a transparent context, insert into our parent context,
817 : // too. This operation is recursive.
2556: branch 1 taken
86739: branch 2 taken
818 89295: if (isTransparentContext())
819 2556: getParent()->makeDeclVisibleInContext(D, Recoverable);
820 : }
821 :
822 45803: void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
823 : // Skip unnamed declarations.
810: branch 2 taken
44993: branch 3 taken
824 45803: if (!D->getDeclName())
825 810: return;
826 :
827 : // FIXME: This feels like a hack. Should DeclarationName support
828 : // template-ids, or is there a better way to keep specializations
829 : // from being visible?
0: branch 1 not taken
44993: branch 2 taken
830 44993: if (isa<ClassTemplateSpecializationDecl>(D))
831 0: return;
832 :
8948: branch 0 taken
36045: branch 1 taken
833 44993: if (!LookupPtr)
834 8948: LookupPtr = new StoredDeclsMap;
835 :
836 : // Insert this declaration into the map.
837 44993: StoredDeclsMap &Map = *static_cast<StoredDeclsMap*>(LookupPtr);
838 44993: StoredDeclsList &DeclNameEntries = Map[D->getDeclName()];
39668: branch 1 taken
5325: branch 2 taken
839 44993: if (DeclNameEntries.isNull()) {
840 39668: DeclNameEntries.setOnlyValue(D);
841 39668: return;
842 : }
843 :
844 : // If it is possible that this is a redeclaration, check to see if there is
845 : // already a decl for which declarationReplaces returns true. If there is
846 : // one, just replace it and return.
849: branch 2 taken
4476: branch 3 taken
847 5325: if (DeclNameEntries.HandleRedeclaration(getParentASTContext(), D))
848 849: return;
849 :
850 : // Put this declaration into the appropriate slot.
851 4476: DeclNameEntries.AddSubsequentDecl(D);
852 : }
853 :
854 : /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
855 : /// this context.
856 : DeclContext::udir_iterator_range
857 68025: DeclContext::getUsingDirectives() const {
858 68025: lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
859 : return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
860 68025: reinterpret_cast<udir_iterator>(Result.second));
861 : }
862 :
863 10: void StoredDeclsList::materializeDecls(ASTContext &Context) {
0: branch 1 not taken
10: branch 2 taken
864 10: if (isNull())
865 0: return;
866 :
0: branch 0 not taken
10: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
867 10: switch ((DataKind)(Data & 0x03)) {
868 : case DK_Decl:
869 : case DK_Decl_Vector:
870 0: break;
871 :
872 : case DK_DeclID: {
873 : // Resolve this declaration ID to an actual declaration by
874 : // querying the external AST source.
875 10: unsigned DeclID = Data >> 2;
876 :
877 10: ExternalASTSource *Source = Context.getExternalSource();
0: branch 0 not taken
10: branch 1 taken
878 10: assert(Source && "No external AST source available!");
879 :
880 10: Data = reinterpret_cast<uintptr_t>(Source->GetDecl(DeclID));
881 10: break;
882 : }
883 :
884 : case DK_ID_Vector: {
885 : // We have a vector of declaration IDs. Resolve all of them to
886 : // actual declarations.
887 0: VectorTy &Vector = *getAsVector();
888 0: ExternalASTSource *Source = Context.getExternalSource();
0: branch 0 not taken
0: branch 1 not taken
889 0: assert(Source && "No external AST source available!");
890 :
0: branch 1 not taken
0: branch 2 not taken
891 0: for (unsigned I = 0, N = Vector.size(); I != N; ++I)
892 0: Vector[I] = reinterpret_cast<uintptr_t>(Source->GetDecl(Vector[I]));
893 :
894 0: Data = (Data & ~0x03) | DK_Decl_Vector;
895 : break;
896 : }
897 : }
898 : }
Generated: 2010-02-10 01:31 by zcov