blob: 02e71d7a8681efe20a5219e6c744e3678b7899f0 [file] [log] [blame]
Eli Friedmana8a09ac2008-06-07 16:52:53 +00001//===--- 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"
Douglas Gregor469fc9a2009-02-02 23:39:07 +000015#include "clang/AST/Decl.h"
Douglas Gregord2b6edc2009-04-07 17:20:56 +000016#include "clang/AST/DeclContextInternals.h"
Argiris Kirtzidis6df1fc02008-06-09 21:05:31 +000017#include "clang/AST/DeclCXX.h"
Douglas Gregor279272e2009-02-04 19:02:06 +000018#include "clang/AST/DeclObjC.h"
19#include "clang/AST/DeclTemplate.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000020#include "clang/AST/ExternalASTSource.h"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000021#include "clang/AST/ASTContext.h"
Douglas Gregor8acb7272008-12-11 16:49:14 +000022#include "clang/AST/Type.h"
Sebastian Redlbc9ef252009-04-26 20:35:05 +000023#include "clang/AST/Stmt.h"
24#include "clang/AST/StmtCXX.h"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000025#include "llvm/ADT/DenseMap.h"
Chris Lattnerc309ade2009-03-05 08:00:35 +000026#include "llvm/Support/raw_ostream.h"
Douglas Gregor6e71edc2008-12-23 21:05:05 +000027#include <algorithm>
Chris Lattner7d6220c2009-03-02 22:20:04 +000028#include <cstdio>
Douglas Gregorddfd9d52008-12-23 00:26:44 +000029#include <vector>
Eli Friedmana8a09ac2008-06-07 16:52:53 +000030using namespace clang;
31
32//===----------------------------------------------------------------------===//
33// Statistics
34//===----------------------------------------------------------------------===//
35
Douglas Gregor469fc9a2009-02-02 23:39:07 +000036#define DECL(Derived, Base) static int n##Derived##s = 0;
37#include "clang/AST/DeclNodes.def"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000038
39static bool StatSwitch = false;
40
Eli Friedmana8a09ac2008-06-07 16:52:53 +000041const char *Decl::getDeclKindName() const {
42 switch (DeclKind) {
Douglas Gregor469fc9a2009-02-02 23:39:07 +000043 default: assert(0 && "Declaration not in DeclNodes.def!");
44#define DECL(Derived, Base) case Derived: return #Derived;
45#include "clang/AST/DeclNodes.def"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000046 }
47}
48
Steve Naroffe5f128a2009-01-20 19:53:53 +000049const char *DeclContext::getDeclKindName() const {
50 switch (DeclKind) {
Douglas Gregor469fc9a2009-02-02 23:39:07 +000051 default: assert(0 && "Declaration context not in DeclNodes.def!");
Argiris Kirtzidis2d9b7612009-02-16 14:28:33 +000052#define DECL(Derived, Base) case Decl::Derived: return #Derived;
Douglas Gregor469fc9a2009-02-02 23:39:07 +000053#include "clang/AST/DeclNodes.def"
Steve Naroffe5f128a2009-01-20 19:53:53 +000054 }
55}
56
Eli Friedmana8a09ac2008-06-07 16:52:53 +000057bool Decl::CollectingStats(bool Enable) {
58 if (Enable)
59 StatSwitch = true;
60 return StatSwitch;
61}
62
63void Decl::PrintStats() {
64 fprintf(stderr, "*** Decl Stats:\n");
Eli Friedmana8a09ac2008-06-07 16:52:53 +000065
Douglas Gregor469fc9a2009-02-02 23:39:07 +000066 int totalDecls = 0;
67#define DECL(Derived, Base) totalDecls += n##Derived##s;
68#include "clang/AST/DeclNodes.def"
69 fprintf(stderr, " %d decls total.\n", totalDecls);
70
71 int totalBytes = 0;
72#define DECL(Derived, Base) \
73 if (n##Derived##s > 0) { \
74 totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl)); \
75 fprintf(stderr, " %d " #Derived " decls, %d each (%d bytes)\n", \
76 n##Derived##s, (int)sizeof(Derived##Decl), \
77 (int)(n##Derived##s * sizeof(Derived##Decl))); \
78 }
79#include "clang/AST/DeclNodes.def"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000080
Douglas Gregor469fc9a2009-02-02 23:39:07 +000081 fprintf(stderr, "Total bytes = %d\n", totalBytes);
Eli Friedmana8a09ac2008-06-07 16:52:53 +000082}
83
84void Decl::addDeclKind(Kind k) {
85 switch (k) {
Douglas Gregor469fc9a2009-02-02 23:39:07 +000086 default: assert(0 && "Declaration not in DeclNodes.def!");
87#define DECL(Derived, Base) case Derived: ++n##Derived##s; break;
88#include "clang/AST/DeclNodes.def"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000089 }
90}
91
Anders Carlssonc2018a72009-06-13 00:08:58 +000092bool Decl::isTemplateParameterPack() const {
93 if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
94 return TTP->isParameterPack();
95
96 return false;
97}
98
Eli Friedmana8a09ac2008-06-07 16:52:53 +000099//===----------------------------------------------------------------------===//
Chris Lattnerc309ade2009-03-05 08:00:35 +0000100// PrettyStackTraceDecl Implementation
101//===----------------------------------------------------------------------===//
102
103void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
104 SourceLocation TheLoc = Loc;
105 if (TheLoc.isInvalid() && TheDecl)
106 TheLoc = TheDecl->getLocation();
107
108 if (TheLoc.isValid()) {
109 TheLoc.print(OS, SM);
110 OS << ": ";
111 }
112
113 OS << Message;
114
115 if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
116 OS << " '" << DN->getQualifiedNameAsString() << '\'';
117 OS << '\n';
118}
119
120//===----------------------------------------------------------------------===//
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000121// Decl Implementation
122//===----------------------------------------------------------------------===//
123
Chris Lattner8752fe02009-03-27 20:18:19 +0000124// Out-of-line virtual method providing a home for Decl.
125Decl::~Decl() {
126 if (isOutOfSemaDC())
127 delete getMultipleDC();
128
129 assert(!HasAttrs && "attributes should have been freed by Destroy");
130}
131
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000132void Decl::setDeclContext(DeclContext *DC) {
133 if (isOutOfSemaDC())
134 delete getMultipleDC();
135
Chris Lattner5ce4f6d2009-03-29 06:06:59 +0000136 DeclCtx = DC;
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000137}
138
139void Decl::setLexicalDeclContext(DeclContext *DC) {
140 if (DC == getLexicalDeclContext())
141 return;
142
143 if (isInSemaDC()) {
144 MultipleDC *MDC = new MultipleDC();
145 MDC->SemanticDC = getDeclContext();
146 MDC->LexicalDC = DC;
Chris Lattner5ce4f6d2009-03-29 06:06:59 +0000147 DeclCtx = MDC;
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000148 } else {
149 getMultipleDC()->LexicalDC = DC;
150 }
151}
152
Chris Lattner8752fe02009-03-27 20:18:19 +0000153unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
154 switch (DeclKind) {
155 default:
156 if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast)
157 return IDNS_Ordinary;
158 assert(0 && "Unknown decl kind!");
159 case OverloadedFunction:
160 case Typedef:
161 case EnumConstant:
162 case Var:
163 case ImplicitParam:
164 case ParmVar:
165 case OriginalParmVar:
166 case NonTypeTemplateParm:
Douglas Gregor683a1142009-06-20 00:51:54 +0000167 case Using:
Chris Lattner8752fe02009-03-27 20:18:19 +0000168 case ObjCMethod:
169 case ObjCContainer:
170 case ObjCCategory:
171 case ObjCInterface:
Chris Lattner8752fe02009-03-27 20:18:19 +0000172 case ObjCProperty:
173 case ObjCCompatibleAlias:
174 return IDNS_Ordinary;
175
176 case ObjCProtocol:
Douglas Gregorafd5eb32009-04-24 00:11:27 +0000177 return IDNS_ObjCProtocol;
Chris Lattner8752fe02009-03-27 20:18:19 +0000178
Douglas Gregorafd5eb32009-04-24 00:11:27 +0000179 case ObjCImplementation:
180 return IDNS_ObjCImplementation;
181
182 case ObjCCategoryImpl:
183 return IDNS_ObjCCategoryImpl;
184
Chris Lattner8752fe02009-03-27 20:18:19 +0000185 case Field:
186 case ObjCAtDefsField:
187 case ObjCIvar:
188 return IDNS_Member;
189
190 case Record:
191 case CXXRecord:
192 case Enum:
193 case TemplateTypeParm:
194 return IDNS_Tag;
195
196 case Namespace:
197 case Template:
198 case FunctionTemplate:
199 case ClassTemplate:
200 case TemplateTemplateParm:
Anders Carlsson1bf91fb2009-03-28 23:02:53 +0000201 case NamespaceAlias:
Chris Lattner8752fe02009-03-27 20:18:19 +0000202 return IDNS_Tag | IDNS_Ordinary;
203
204 // Never have names.
205 case LinkageSpec:
206 case FileScopeAsm:
207 case StaticAssert:
208 case ObjCClass:
Chris Lattner8752fe02009-03-27 20:18:19 +0000209 case ObjCPropertyImpl:
210 case ObjCForwardProtocol:
211 case Block:
212 case TranslationUnit:
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000213
Chris Lattner8752fe02009-03-27 20:18:19 +0000214 // Aren't looked up?
215 case UsingDirective:
216 case ClassTemplateSpecialization:
Douglas Gregor58944ac2009-05-31 09:31:02 +0000217 case ClassTemplatePartialSpecialization:
Chris Lattner8752fe02009-03-27 20:18:19 +0000218 return 0;
219 }
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000220}
221
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000222void Decl::addAttr(ASTContext &Context, Attr *NewAttr) {
223 Attr *&ExistingAttr = Context.getDeclAttrs(this);
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000224
225 NewAttr->setNext(ExistingAttr);
226 ExistingAttr = NewAttr;
227
228 HasAttrs = true;
229}
230
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000231void Decl::invalidateAttrs(ASTContext &Context) {
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000232 if (!HasAttrs) return;
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000233
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000234 HasAttrs = false;
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000235 Context.eraseDeclAttrs(this);
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000236}
237
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000238const Attr *Decl::getAttrsImpl(ASTContext &Context) const {
Chris Lattner004a9bb2009-03-21 06:27:31 +0000239 assert(HasAttrs && "getAttrs() should verify this!");
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000240 return Context.getDeclAttrs(this);
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000241}
242
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000243void Decl::swapAttrs(ASTContext &Context, Decl *RHS) {
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000244 bool HasLHSAttr = this->HasAttrs;
245 bool HasRHSAttr = RHS->HasAttrs;
246
247 // Usually, neither decl has attrs, nothing to do.
248 if (!HasLHSAttr && !HasRHSAttr) return;
249
250 // If 'this' has no attrs, swap the other way.
251 if (!HasLHSAttr)
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000252 return RHS->swapAttrs(Context, this);
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000253
254 // Handle the case when both decls have attrs.
255 if (HasRHSAttr) {
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000256 std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000257 return;
258 }
259
260 // Otherwise, LHS has an attr and RHS doesn't.
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000261 Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this);
262 Context.eraseDeclAttrs(this);
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000263 this->HasAttrs = false;
264 RHS->HasAttrs = true;
265}
266
267
Chris Lattner0fc6d642009-03-04 06:05:19 +0000268void Decl::Destroy(ASTContext &C) {
269 // Free attributes for this decl.
270 if (HasAttrs) {
Douglas Gregor98da6ae2009-06-18 16:11:24 +0000271 C.getDeclAttrs(this)->Destroy(C);
272 invalidateAttrs(C);
Chris Lattner0fc6d642009-03-04 06:05:19 +0000273 HasAttrs = false;
274 }
275
Douglas Gregor8314d742009-01-13 19:47:12 +0000276#if 0
Douglas Gregorf4006be2009-01-20 04:25:11 +0000277 // FIXME: Once ownership is fully understood, we can enable this code
278 if (DeclContext *DC = dyn_cast<DeclContext>(this))
279 DC->decls_begin()->Destroy(C);
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000280
Chris Lattnerfb8416a2009-03-28 06:04:26 +0000281 // Observe the unrolled recursion. By setting N->NextDeclInContext = 0x0
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000282 // within the loop, only the Destroy method for the first Decl
283 // will deallocate all of the Decls in a chain.
284
Chris Lattnerfb8416a2009-03-28 06:04:26 +0000285 Decl* N = getNextDeclInContext();
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000286
287 while (N) {
Chris Lattnerfb8416a2009-03-28 06:04:26 +0000288 Decl* Tmp = N->getNextDeclInContext();
289 N->NextDeclInContext = 0;
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000290 N->Destroy(C);
291 N = Tmp;
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000292 }
Douglas Gregor8314d742009-01-13 19:47:12 +0000293
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000294 this->~Decl();
Steve Naroff5abb0282009-01-27 21:25:57 +0000295 C.Deallocate((void *)this);
Douglas Gregorf4006be2009-01-20 04:25:11 +0000296#endif
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000297}
298
Argiris Kirtzidis4b662ea2008-10-12 16:14:48 +0000299Decl *Decl::castFromDeclContext (const DeclContext *D) {
Argiris Kirtzidis981aa132009-02-16 14:29:28 +0000300 Decl::Kind DK = D->getDeclKind();
301 switch(DK) {
302#define DECL_CONTEXT(Name) \
303 case Decl::Name: \
304 return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
305#define DECL_CONTEXT_BASE(Name)
306#include "clang/AST/DeclNodes.def"
307 default:
308#define DECL_CONTEXT_BASE(Name) \
309 if (DK >= Decl::Name##First && DK <= Decl::Name##Last) \
310 return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
311#include "clang/AST/DeclNodes.def"
312 assert(false && "a decl that inherits DeclContext isn't handled");
313 return 0;
314 }
Argiris Kirtzidis4b662ea2008-10-12 16:14:48 +0000315}
316
317DeclContext *Decl::castToDeclContext(const Decl *D) {
Argiris Kirtzidis981aa132009-02-16 14:29:28 +0000318 Decl::Kind DK = D->getKind();
319 switch(DK) {
320#define DECL_CONTEXT(Name) \
321 case Decl::Name: \
322 return static_cast<Name##Decl*>(const_cast<Decl*>(D));
323#define DECL_CONTEXT_BASE(Name)
324#include "clang/AST/DeclNodes.def"
325 default:
326#define DECL_CONTEXT_BASE(Name) \
327 if (DK >= Decl::Name##First && DK <= Decl::Name##Last) \
328 return static_cast<Name##Decl*>(const_cast<Decl*>(D));
329#include "clang/AST/DeclNodes.def"
330 assert(false && "a decl that inherits DeclContext isn't handled");
331 return 0;
332 }
Argiris Kirtzidis4b662ea2008-10-12 16:14:48 +0000333}
334
Sebastian Redlbc9ef252009-04-26 20:35:05 +0000335CompoundStmt* Decl::getCompoundBody(ASTContext &Context) const {
336 return dyn_cast_or_null<CompoundStmt>(getBody(Context));
337}
338
339SourceLocation Decl::getBodyRBrace(ASTContext &Context) const {
340 Stmt *Body = getBody(Context);
341 if (!Body)
342 return SourceLocation();
343 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
344 return CS->getRBracLoc();
345 assert(isa<CXXTryStmt>(Body) &&
346 "Body can only be CompoundStmt or CXXTryStmt");
347 return cast<CXXTryStmt>(Body)->getSourceRange().getEnd();
348}
349
Anders Carlsson8ea6a322009-03-25 23:38:06 +0000350#ifndef NDEBUG
351void Decl::CheckAccessDeclContext() const {
Douglas Gregora470cea2009-04-07 20:58:25 +0000352 assert((Access != AS_none || isa<TranslationUnitDecl>(this) ||
353 !isa<CXXRecordDecl>(getDeclContext())) &&
Anders Carlsson8ea6a322009-03-25 23:38:06 +0000354 "Access specifier is AS_none inside a record decl");
355}
356
357#endif
358
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000359//===----------------------------------------------------------------------===//
360// DeclContext Implementation
361//===----------------------------------------------------------------------===//
362
Argiris Kirtzidis981aa132009-02-16 14:29:28 +0000363bool DeclContext::classof(const Decl *D) {
364 switch (D->getKind()) {
365#define DECL_CONTEXT(Name) case Decl::Name:
366#define DECL_CONTEXT_BASE(Name)
367#include "clang/AST/DeclNodes.def"
368 return true;
369 default:
370#define DECL_CONTEXT_BASE(Name) \
371 if (D->getKind() >= Decl::Name##First && \
372 D->getKind() <= Decl::Name##Last) \
373 return true;
374#include "clang/AST/DeclNodes.def"
375 return false;
376 }
377}
378
Douglas Gregor8acb7272008-12-11 16:49:14 +0000379DeclContext::~DeclContext() {
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000380 delete static_cast<StoredDeclsMap*>(LookupPtr);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000381}
382
383void DeclContext::DestroyDecls(ASTContext &C) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000384 for (decl_iterator D = decls_begin(C); D != decls_end(C); )
Douglas Gregorf4006be2009-01-20 04:25:11 +0000385 (*D++)->Destroy(C);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000386}
387
Douglas Gregor1a6b88e2009-05-28 16:34:51 +0000388bool DeclContext::isDependentContext() const {
389 if (isFileContext())
390 return false;
391
Douglas Gregor58944ac2009-05-31 09:31:02 +0000392 if (isa<ClassTemplatePartialSpecializationDecl>(this))
393 return true;
394
Douglas Gregor1a6b88e2009-05-28 16:34:51 +0000395 if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
396 if (Record->getDescribedClassTemplate())
397 return true;
398
399 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this))
400 if (Function->getDescribedFunctionTemplate())
401 return true;
402
403 return getParent() && getParent()->isDependentContext();
404}
405
Douglas Gregord8028382009-01-05 19:45:36 +0000406bool DeclContext::isTransparentContext() const {
407 if (DeclKind == Decl::Enum)
408 return true; // FIXME: Check for C++0x scoped enums
409 else if (DeclKind == Decl::LinkageSpec)
410 return true;
Douglas Gregor1db12932009-02-26 00:02:51 +0000411 else if (DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast)
Douglas Gregor723d3332009-01-07 00:43:41 +0000412 return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
Douglas Gregord8028382009-01-05 19:45:36 +0000413 else if (DeclKind == Decl::Namespace)
414 return false; // FIXME: Check for C++0x inline namespaces
415
416 return false;
417}
418
Steve Naroffab63fd62009-01-08 17:28:14 +0000419DeclContext *DeclContext::getPrimaryContext() {
Douglas Gregor8acb7272008-12-11 16:49:14 +0000420 switch (DeclKind) {
Douglas Gregor8acb7272008-12-11 16:49:14 +0000421 case Decl::TranslationUnit:
Douglas Gregord8028382009-01-05 19:45:36 +0000422 case Decl::LinkageSpec:
423 case Decl::Block:
Douglas Gregor8acb7272008-12-11 16:49:14 +0000424 // There is only one DeclContext for these entities.
425 return this;
426
427 case Decl::Namespace:
428 // The original namespace is our primary context.
429 return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
430
Douglas Gregor8acb7272008-12-11 16:49:14 +0000431 case Decl::ObjCMethod:
432 return this;
433
434 case Decl::ObjCInterface:
Steve Naroffab63fd62009-01-08 17:28:14 +0000435 case Decl::ObjCProtocol:
436 case Decl::ObjCCategory:
Douglas Gregor8acb7272008-12-11 16:49:14 +0000437 // FIXME: Can Objective-C interfaces be forward-declared?
438 return this;
439
Steve Naroffab63fd62009-01-08 17:28:14 +0000440 case Decl::ObjCImplementation:
441 case Decl::ObjCCategoryImpl:
442 return this;
443
Douglas Gregor8acb7272008-12-11 16:49:14 +0000444 default:
Douglas Gregora08b6c72009-02-17 23:15:12 +0000445 if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
446 // If this is a tag type that has a definition or is currently
447 // being defined, that definition is our primary context.
Chris Lattnerfb8416a2009-03-28 06:04:26 +0000448 if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAsTagType())
Douglas Gregora08b6c72009-02-17 23:15:12 +0000449 if (TagT->isBeingDefined() ||
450 (TagT->getDecl() && TagT->getDecl()->isDefinition()))
451 return TagT->getDecl();
452 return this;
453 }
454
Douglas Gregor8acb7272008-12-11 16:49:14 +0000455 assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
456 "Unknown DeclContext kind");
457 return this;
458 }
459}
460
461DeclContext *DeclContext::getNextContext() {
462 switch (DeclKind) {
Douglas Gregor8acb7272008-12-11 16:49:14 +0000463 case Decl::Namespace:
464 // Return the next namespace
465 return static_cast<NamespaceDecl*>(this)->getNextNamespace();
466
467 default:
Douglas Gregor8acb7272008-12-11 16:49:14 +0000468 return 0;
469 }
470}
471
Douglas Gregorc34897d2009-04-09 22:27:44 +0000472/// \brief Load the declarations within this lexical storage from an
473/// external source.
474void
475DeclContext::LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const {
476 ExternalASTSource *Source = Context.getExternalSource();
477 assert(hasExternalLexicalStorage() && Source && "No external storage?");
478
Eli Friedmancdf59742009-04-27 23:43:36 +0000479 llvm::SmallVector<uint32_t, 64> Decls;
Douglas Gregorc34897d2009-04-09 22:27:44 +0000480 if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this),
481 Decls))
482 return;
483
484 // There is no longer any lexical storage in this context
485 ExternalLexicalStorage = false;
486
487 if (Decls.empty())
488 return;
489
490 // Resolve all of the declaration IDs into declarations, building up
491 // a chain of declarations via the Decl::NextDeclInContext field.
492 Decl *FirstNewDecl = 0;
493 Decl *PrevDecl = 0;
494 for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
495 Decl *D = Source->GetDecl(Decls[I]);
496 if (PrevDecl)
497 PrevDecl->NextDeclInContext = D;
498 else
499 FirstNewDecl = D;
500
501 PrevDecl = D;
502 }
503
504 // Splice the newly-read declarations into the beginning of the list
505 // of declarations.
506 PrevDecl->NextDeclInContext = FirstDecl;
507 FirstDecl = FirstNewDecl;
508 if (!LastDecl)
509 LastDecl = PrevDecl;
510}
511
512void
513DeclContext::LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const {
514 DeclContext *This = const_cast<DeclContext *>(this);
515 ExternalASTSource *Source = Context.getExternalSource();
516 assert(hasExternalVisibleStorage() && Source && "No external storage?");
517
518 llvm::SmallVector<VisibleDeclaration, 64> Decls;
519 if (Source->ReadDeclsVisibleInContext(This, Decls))
520 return;
521
522 // There is no longer any visible storage in this context
523 ExternalVisibleStorage = false;
524
525 // Load the declaration IDs for all of the names visible in this
526 // context.
527 assert(!LookupPtr && "Have a lookup map before de-serialization?");
528 StoredDeclsMap *Map = new StoredDeclsMap;
529 LookupPtr = Map;
530 for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
531 (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
532 }
533}
534
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000535DeclContext::decl_iterator DeclContext::decls_begin(ASTContext &Context) const {
Douglas Gregorc34897d2009-04-09 22:27:44 +0000536 if (hasExternalLexicalStorage())
537 LoadLexicalDeclsFromExternalStorage(Context);
538
539 // FIXME: Check whether we need to load some declarations from
540 // external storage.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000541 return decl_iterator(FirstDecl);
542}
543
544DeclContext::decl_iterator DeclContext::decls_end(ASTContext &Context) const {
Douglas Gregorc34897d2009-04-09 22:27:44 +0000545 if (hasExternalLexicalStorage())
546 LoadLexicalDeclsFromExternalStorage(Context);
547
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000548 return decl_iterator();
549}
550
Douglas Gregorac8f2802009-04-10 17:25:41 +0000551bool DeclContext::decls_empty(ASTContext &Context) const {
552 if (hasExternalLexicalStorage())
553 LoadLexicalDeclsFromExternalStorage(Context);
554
555 return !FirstDecl;
556}
557
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000558void DeclContext::addDecl(ASTContext &Context, Decl *D) {
Chris Lattner53602072009-02-20 00:56:18 +0000559 assert(D->getLexicalDeclContext() == this &&
560 "Decl inserted into wrong lexical context");
Chris Lattnerfb8416a2009-03-28 06:04:26 +0000561 assert(!D->getNextDeclInContext() && D != LastDecl &&
Douglas Gregord1675382009-01-09 19:42:16 +0000562 "Decl already inserted into a DeclContext");
563
564 if (FirstDecl) {
Chris Lattnerfb8416a2009-03-28 06:04:26 +0000565 LastDecl->NextDeclInContext = D;
Douglas Gregord1675382009-01-09 19:42:16 +0000566 LastDecl = D;
567 } else {
568 FirstDecl = LastDecl = D;
569 }
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000570
571 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000572 ND->getDeclContext()->makeDeclVisibleInContext(Context, ND);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000573}
574
Douglas Gregord8028382009-01-05 19:45:36 +0000575/// buildLookup - Build the lookup data structure with all of the
576/// declarations in DCtx (and any other contexts linked to it or
577/// transparent contexts nested within it).
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000578void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
Douglas Gregord8028382009-01-05 19:45:36 +0000579 for (; DCtx; DCtx = DCtx->getNextContext()) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000580 for (decl_iterator D = DCtx->decls_begin(Context),
581 DEnd = DCtx->decls_end(Context);
Douglas Gregorf0464ec2009-01-06 07:17:58 +0000582 D != DEnd; ++D) {
Douglas Gregord8028382009-01-05 19:45:36 +0000583 // Insert this declaration into the lookup structure
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000584 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000585 makeDeclVisibleInContextImpl(Context, ND);
Douglas Gregord8028382009-01-05 19:45:36 +0000586
587 // If this declaration is itself a transparent declaration context,
588 // add its members (recursively).
589 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
590 if (InnerCtx->isTransparentContext())
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000591 buildLookup(Context, InnerCtx->getPrimaryContext());
Douglas Gregord8028382009-01-05 19:45:36 +0000592 }
593 }
594}
595
Douglas Gregor8acb7272008-12-11 16:49:14 +0000596DeclContext::lookup_result
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000597DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
Steve Naroffab63fd62009-01-08 17:28:14 +0000598 DeclContext *PrimaryContext = getPrimaryContext();
Douglas Gregor8acb7272008-12-11 16:49:14 +0000599 if (PrimaryContext != this)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000600 return PrimaryContext->lookup(Context, Name);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000601
Douglas Gregorc34897d2009-04-09 22:27:44 +0000602 if (hasExternalVisibleStorage())
603 LoadVisibleDeclsFromExternalStorage(Context);
604
Douglas Gregorddfd9d52008-12-23 00:26:44 +0000605 /// If there is no lookup data structure, build one now by walking
Douglas Gregor8acb7272008-12-11 16:49:14 +0000606 /// all of the linked DeclContexts (in declaration order!) and
607 /// inserting their values.
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000608 if (!LookupPtr) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000609 buildLookup(Context, this);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000610
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000611 if (!LookupPtr)
Chris Lattner265f01d2009-02-20 00:55:03 +0000612 return lookup_result(0, 0);
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000613 }
Douglas Gregor8acb7272008-12-11 16:49:14 +0000614
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000615 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr);
616 StoredDeclsMap::iterator Pos = Map->find(Name);
617 if (Pos == Map->end())
618 return lookup_result(0, 0);
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000619 return Pos->second.getLookupResult(Context);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000620}
621
622DeclContext::lookup_const_result
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000623DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
624 return const_cast<DeclContext*>(this)->lookup(Context, Name);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000625}
626
Chris Lattner9a502bd2009-03-27 19:19:59 +0000627DeclContext *DeclContext::getLookupContext() {
628 DeclContext *Ctx = this;
Douglas Gregordb568cf2009-01-08 20:45:30 +0000629 // Skip through transparent contexts.
Douglas Gregor69e781f2009-01-06 23:51:29 +0000630 while (Ctx->isTransparentContext())
631 Ctx = Ctx->getParent();
632 return Ctx;
633}
634
Douglas Gregor0d93f692009-02-25 22:02:03 +0000635DeclContext *DeclContext::getEnclosingNamespaceContext() {
636 DeclContext *Ctx = this;
637 // Skip through non-namespace, non-translation-unit contexts.
638 while (!Ctx->isFileContext() || Ctx->isTransparentContext())
639 Ctx = Ctx->getParent();
640 return Ctx->getPrimaryContext();
641}
642
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000643void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
Douglas Gregora08b6c72009-02-17 23:15:12 +0000644 // FIXME: This feels like a hack. Should DeclarationName support
645 // template-ids, or is there a better way to keep specializations
646 // from being visible?
647 if (isa<ClassTemplateSpecializationDecl>(D))
648 return;
649
Steve Naroffab63fd62009-01-08 17:28:14 +0000650 DeclContext *PrimaryContext = getPrimaryContext();
Douglas Gregor8acb7272008-12-11 16:49:14 +0000651 if (PrimaryContext != this) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000652 PrimaryContext->makeDeclVisibleInContext(Context, D);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000653 return;
654 }
655
656 // If we already have a lookup data structure, perform the insertion
657 // into it. Otherwise, be lazy and don't build that structure until
658 // someone asks for it.
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000659 if (LookupPtr)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000660 makeDeclVisibleInContextImpl(Context, D);
Douglas Gregord8028382009-01-05 19:45:36 +0000661
Douglas Gregord8028382009-01-05 19:45:36 +0000662 // If we are a transparent context, insert into our parent context,
663 // too. This operation is recursive.
664 if (isTransparentContext())
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000665 getParent()->makeDeclVisibleInContext(Context, D);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000666}
667
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000668void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
669 NamedDecl *D) {
Douglas Gregord8028382009-01-05 19:45:36 +0000670 // Skip unnamed declarations.
671 if (!D->getDeclName())
672 return;
673
Douglas Gregora08b6c72009-02-17 23:15:12 +0000674 // FIXME: This feels like a hack. Should DeclarationName support
675 // template-ids, or is there a better way to keep specializations
676 // from being visible?
677 if (isa<ClassTemplateSpecializationDecl>(D))
678 return;
679
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000680 if (!LookupPtr)
681 LookupPtr = new StoredDeclsMap;
Douglas Gregor8acb7272008-12-11 16:49:14 +0000682
683 // Insert this declaration into the map.
Douglas Gregor13c27cd2009-04-09 17:29:08 +0000684 StoredDeclsMap &Map = *static_cast<StoredDeclsMap*>(LookupPtr);
Chris Lattner77820d52009-02-20 01:44:05 +0000685 StoredDeclsList &DeclNameEntries = Map[D->getDeclName()];
686 if (DeclNameEntries.isNull()) {
687 DeclNameEntries.setOnlyValue(D);
Chris Lattner6719b1f2009-02-19 07:00:44 +0000688 return;
Douglas Gregor8acb7272008-12-11 16:49:14 +0000689 }
Chris Lattner265f01d2009-02-20 00:55:03 +0000690
Chris Lattnerba589d42009-02-20 01:10:07 +0000691 // If it is possible that this is a redeclaration, check to see if there is
692 // already a decl for which declarationReplaces returns true. If there is
693 // one, just replace it and return.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000694 if (DeclNameEntries.HandleRedeclaration(Context, D))
Chris Lattner77820d52009-02-20 01:44:05 +0000695 return;
Chris Lattner265f01d2009-02-20 00:55:03 +0000696
Chris Lattner6719b1f2009-02-19 07:00:44 +0000697 // Put this declaration into the appropriate slot.
Chris Lattner77820d52009-02-20 01:44:05 +0000698 DeclNameEntries.AddSubsequentDecl(D);
Douglas Gregor8acb7272008-12-11 16:49:14 +0000699}
Douglas Gregor7a7be652009-02-03 19:21:40 +0000700
701/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
702/// this context.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000703DeclContext::udir_iterator_range
704DeclContext::getUsingDirectives(ASTContext &Context) const {
705 lookup_const_result Result = lookup(Context, UsingDirectiveDecl::getName());
Douglas Gregor7a7be652009-02-03 19:21:40 +0000706 return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
707 reinterpret_cast<udir_iterator>(Result.second));
708}
Douglas Gregorc34897d2009-04-09 22:27:44 +0000709
710void StoredDeclsList::materializeDecls(ASTContext &Context) {
711 if (isNull())
712 return;
713
714 switch ((DataKind)(Data & 0x03)) {
715 case DK_Decl:
716 case DK_Decl_Vector:
717 break;
718
719 case DK_DeclID: {
720 // Resolve this declaration ID to an actual declaration by
721 // querying the external AST source.
722 unsigned DeclID = Data >> 2;
723
724 ExternalASTSource *Source = Context.getExternalSource();
725 assert(Source && "No external AST source available!");
726
727 Data = reinterpret_cast<uintptr_t>(Source->GetDecl(DeclID));
728 break;
729 }
730
731 case DK_ID_Vector: {
732 // We have a vector of declaration IDs. Resolve all of them to
733 // actual declarations.
734 VectorTy &Vector = *getAsVector();
735 ExternalASTSource *Source = Context.getExternalSource();
736 assert(Source && "No external AST source available!");
737
738 for (unsigned I = 0, N = Vector.size(); I != N; ++I)
739 Vector[I] = reinterpret_cast<uintptr_t>(Source->GetDecl(Vector[I]));
740
741 Data = (Data & ~0x03) | DK_Decl_Vector;
742 break;
743 }
744 }
745}