blob: 5d70493d1d6a211ce069337da4de67d3bba562c8 [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"
Daniel Dunbarde300732008-08-11 04:54:23 +000015#include "clang/AST/DeclObjC.h"
Argiris Kirtzidis6df1fc02008-06-09 21:05:31 +000016#include "clang/AST/DeclCXX.h"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000017#include "clang/AST/ASTContext.h"
Douglas Gregor8acb7272008-12-11 16:49:14 +000018#include "clang/AST/Type.h"
Eli Friedmana8a09ac2008-06-07 16:52:53 +000019#include "llvm/ADT/DenseMap.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// Statistics
24//===----------------------------------------------------------------------===//
25
26// temporary statistics gathering
27static unsigned nFuncs = 0;
28static unsigned nVars = 0;
29static unsigned nParmVars = 0;
Fariborz Jahaniana7babab2008-12-20 21:06:28 +000030static unsigned nOriginalParmVars = 0;
Eli Friedmana8a09ac2008-06-07 16:52:53 +000031static unsigned nSUC = 0;
Argiris Kirtzidisaefcabd2008-08-10 01:47:31 +000032static unsigned nCXXSUC = 0;
Eli Friedmana8a09ac2008-06-07 16:52:53 +000033static unsigned nEnumConst = 0;
34static unsigned nEnumDecls = 0;
35static unsigned nNamespaces = 0;
Douglas Gregord2baafd2008-10-21 16:13:35 +000036static unsigned nOverFuncs = 0;
Eli Friedmana8a09ac2008-06-07 16:52:53 +000037static unsigned nTypedef = 0;
38static unsigned nFieldDecls = 0;
39static unsigned nInterfaceDecls = 0;
40static unsigned nClassDecls = 0;
41static unsigned nMethodDecls = 0;
42static unsigned nProtocolDecls = 0;
43static unsigned nForwardProtocolDecls = 0;
44static unsigned nCategoryDecls = 0;
45static unsigned nIvarDecls = 0;
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000046static unsigned nAtDefsFieldDecls = 0;
Eli Friedmana8a09ac2008-06-07 16:52:53 +000047static unsigned nObjCImplementationDecls = 0;
48static unsigned nObjCCategoryImpl = 0;
49static unsigned nObjCCompatibleAlias = 0;
50static unsigned nObjCPropertyDecl = 0;
51static unsigned nObjCPropertyImplDecl = 0;
52static unsigned nLinkageSpecDecl = 0;
53static unsigned nFileScopeAsmDecl = 0;
Steve Naroff9ac456d2008-10-08 17:01:13 +000054static unsigned nBlockDecls = 0;
Eli Friedmana8a09ac2008-06-07 16:52:53 +000055
56static bool StatSwitch = false;
57
58// This keeps track of all decl attributes. Since so few decls have attrs, we
59// keep them in a hash map instead of wasting space in the Decl class.
60typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
61
62static DeclAttrMapTy *DeclAttrs = 0;
63
64const char *Decl::getDeclKindName() const {
65 switch (DeclKind) {
66 default: assert(0 && "Unknown decl kind!");
67 case Namespace: return "Namespace";
Douglas Gregord2baafd2008-10-21 16:13:35 +000068 case OverloadedFunction: return "OverloadedFunction";
Eli Friedmana8a09ac2008-06-07 16:52:53 +000069 case Typedef: return "Typedef";
70 case Function: return "Function";
71 case Var: return "Var";
72 case ParmVar: return "ParmVar";
Fariborz Jahaniana7babab2008-12-20 21:06:28 +000073 case OriginalParmVar: return "OriginalParmVar";
Eli Friedmana8a09ac2008-06-07 16:52:53 +000074 case EnumConstant: return "EnumConstant";
75 case ObjCIvar: return "ObjCIvar";
76 case ObjCInterface: return "ObjCInterface";
Steve Naroff110be842008-12-01 20:33:01 +000077 case ObjCImplementation: return "ObjCImplementation";
Eli Friedmana8a09ac2008-06-07 16:52:53 +000078 case ObjCClass: return "ObjCClass";
79 case ObjCMethod: return "ObjCMethod";
80 case ObjCProtocol: return "ObjCProtocol";
Steve Naroff110be842008-12-01 20:33:01 +000081 case ObjCProperty: return "ObjCProperty";
82 case ObjCPropertyImpl: return "ObjCPropertyImpl";
Eli Friedmana8a09ac2008-06-07 16:52:53 +000083 case ObjCForwardProtocol: return "ObjCForwardProtocol";
Argiris Kirtzidis2538a8c2008-10-15 00:42:39 +000084 case Record: return "Record";
85 case CXXRecord: return "CXXRecord";
Eli Friedmana8a09ac2008-06-07 16:52:53 +000086 case Enum: return "Enum";
Steve Naroff9ac456d2008-10-08 17:01:13 +000087 case Block: return "Block";
Eli Friedmana8a09ac2008-06-07 16:52:53 +000088 }
89}
90
91bool Decl::CollectingStats(bool Enable) {
92 if (Enable)
93 StatSwitch = true;
94 return StatSwitch;
95}
96
97void Decl::PrintStats() {
98 fprintf(stderr, "*** Decl Stats:\n");
99 fprintf(stderr, " %d decls total.\n",
Fariborz Jahaniana7babab2008-12-20 21:06:28 +0000100 int(nFuncs+nVars+nParmVars+nOriginalParmVars+nFieldDecls+nSUC+nCXXSUC+
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000101 nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
102 nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
Douglas Gregord2baafd2008-10-21 16:13:35 +0000103 nAtDefsFieldDecls+nNamespaces+nOverFuncs));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000104 fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n",
105 nNamespaces, (int)sizeof(NamespaceDecl),
106 int(nNamespaces*sizeof(NamespaceDecl)));
Douglas Gregord2baafd2008-10-21 16:13:35 +0000107 fprintf(stderr, " %d overloaded function decls, %d each (%d bytes)\n",
108 nOverFuncs, (int)sizeof(OverloadedFunctionDecl),
109 int(nOverFuncs*sizeof(OverloadedFunctionDecl)));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000110 fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
111 nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
112 fprintf(stderr, " %d variable decls, %d each (%d bytes)\n",
113 nVars, (int)sizeof(VarDecl),
114 int(nVars*sizeof(VarDecl)));
115 fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
116 nParmVars, (int)sizeof(ParmVarDecl),
117 int(nParmVars*sizeof(ParmVarDecl)));
Fariborz Jahaniana7babab2008-12-20 21:06:28 +0000118 fprintf(stderr, " %d original parameter variable decls, %d each (%d bytes)\n",
119 nOriginalParmVars, (int)sizeof(ParmVarWithOriginalTypeDecl),
120 int(nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000121 fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
122 nFieldDecls, (int)sizeof(FieldDecl),
123 int(nFieldDecls*sizeof(FieldDecl)));
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000124 fprintf(stderr, " %d @defs generated field decls, %d each (%d bytes)\n",
125 nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl),
126 int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl)));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000127 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
128 nSUC, (int)sizeof(RecordDecl),
129 int(nSUC*sizeof(RecordDecl)));
Argiris Kirtzidisaefcabd2008-08-10 01:47:31 +0000130 fprintf(stderr, " %d C++ struct/union/class decls, %d each (%d bytes)\n",
131 nCXXSUC, (int)sizeof(CXXRecordDecl),
132 int(nCXXSUC*sizeof(CXXRecordDecl)));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000133 fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
134 nEnumDecls, (int)sizeof(EnumDecl),
135 int(nEnumDecls*sizeof(EnumDecl)));
136 fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
137 nEnumConst, (int)sizeof(EnumConstantDecl),
138 int(nEnumConst*sizeof(EnumConstantDecl)));
139 fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
140 nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
141 // Objective-C decls...
142 fprintf(stderr, " %d interface decls, %d each (%d bytes)\n",
143 nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
144 int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
145 fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n",
146 nIvarDecls, (int)sizeof(ObjCIvarDecl),
147 int(nIvarDecls*sizeof(ObjCIvarDecl)));
148 fprintf(stderr, " %d class decls, %d each (%d bytes)\n",
149 nClassDecls, (int)sizeof(ObjCClassDecl),
150 int(nClassDecls*sizeof(ObjCClassDecl)));
151 fprintf(stderr, " %d method decls, %d each (%d bytes)\n",
152 nMethodDecls, (int)sizeof(ObjCMethodDecl),
153 int(nMethodDecls*sizeof(ObjCMethodDecl)));
154 fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n",
155 nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
156 int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
157 fprintf(stderr, " %d forward protocol decls, %d each (%d bytes)\n",
158 nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
159 int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
160 fprintf(stderr, " %d category decls, %d each (%d bytes)\n",
161 nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
162 int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
163
164 fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n",
165 nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
166 int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
167
168 fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n",
169 nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
170 int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
171
172 fprintf(stderr, " %d compatibility alias decls, %d each (%d bytes)\n",
173 nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
174 int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
175
176 fprintf(stderr, " %d property decls, %d each (%d bytes)\n",
177 nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
178 int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
179
180 fprintf(stderr, " %d property implementation decls, %d each (%d bytes)\n",
181 nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
182 int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
183
184 fprintf(stderr, "Total bytes = %d\n",
185 int(nFuncs*sizeof(FunctionDecl)+
186 nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
Fariborz Jahaniana7babab2008-12-20 21:06:28 +0000187 nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)+
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000188 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
Douglas Gregor8acb7272008-12-11 16:49:14 +0000189 nCXXSUC*sizeof(CXXRecordDecl)+
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000190 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
191 nTypedef*sizeof(TypedefDecl)+
192 nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
193 nIvarDecls*sizeof(ObjCIvarDecl)+
194 nClassDecls*sizeof(ObjCClassDecl)+
195 nMethodDecls*sizeof(ObjCMethodDecl)+
196 nProtocolDecls*sizeof(ObjCProtocolDecl)+
197 nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
198 nCategoryDecls*sizeof(ObjCCategoryDecl)+
199 nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
200 nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
201 nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
202 nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
203 nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
204 nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
205 nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
Douglas Gregord2baafd2008-10-21 16:13:35 +0000206 nNamespaces*sizeof(NamespaceDecl)+
207 nOverFuncs*sizeof(OverloadedFunctionDecl)));
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000208
209}
210
211void Decl::addDeclKind(Kind k) {
212 switch (k) {
213 case Namespace: nNamespaces++; break;
Douglas Gregord2baafd2008-10-21 16:13:35 +0000214 case OverloadedFunction: nOverFuncs++; break;
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000215 case Typedef: nTypedef++; break;
216 case Function: nFuncs++; break;
217 case Var: nVars++; break;
218 case ParmVar: nParmVars++; break;
Fariborz Jahaniana7babab2008-12-20 21:06:28 +0000219 case OriginalParmVar: nOriginalParmVars++; break;
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000220 case EnumConstant: nEnumConst++; break;
221 case Field: nFieldDecls++; break;
Argiris Kirtzidis2538a8c2008-10-15 00:42:39 +0000222 case Record: nSUC++; break;
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000223 case Enum: nEnumDecls++; break;
224 case ObjCInterface: nInterfaceDecls++; break;
225 case ObjCClass: nClassDecls++; break;
226 case ObjCMethod: nMethodDecls++; break;
227 case ObjCProtocol: nProtocolDecls++; break;
228 case ObjCForwardProtocol: nForwardProtocolDecls++; break;
229 case ObjCCategory: nCategoryDecls++; break;
230 case ObjCIvar: nIvarDecls++; break;
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000231 case ObjCAtDefsField: nAtDefsFieldDecls++; break;
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000232 case ObjCImplementation: nObjCImplementationDecls++; break;
233 case ObjCCategoryImpl: nObjCCategoryImpl++; break;
234 case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
235 case ObjCProperty: nObjCPropertyDecl++; break;
236 case ObjCPropertyImpl: nObjCPropertyImplDecl++; break;
237 case LinkageSpec: nLinkageSpecDecl++; break;
238 case FileScopeAsm: nFileScopeAsmDecl++; break;
Steve Naroff9ac456d2008-10-08 17:01:13 +0000239 case Block: nBlockDecls++; break;
Chris Lattner8c7c6a12008-06-17 18:05:57 +0000240 case ImplicitParam:
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000241 case TranslationUnit: break;
Argiris Kirtzidis6df1fc02008-06-09 21:05:31 +0000242
Argiris Kirtzidis2538a8c2008-10-15 00:42:39 +0000243 case CXXRecord: nCXXSUC++; break;
Argiris Kirtzidis6df1fc02008-06-09 21:05:31 +0000244 // FIXME: Statistics for C++ decls.
Douglas Gregordd861062008-12-05 18:15:24 +0000245 case TemplateTypeParm:
246 case NonTypeTemplateParm:
Argiris Kirtzidis6df1fc02008-06-09 21:05:31 +0000247 case CXXMethod:
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000248 case CXXConstructor:
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000249 case CXXDestructor:
Douglas Gregor3ef6c972008-11-07 20:08:42 +0000250 case CXXConversion:
Argiris Kirtzidis6df1fc02008-06-09 21:05:31 +0000251 case CXXClassVar:
252 break;
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000253 }
254}
255
256//===----------------------------------------------------------------------===//
257// Decl Implementation
258//===----------------------------------------------------------------------===//
259
260// Out-of-line virtual method providing a home for Decl.
261Decl::~Decl() {
262 if (!HasAttrs)
263 return;
264
265 DeclAttrMapTy::iterator it = DeclAttrs->find(this);
266 assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
267
268 // release attributes.
269 delete it->second;
270 invalidateAttrs();
271}
272
273void Decl::addAttr(Attr *NewAttr) {
274 if (!DeclAttrs)
275 DeclAttrs = new DeclAttrMapTy();
276
277 Attr *&ExistingAttr = (*DeclAttrs)[this];
278
279 NewAttr->setNext(ExistingAttr);
280 ExistingAttr = NewAttr;
281
282 HasAttrs = true;
283}
284
285void Decl::invalidateAttrs() {
286 if (!HasAttrs) return;
287
288 HasAttrs = false;
289 (*DeclAttrs)[this] = 0;
290 DeclAttrs->erase(this);
291
292 if (DeclAttrs->empty()) {
293 delete DeclAttrs;
294 DeclAttrs = 0;
295 }
296}
297
298const Attr *Decl::getAttrs() const {
299 if (!HasAttrs)
300 return 0;
301
302 return (*DeclAttrs)[this];
303}
304
305void Decl::swapAttrs(Decl *RHS) {
306 bool HasLHSAttr = this->HasAttrs;
307 bool HasRHSAttr = RHS->HasAttrs;
308
309 // Usually, neither decl has attrs, nothing to do.
310 if (!HasLHSAttr && !HasRHSAttr) return;
311
312 // If 'this' has no attrs, swap the other way.
313 if (!HasLHSAttr)
314 return RHS->swapAttrs(this);
315
316 // Handle the case when both decls have attrs.
317 if (HasRHSAttr) {
318 std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
319 return;
320 }
321
322 // Otherwise, LHS has an attr and RHS doesn't.
323 (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
324 (*DeclAttrs).erase(this);
325 this->HasAttrs = false;
326 RHS->HasAttrs = true;
327}
328
329
330void Decl::Destroy(ASTContext& C) {
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000331 if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
332
333 // Observe the unrolled recursion. By setting N->NextDeclarator = 0x0
334 // within the loop, only the Destroy method for the first ScopedDecl
335 // will deallocate all of the ScopedDecls in a chain.
336
337 ScopedDecl* N = SD->getNextDeclarator();
338
339 while (N) {
340 ScopedDecl* Tmp = N->getNextDeclarator();
341 N->NextDeclarator = 0x0;
342 N->Destroy(C);
343 N = Tmp;
344 }
345 }
346
347 this->~Decl();
348 C.getAllocator().Deallocate((void *)this);
349}
350
Argiris Kirtzidis4b662ea2008-10-12 16:14:48 +0000351Decl *Decl::castFromDeclContext (const DeclContext *D) {
352 return DeclContext::CastTo<Decl>(D);
353}
354
355DeclContext *Decl::castToDeclContext(const Decl *D) {
356 return DeclContext::CastTo<DeclContext>(D);
357}
358
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000359//===----------------------------------------------------------------------===//
360// DeclContext Implementation
361//===----------------------------------------------------------------------===//
362
Argiris Kirtzidis5703f442008-11-19 17:36:39 +0000363const DeclContext *DeclContext::getParent() const {
364 if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000365 return SD->getDeclContext();
Argiris Kirtzidis5703f442008-11-19 17:36:39 +0000366 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
Steve Naroff52059382008-10-10 01:28:17 +0000367 return BD->getParentContext();
Eli Friedmana8a09ac2008-06-07 16:52:53 +0000368 else
369 return NULL;
370}
Argiris Kirtzidis9cd599b2008-11-19 18:01:13 +0000371
372const DeclContext *DeclContext::getLexicalParent() const {
373 if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
374 return SD->getLexicalDeclContext();
Argiris Kirtzidisbc470282008-11-19 18:07:24 +0000375 return getParent();
Argiris Kirtzidis9cd599b2008-11-19 18:01:13 +0000376}
Douglas Gregor8acb7272008-12-11 16:49:14 +0000377
378/// TwoNamedDecls - Stores up to two NamedDecls. The first
379/// declaration, if any, is in the ordinary identifier namespace, and
380/// corresponds to values (functions, variables, etc.). The second
381/// declaration, if any, is in the tag identifier namespace, and
382/// corresponds to tag types (classes, enums).
383struct TwoNamedDecls {
384 NamedDecl* Decls[2];
385};
386
387// FIXME: We really want to use a DenseSet here to eliminate the
388// redundant storage of the declaration names, but (1) it doesn't give
389// us the ability to search based on DeclarationName, (2) we really
390// need something more like a DenseMultiSet, and (3) it's
391// implemented in terms of DenseMap anyway.
392typedef llvm::DenseMap<DeclarationName, TwoNamedDecls> StoredDeclsMap;
393
394DeclContext::~DeclContext() {
395 unsigned Size = LookupPtr.getInt();
396 if (Size == LookupIsMap) {
397 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
398 delete Map;
399 } else {
400 NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
401 delete [] Array;
402 }
403}
404
405void DeclContext::DestroyDecls(ASTContext &C) {
406 for (decl_iterator D = Decls.begin(); D != Decls.end(); ++D) {
407 if ((*D)->getLexicalDeclContext() == this)
408 (*D)->Destroy(C);
409 }
410}
411
412DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
413 switch (DeclKind) {
414 case Decl::Block:
415 case Decl::TranslationUnit:
416 // There is only one DeclContext for these entities.
417 return this;
418
419 case Decl::Namespace:
420 // The original namespace is our primary context.
421 return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
422
423 case Decl::Enum:
424 // The declaration associated with the enumeration type is our
425 // primary context.
426 return Context.getTypeDeclType(static_cast<EnumDecl*>(this))
427 ->getAsEnumType()->getDecl();
428
429 case Decl::Record:
430 case Decl::CXXRecord: {
431 // The declaration associated with the type is be our primary
432 // context.
433#if 0
434 // FIXME: This is what we expect to do. However, it doesn't work
435 // because ASTContext::setTagDefinition changes the result of
436 // Context.getTypeDeclType, meaning that our "primary" declaration
437 // of a RecordDecl/CXXRecordDecl will change, and we won't be able
438 // to find any values inserted into the earlier "primary"
439 // declaration. We need better tracking of redeclarations and
440 // definitions.
441 QualType Type = Context.getTypeDeclType(static_cast<RecordDecl*>(this));
442 return Type->getAsRecordType()->getDecl();
443#else
444 // FIXME: This hack will work for now, because the declaration we
445 // create when we're defining the record is the one we'll use as
446 // the definition later.
447 return this;
448#endif
449 }
450
451 case Decl::ObjCMethod:
452 return this;
453
454 case Decl::ObjCInterface:
455 // FIXME: Can Objective-C interfaces be forward-declared?
456 return this;
457
458 default:
459 assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
460 "Unknown DeclContext kind");
461 return this;
462 }
463}
464
465DeclContext *DeclContext::getNextContext() {
466 switch (DeclKind) {
467 case Decl::Block:
468 case Decl::TranslationUnit:
469 case Decl::Enum:
470 case Decl::Record:
471 case Decl::CXXRecord:
472 case Decl::ObjCMethod:
473 case Decl::ObjCInterface:
474 // There is only one DeclContext for these entities.
475 return 0;
476
477 case Decl::Namespace:
478 // Return the next namespace
479 return static_cast<NamespaceDecl*>(this)->getNextNamespace();
480
481 default:
482 assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
483 "Unknown DeclContext kind");
484 return 0;
485 }
486}
487
488void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup) {
489 Decls.push_back(D);
490 if (AllowLookup)
491 D->getDeclContext()->insert(Context, D);
492}
493
494DeclContext::lookup_result
495DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
496 DeclContext *PrimaryContext = getPrimaryContext(Context);
497 if (PrimaryContext != this)
498 return PrimaryContext->lookup(Context, Name);
499
500 /// If there is no lookup data structure, build one now by talking
501 /// all of the linked DeclContexts (in declaration order!) and
502 /// inserting their values.
503 if (LookupPtr.getPointer() == 0) {
504 for (DeclContext *DCtx = this; DCtx; DCtx = DCtx->getNextContext())
505 for (decl_iterator D = DCtx->decls_begin(); D != DCtx->decls_end(); ++D)
506 insertImpl(*D);
507 }
508
509 lookup_result Result(0, 0);
510 if (isLookupMap()) {
511 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
512 StoredDeclsMap::iterator Pos = Map->find(Name);
513 if (Pos != Map->end()) {
514 Result.first = Pos->second.Decls[0]? &Pos->second.Decls[0]
515 : &Pos->second.Decls[1];
516 Result.second = Pos->second.Decls[1]? &Pos->second.Decls[2]
517 : &Pos->second.Decls[1];
518 }
519 return Result;
520 }
521
522 // We have a small array. Look into it.
523 unsigned Size = LookupPtr.getInt();
524 NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
Douglas Gregor39677622008-12-11 20:41:00 +0000525 for (unsigned Idx = 0; Idx != Size; ++Idx)
Douglas Gregor8acb7272008-12-11 16:49:14 +0000526 if (Array[Idx]->getDeclName() == Name) {
527 Result.first = &Array[Idx];
528 Result.second = Result.first + 1;
529 if (Idx + 1 < Size && Array[Idx + 1]->getDeclName() == Name)
530 ++Result.second;
531 break;
532 }
533
534 return Result;
535}
536
537DeclContext::lookup_const_result
538DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
539 return const_cast<DeclContext*>(this)->lookup(Context, Name);
540}
541
542void DeclContext::insert(ASTContext &Context, NamedDecl *D) {
543 DeclContext *PrimaryContext = getPrimaryContext(Context);
544 if (PrimaryContext != this) {
545 PrimaryContext->insert(Context, D);
546 return;
547 }
548
549 // If we already have a lookup data structure, perform the insertion
550 // into it. Otherwise, be lazy and don't build that structure until
551 // someone asks for it.
552 if (LookupPtr.getPointer())
553 insertImpl(D);
554}
555
556void DeclContext::insertImpl(NamedDecl *D) {
557 if (!isLookupMap()) {
558 unsigned Size = LookupPtr.getInt();
559
560 // The lookup data is stored as an array. Search through the array
561 // to find the insertion location.
562 NamedDecl **Array;
563 if (Size == 0) {
564 Array = new NamedDecl*[LookupIsMap - 1];
565 LookupPtr.setPointer(Array);
566 } else {
567 Array = static_cast<NamedDecl **>(LookupPtr.getPointer());
568 }
569
570 // We always keep declarations of the same name next to each other
571 // in the array, so that it is easy to return multiple results
572 // from lookup(). There will be zero, one, or two declarations of
573 // the same name.
574 unsigned Match;
Douglas Gregor39677622008-12-11 20:41:00 +0000575 for (Match = 0; Match != Size; ++Match)
Douglas Gregor8acb7272008-12-11 16:49:14 +0000576 if (Array[Match]->getDeclName() == D->getDeclName())
Douglas Gregor39677622008-12-11 20:41:00 +0000577 break;
Douglas Gregor8acb7272008-12-11 16:49:14 +0000578
Douglas Gregor39677622008-12-11 20:41:00 +0000579 if (Match != Size) {
Douglas Gregor8acb7272008-12-11 16:49:14 +0000580 // We found another declaration with the same name. If it's also
581 // in the same identifier namespace, update the declaration in
582 // place.
583 Decl::IdentifierNamespace NS = D->getIdentifierNamespace();
584 if (Array[Match]->getIdentifierNamespace() == NS) {
585 Array[Match] = D;
586 return;
587 }
588 if (Match + 1 < Size && Array[Match + 1]->getIdentifierNamespace() == NS) {
589 Array[Match + 1] = D;
590 return;
591 }
592
593 // If there is an existing declaration in the namespace of
594 // ordinary identifiers, then it must precede the tag
595 // declaration for C++ name lookup to operate properly. Therefore,
596 // if our match is an ordinary name and the new name is in the
597 // tag namespace, we'll insert the new declaration after it.
Douglas Gregor39677622008-12-11 20:41:00 +0000598 if (Match != Size && (NS == Decl::IDNS_Tag) &&
Douglas Gregor8acb7272008-12-11 16:49:14 +0000599 (Array[Match]->getIdentifierNamespace() & Decl::IDNS_Ordinary))
600 ++Match;
601 }
602
603 if (Size < LookupIsMap - 1) {
604 // The new declaration will fit in the array. Insert the new
605 // declaration at the position Match in the array.
606 for (unsigned Idx = Size; Idx > Match; --Idx)
607 Array[Idx] = Array[Idx-1];
608
609 Array[Match] = D;
610 LookupPtr.setInt(Size + 1);
611 return;
612 }
613
614 // We've reached capacity in this array. Create a map and copy in
615 // all of the declarations that were stored in the array.
616 StoredDeclsMap *Map = new StoredDeclsMap(16);
617 LookupPtr.setPointer(Map);
618 LookupPtr.setInt(LookupIsMap);
Douglas Gregor39677622008-12-11 20:41:00 +0000619 for (unsigned Idx = 0; Idx != LookupIsMap - 1; ++Idx)
Douglas Gregor8acb7272008-12-11 16:49:14 +0000620 insertImpl(Array[Idx]);
621 delete [] Array;
622
623 // Fall through to perform insertion into the map.
624 }
625
626 // Insert this declaration into the map.
627 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
628 StoredDeclsMap::iterator Pos = Map->find(D->getDeclName());
629 unsigned IndexOfD = D->getIdentifierNamespace() & Decl::IDNS_Ordinary? 0 : 1;
630
631 if (Pos == Map->end()) {
632 // Put this declaration into the appropriate slot.
633 TwoNamedDecls Val;
Douglas Gregor8acb7272008-12-11 16:49:14 +0000634 Val.Decls[IndexOfD] = D;
Douglas Gregor39677622008-12-11 20:41:00 +0000635 Val.Decls[!IndexOfD] = 0;
636 Map->insert(std::make_pair(D->getDeclName(),Val)).first;
Douglas Gregor8acb7272008-12-11 16:49:14 +0000637 } else {
638 Pos->second.Decls[IndexOfD] = D;
639 }
640}