xref: /minix3/external/bsd/llvm/dist/clang/lib/AST/DeclBase.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the Decl and DeclContext classes.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "clang/AST/DeclBase.h"
15f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
16f4a2713aSLionel Sambuc #include "clang/AST/ASTMutationListener.h"
17f4a2713aSLionel Sambuc #include "clang/AST/Attr.h"
18f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
20f4a2713aSLionel Sambuc #include "clang/AST/DeclContextInternals.h"
21f4a2713aSLionel Sambuc #include "clang/AST/DeclFriend.h"
22f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
23f4a2713aSLionel Sambuc #include "clang/AST/DeclOpenMP.h"
24f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
25f4a2713aSLionel Sambuc #include "clang/AST/DependentDiagnostic.h"
26f4a2713aSLionel Sambuc #include "clang/AST/ExternalASTSource.h"
27f4a2713aSLionel Sambuc #include "clang/AST/Stmt.h"
28f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h"
29f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
30f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
31f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h"
32f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
33f4a2713aSLionel Sambuc #include <algorithm>
34f4a2713aSLionel Sambuc using namespace clang;
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
37f4a2713aSLionel Sambuc //  Statistics
38f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
41f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
42f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
43f4a2713aSLionel Sambuc 
updateOutOfDate(IdentifierInfo & II) const44f4a2713aSLionel Sambuc void Decl::updateOutOfDate(IdentifierInfo &II) const {
45f4a2713aSLionel Sambuc   getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
46f4a2713aSLionel Sambuc }
47f4a2713aSLionel Sambuc 
operator new(std::size_t Size,const ASTContext & Context,unsigned ID,std::size_t Extra)48*0a6a1f1dSLionel Sambuc void *Decl::operator new(std::size_t Size, const ASTContext &Context,
49*0a6a1f1dSLionel Sambuc                          unsigned ID, std::size_t Extra) {
50f4a2713aSLionel Sambuc   // Allocate an extra 8 bytes worth of storage, which ensures that the
51f4a2713aSLionel Sambuc   // resulting pointer will still be 8-byte aligned.
52*0a6a1f1dSLionel Sambuc   void *Start = Context.Allocate(Size + Extra + 8);
53f4a2713aSLionel Sambuc   void *Result = (char*)Start + 8;
54f4a2713aSLionel Sambuc 
55f4a2713aSLionel Sambuc   unsigned *PrefixPtr = (unsigned *)Result - 2;
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc   // Zero out the first 4 bytes; this is used to store the owning module ID.
58f4a2713aSLionel Sambuc   PrefixPtr[0] = 0;
59f4a2713aSLionel Sambuc 
60f4a2713aSLionel Sambuc   // Store the global declaration ID in the second 4 bytes.
61f4a2713aSLionel Sambuc   PrefixPtr[1] = ID;
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   return Result;
64f4a2713aSLionel Sambuc }
65f4a2713aSLionel Sambuc 
operator new(std::size_t Size,const ASTContext & Ctx,DeclContext * Parent,std::size_t Extra)66*0a6a1f1dSLionel Sambuc void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
67*0a6a1f1dSLionel Sambuc                          DeclContext *Parent, std::size_t Extra) {
68*0a6a1f1dSLionel Sambuc   assert(!Parent || &Parent->getParentASTContext() == &Ctx);
69*0a6a1f1dSLionel Sambuc   return ::operator new(Size + Extra, Ctx);
70*0a6a1f1dSLionel Sambuc }
71*0a6a1f1dSLionel Sambuc 
getOwningModuleSlow() const72f4a2713aSLionel Sambuc Module *Decl::getOwningModuleSlow() const {
73f4a2713aSLionel Sambuc   assert(isFromASTFile() && "Not from AST file?");
74f4a2713aSLionel Sambuc   return getASTContext().getExternalSource()->getModule(getOwningModuleID());
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc 
getDeclKindName() const77f4a2713aSLionel Sambuc const char *Decl::getDeclKindName() const {
78f4a2713aSLionel Sambuc   switch (DeclKind) {
79f4a2713aSLionel Sambuc   default: llvm_unreachable("Declaration not in DeclNodes.inc!");
80f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
81f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
82f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
83f4a2713aSLionel Sambuc   }
84f4a2713aSLionel Sambuc }
85f4a2713aSLionel Sambuc 
setInvalidDecl(bool Invalid)86f4a2713aSLionel Sambuc void Decl::setInvalidDecl(bool Invalid) {
87f4a2713aSLionel Sambuc   InvalidDecl = Invalid;
88*0a6a1f1dSLionel Sambuc   assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
89f4a2713aSLionel Sambuc   if (Invalid && !isa<ParmVarDecl>(this)) {
90f4a2713aSLionel Sambuc     // Defensive maneuver for ill-formed code: we're likely not to make it to
91f4a2713aSLionel Sambuc     // a point where we set the access specifier, so default it to "public"
92f4a2713aSLionel Sambuc     // to avoid triggering asserts elsewhere in the front end.
93f4a2713aSLionel Sambuc     setAccess(AS_public);
94f4a2713aSLionel Sambuc   }
95f4a2713aSLionel Sambuc }
96f4a2713aSLionel Sambuc 
getDeclKindName() const97f4a2713aSLionel Sambuc const char *DeclContext::getDeclKindName() const {
98f4a2713aSLionel Sambuc   switch (DeclKind) {
99f4a2713aSLionel Sambuc   default: llvm_unreachable("Declaration context not in DeclNodes.inc!");
100f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
101f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
102f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
103f4a2713aSLionel Sambuc   }
104f4a2713aSLionel Sambuc }
105f4a2713aSLionel Sambuc 
106f4a2713aSLionel Sambuc bool Decl::StatisticsEnabled = false;
EnableStatistics()107f4a2713aSLionel Sambuc void Decl::EnableStatistics() {
108f4a2713aSLionel Sambuc   StatisticsEnabled = true;
109f4a2713aSLionel Sambuc }
110f4a2713aSLionel Sambuc 
PrintStats()111f4a2713aSLionel Sambuc void Decl::PrintStats() {
112f4a2713aSLionel Sambuc   llvm::errs() << "\n*** Decl Stats:\n";
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc   int totalDecls = 0;
115f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
116f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
117f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
118f4a2713aSLionel Sambuc   llvm::errs() << "  " << totalDecls << " decls total.\n";
119f4a2713aSLionel Sambuc 
120f4a2713aSLionel Sambuc   int totalBytes = 0;
121f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE)                                             \
122f4a2713aSLionel Sambuc   if (n##DERIVED##s > 0) {                                              \
123f4a2713aSLionel Sambuc     totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl));         \
124f4a2713aSLionel Sambuc     llvm::errs() << "    " << n##DERIVED##s << " " #DERIVED " decls, "  \
125f4a2713aSLionel Sambuc                  << sizeof(DERIVED##Decl) << " each ("                  \
126f4a2713aSLionel Sambuc                  << n##DERIVED##s * sizeof(DERIVED##Decl)               \
127f4a2713aSLionel Sambuc                  << " bytes)\n";                                        \
128f4a2713aSLionel Sambuc   }
129f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
130f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
131f4a2713aSLionel Sambuc 
132f4a2713aSLionel Sambuc   llvm::errs() << "Total bytes = " << totalBytes << "\n";
133f4a2713aSLionel Sambuc }
134f4a2713aSLionel Sambuc 
add(Kind k)135f4a2713aSLionel Sambuc void Decl::add(Kind k) {
136f4a2713aSLionel Sambuc   switch (k) {
137f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
138f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
139f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
140f4a2713aSLionel Sambuc   }
141f4a2713aSLionel Sambuc }
142f4a2713aSLionel Sambuc 
isTemplateParameterPack() const143f4a2713aSLionel Sambuc bool Decl::isTemplateParameterPack() const {
144f4a2713aSLionel Sambuc   if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
145f4a2713aSLionel Sambuc     return TTP->isParameterPack();
146f4a2713aSLionel Sambuc   if (const NonTypeTemplateParmDecl *NTTP
147f4a2713aSLionel Sambuc                                 = dyn_cast<NonTypeTemplateParmDecl>(this))
148f4a2713aSLionel Sambuc     return NTTP->isParameterPack();
149f4a2713aSLionel Sambuc   if (const TemplateTemplateParmDecl *TTP
150f4a2713aSLionel Sambuc                                     = dyn_cast<TemplateTemplateParmDecl>(this))
151f4a2713aSLionel Sambuc     return TTP->isParameterPack();
152f4a2713aSLionel Sambuc   return false;
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc 
isParameterPack() const155f4a2713aSLionel Sambuc bool Decl::isParameterPack() const {
156f4a2713aSLionel Sambuc   if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(this))
157f4a2713aSLionel Sambuc     return Parm->isParameterPack();
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc   return isTemplateParameterPack();
160f4a2713aSLionel Sambuc }
161f4a2713aSLionel Sambuc 
getAsFunction()162*0a6a1f1dSLionel Sambuc FunctionDecl *Decl::getAsFunction() {
163*0a6a1f1dSLionel Sambuc   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
164*0a6a1f1dSLionel Sambuc     return FD;
165*0a6a1f1dSLionel Sambuc   if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(this))
166*0a6a1f1dSLionel Sambuc     return FTD->getTemplatedDecl();
167*0a6a1f1dSLionel Sambuc   return nullptr;
168f4a2713aSLionel Sambuc }
169f4a2713aSLionel Sambuc 
isTemplateDecl() const170f4a2713aSLionel Sambuc bool Decl::isTemplateDecl() const {
171f4a2713aSLionel Sambuc   return isa<TemplateDecl>(this);
172f4a2713aSLionel Sambuc }
173f4a2713aSLionel Sambuc 
getParentFunctionOrMethod() const174f4a2713aSLionel Sambuc const DeclContext *Decl::getParentFunctionOrMethod() const {
175f4a2713aSLionel Sambuc   for (const DeclContext *DC = getDeclContext();
176f4a2713aSLionel Sambuc        DC && !DC->isTranslationUnit() && !DC->isNamespace();
177f4a2713aSLionel Sambuc        DC = DC->getParent())
178f4a2713aSLionel Sambuc     if (DC->isFunctionOrMethod())
179f4a2713aSLionel Sambuc       return DC;
180f4a2713aSLionel Sambuc 
181*0a6a1f1dSLionel Sambuc   return nullptr;
182f4a2713aSLionel Sambuc }
183f4a2713aSLionel Sambuc 
184f4a2713aSLionel Sambuc 
185f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
186f4a2713aSLionel Sambuc // PrettyStackTraceDecl Implementation
187f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
188f4a2713aSLionel Sambuc 
print(raw_ostream & OS) const189f4a2713aSLionel Sambuc void PrettyStackTraceDecl::print(raw_ostream &OS) const {
190f4a2713aSLionel Sambuc   SourceLocation TheLoc = Loc;
191f4a2713aSLionel Sambuc   if (TheLoc.isInvalid() && TheDecl)
192f4a2713aSLionel Sambuc     TheLoc = TheDecl->getLocation();
193f4a2713aSLionel Sambuc 
194f4a2713aSLionel Sambuc   if (TheLoc.isValid()) {
195f4a2713aSLionel Sambuc     TheLoc.print(OS, SM);
196f4a2713aSLionel Sambuc     OS << ": ";
197f4a2713aSLionel Sambuc   }
198f4a2713aSLionel Sambuc 
199f4a2713aSLionel Sambuc   OS << Message;
200f4a2713aSLionel Sambuc 
201f4a2713aSLionel Sambuc   if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
202f4a2713aSLionel Sambuc     OS << " '";
203f4a2713aSLionel Sambuc     DN->printQualifiedName(OS);
204f4a2713aSLionel Sambuc     OS << '\'';
205f4a2713aSLionel Sambuc   }
206f4a2713aSLionel Sambuc   OS << '\n';
207f4a2713aSLionel Sambuc }
208f4a2713aSLionel Sambuc 
209f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
210f4a2713aSLionel Sambuc // Decl Implementation
211f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
212f4a2713aSLionel Sambuc 
213f4a2713aSLionel Sambuc // Out-of-line virtual method providing a home for Decl.
~Decl()214f4a2713aSLionel Sambuc Decl::~Decl() { }
215f4a2713aSLionel Sambuc 
setDeclContext(DeclContext * DC)216f4a2713aSLionel Sambuc void Decl::setDeclContext(DeclContext *DC) {
217f4a2713aSLionel Sambuc   DeclCtx = DC;
218f4a2713aSLionel Sambuc }
219f4a2713aSLionel Sambuc 
setLexicalDeclContext(DeclContext * DC)220f4a2713aSLionel Sambuc void Decl::setLexicalDeclContext(DeclContext *DC) {
221f4a2713aSLionel Sambuc   if (DC == getLexicalDeclContext())
222f4a2713aSLionel Sambuc     return;
223f4a2713aSLionel Sambuc 
224f4a2713aSLionel Sambuc   if (isInSemaDC()) {
225f4a2713aSLionel Sambuc     setDeclContextsImpl(getDeclContext(), DC, getASTContext());
226f4a2713aSLionel Sambuc   } else {
227f4a2713aSLionel Sambuc     getMultipleDC()->LexicalDC = DC;
228f4a2713aSLionel Sambuc   }
229f4a2713aSLionel Sambuc }
230f4a2713aSLionel Sambuc 
setDeclContextsImpl(DeclContext * SemaDC,DeclContext * LexicalDC,ASTContext & Ctx)231f4a2713aSLionel Sambuc void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
232f4a2713aSLionel Sambuc                                ASTContext &Ctx) {
233f4a2713aSLionel Sambuc   if (SemaDC == LexicalDC) {
234f4a2713aSLionel Sambuc     DeclCtx = SemaDC;
235f4a2713aSLionel Sambuc   } else {
236f4a2713aSLionel Sambuc     Decl::MultipleDC *MDC = new (Ctx) Decl::MultipleDC();
237f4a2713aSLionel Sambuc     MDC->SemanticDC = SemaDC;
238f4a2713aSLionel Sambuc     MDC->LexicalDC = LexicalDC;
239f4a2713aSLionel Sambuc     DeclCtx = MDC;
240f4a2713aSLionel Sambuc   }
241f4a2713aSLionel Sambuc }
242f4a2713aSLionel Sambuc 
isInAnonymousNamespace() const243f4a2713aSLionel Sambuc bool Decl::isInAnonymousNamespace() const {
244f4a2713aSLionel Sambuc   const DeclContext *DC = getDeclContext();
245f4a2713aSLionel Sambuc   do {
246f4a2713aSLionel Sambuc     if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
247f4a2713aSLionel Sambuc       if (ND->isAnonymousNamespace())
248f4a2713aSLionel Sambuc         return true;
249f4a2713aSLionel Sambuc   } while ((DC = DC->getParent()));
250f4a2713aSLionel Sambuc 
251f4a2713aSLionel Sambuc   return false;
252f4a2713aSLionel Sambuc }
253f4a2713aSLionel Sambuc 
isInStdNamespace() const254*0a6a1f1dSLionel Sambuc bool Decl::isInStdNamespace() const {
255*0a6a1f1dSLionel Sambuc   return getDeclContext()->isStdNamespace();
256*0a6a1f1dSLionel Sambuc }
257*0a6a1f1dSLionel Sambuc 
getTranslationUnitDecl()258f4a2713aSLionel Sambuc TranslationUnitDecl *Decl::getTranslationUnitDecl() {
259f4a2713aSLionel Sambuc   if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
260f4a2713aSLionel Sambuc     return TUD;
261f4a2713aSLionel Sambuc 
262f4a2713aSLionel Sambuc   DeclContext *DC = getDeclContext();
263f4a2713aSLionel Sambuc   assert(DC && "This decl is not contained in a translation unit!");
264f4a2713aSLionel Sambuc 
265f4a2713aSLionel Sambuc   while (!DC->isTranslationUnit()) {
266f4a2713aSLionel Sambuc     DC = DC->getParent();
267f4a2713aSLionel Sambuc     assert(DC && "This decl is not contained in a translation unit!");
268f4a2713aSLionel Sambuc   }
269f4a2713aSLionel Sambuc 
270f4a2713aSLionel Sambuc   return cast<TranslationUnitDecl>(DC);
271f4a2713aSLionel Sambuc }
272f4a2713aSLionel Sambuc 
getASTContext() const273f4a2713aSLionel Sambuc ASTContext &Decl::getASTContext() const {
274f4a2713aSLionel Sambuc   return getTranslationUnitDecl()->getASTContext();
275f4a2713aSLionel Sambuc }
276f4a2713aSLionel Sambuc 
getASTMutationListener() const277f4a2713aSLionel Sambuc ASTMutationListener *Decl::getASTMutationListener() const {
278f4a2713aSLionel Sambuc   return getASTContext().getASTMutationListener();
279f4a2713aSLionel Sambuc }
280f4a2713aSLionel Sambuc 
getMaxAlignment() const281f4a2713aSLionel Sambuc unsigned Decl::getMaxAlignment() const {
282f4a2713aSLionel Sambuc   if (!hasAttrs())
283f4a2713aSLionel Sambuc     return 0;
284f4a2713aSLionel Sambuc 
285f4a2713aSLionel Sambuc   unsigned Align = 0;
286f4a2713aSLionel Sambuc   const AttrVec &V = getAttrs();
287f4a2713aSLionel Sambuc   ASTContext &Ctx = getASTContext();
288f4a2713aSLionel Sambuc   specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());
289f4a2713aSLionel Sambuc   for (; I != E; ++I)
290f4a2713aSLionel Sambuc     Align = std::max(Align, I->getAlignment(Ctx));
291f4a2713aSLionel Sambuc   return Align;
292f4a2713aSLionel Sambuc }
293f4a2713aSLionel Sambuc 
isUsed(bool CheckUsedAttr) const294f4a2713aSLionel Sambuc bool Decl::isUsed(bool CheckUsedAttr) const {
295f4a2713aSLionel Sambuc   if (Used)
296f4a2713aSLionel Sambuc     return true;
297f4a2713aSLionel Sambuc 
298f4a2713aSLionel Sambuc   // Check for used attribute.
299f4a2713aSLionel Sambuc   if (CheckUsedAttr && hasAttr<UsedAttr>())
300f4a2713aSLionel Sambuc     return true;
301f4a2713aSLionel Sambuc 
302f4a2713aSLionel Sambuc   return false;
303f4a2713aSLionel Sambuc }
304f4a2713aSLionel Sambuc 
markUsed(ASTContext & C)305f4a2713aSLionel Sambuc void Decl::markUsed(ASTContext &C) {
306f4a2713aSLionel Sambuc   if (Used)
307f4a2713aSLionel Sambuc     return;
308f4a2713aSLionel Sambuc 
309f4a2713aSLionel Sambuc   if (C.getASTMutationListener())
310f4a2713aSLionel Sambuc     C.getASTMutationListener()->DeclarationMarkedUsed(this);
311f4a2713aSLionel Sambuc 
312f4a2713aSLionel Sambuc   Used = true;
313f4a2713aSLionel Sambuc }
314f4a2713aSLionel Sambuc 
isReferenced() const315f4a2713aSLionel Sambuc bool Decl::isReferenced() const {
316f4a2713aSLionel Sambuc   if (Referenced)
317f4a2713aSLionel Sambuc     return true;
318f4a2713aSLionel Sambuc 
319f4a2713aSLionel Sambuc   // Check redeclarations.
320*0a6a1f1dSLionel Sambuc   for (auto I : redecls())
321f4a2713aSLionel Sambuc     if (I->Referenced)
322f4a2713aSLionel Sambuc       return true;
323f4a2713aSLionel Sambuc 
324f4a2713aSLionel Sambuc   return false;
325f4a2713aSLionel Sambuc }
326f4a2713aSLionel Sambuc 
327f4a2713aSLionel Sambuc /// \brief Determine the availability of the given declaration based on
328f4a2713aSLionel Sambuc /// the target platform.
329f4a2713aSLionel Sambuc ///
330f4a2713aSLionel Sambuc /// When it returns an availability result other than \c AR_Available,
331f4a2713aSLionel Sambuc /// if the \p Message parameter is non-NULL, it will be set to a
332f4a2713aSLionel Sambuc /// string describing why the entity is unavailable.
333f4a2713aSLionel Sambuc ///
334f4a2713aSLionel Sambuc /// FIXME: Make these strings localizable, since they end up in
335f4a2713aSLionel Sambuc /// diagnostics.
CheckAvailability(ASTContext & Context,const AvailabilityAttr * A,std::string * Message)336f4a2713aSLionel Sambuc static AvailabilityResult CheckAvailability(ASTContext &Context,
337f4a2713aSLionel Sambuc                                             const AvailabilityAttr *A,
338f4a2713aSLionel Sambuc                                             std::string *Message) {
339f4a2713aSLionel Sambuc   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
340f4a2713aSLionel Sambuc   StringRef PrettyPlatformName
341f4a2713aSLionel Sambuc     = AvailabilityAttr::getPrettyPlatformName(TargetPlatform);
342f4a2713aSLionel Sambuc   if (PrettyPlatformName.empty())
343f4a2713aSLionel Sambuc     PrettyPlatformName = TargetPlatform;
344f4a2713aSLionel Sambuc 
345f4a2713aSLionel Sambuc   VersionTuple TargetMinVersion = Context.getTargetInfo().getPlatformMinVersion();
346f4a2713aSLionel Sambuc   if (TargetMinVersion.empty())
347f4a2713aSLionel Sambuc     return AR_Available;
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc   // Match the platform name.
350f4a2713aSLionel Sambuc   if (A->getPlatform()->getName() != TargetPlatform)
351f4a2713aSLionel Sambuc     return AR_Available;
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc   std::string HintMessage;
354f4a2713aSLionel Sambuc   if (!A->getMessage().empty()) {
355f4a2713aSLionel Sambuc     HintMessage = " - ";
356f4a2713aSLionel Sambuc     HintMessage += A->getMessage();
357f4a2713aSLionel Sambuc   }
358f4a2713aSLionel Sambuc 
359f4a2713aSLionel Sambuc   // Make sure that this declaration has not been marked 'unavailable'.
360f4a2713aSLionel Sambuc   if (A->getUnavailable()) {
361f4a2713aSLionel Sambuc     if (Message) {
362f4a2713aSLionel Sambuc       Message->clear();
363f4a2713aSLionel Sambuc       llvm::raw_string_ostream Out(*Message);
364f4a2713aSLionel Sambuc       Out << "not available on " << PrettyPlatformName
365f4a2713aSLionel Sambuc           << HintMessage;
366f4a2713aSLionel Sambuc     }
367f4a2713aSLionel Sambuc 
368f4a2713aSLionel Sambuc     return AR_Unavailable;
369f4a2713aSLionel Sambuc   }
370f4a2713aSLionel Sambuc 
371f4a2713aSLionel Sambuc   // Make sure that this declaration has already been introduced.
372f4a2713aSLionel Sambuc   if (!A->getIntroduced().empty() &&
373f4a2713aSLionel Sambuc       TargetMinVersion < A->getIntroduced()) {
374f4a2713aSLionel Sambuc     if (Message) {
375f4a2713aSLionel Sambuc       Message->clear();
376f4a2713aSLionel Sambuc       llvm::raw_string_ostream Out(*Message);
377*0a6a1f1dSLionel Sambuc       VersionTuple VTI(A->getIntroduced());
378*0a6a1f1dSLionel Sambuc       VTI.UseDotAsSeparator();
379f4a2713aSLionel Sambuc       Out << "introduced in " << PrettyPlatformName << ' '
380*0a6a1f1dSLionel Sambuc           << VTI << HintMessage;
381f4a2713aSLionel Sambuc     }
382f4a2713aSLionel Sambuc 
383f4a2713aSLionel Sambuc     return AR_NotYetIntroduced;
384f4a2713aSLionel Sambuc   }
385f4a2713aSLionel Sambuc 
386f4a2713aSLionel Sambuc   // Make sure that this declaration hasn't been obsoleted.
387f4a2713aSLionel Sambuc   if (!A->getObsoleted().empty() && TargetMinVersion >= A->getObsoleted()) {
388f4a2713aSLionel Sambuc     if (Message) {
389f4a2713aSLionel Sambuc       Message->clear();
390f4a2713aSLionel Sambuc       llvm::raw_string_ostream Out(*Message);
391*0a6a1f1dSLionel Sambuc       VersionTuple VTO(A->getObsoleted());
392*0a6a1f1dSLionel Sambuc       VTO.UseDotAsSeparator();
393f4a2713aSLionel Sambuc       Out << "obsoleted in " << PrettyPlatformName << ' '
394*0a6a1f1dSLionel Sambuc           << VTO << HintMessage;
395f4a2713aSLionel Sambuc     }
396f4a2713aSLionel Sambuc 
397f4a2713aSLionel Sambuc     return AR_Unavailable;
398f4a2713aSLionel Sambuc   }
399f4a2713aSLionel Sambuc 
400f4a2713aSLionel Sambuc   // Make sure that this declaration hasn't been deprecated.
401f4a2713aSLionel Sambuc   if (!A->getDeprecated().empty() && TargetMinVersion >= A->getDeprecated()) {
402f4a2713aSLionel Sambuc     if (Message) {
403f4a2713aSLionel Sambuc       Message->clear();
404f4a2713aSLionel Sambuc       llvm::raw_string_ostream Out(*Message);
405*0a6a1f1dSLionel Sambuc       VersionTuple VTD(A->getDeprecated());
406*0a6a1f1dSLionel Sambuc       VTD.UseDotAsSeparator();
407f4a2713aSLionel Sambuc       Out << "first deprecated in " << PrettyPlatformName << ' '
408*0a6a1f1dSLionel Sambuc           << VTD << HintMessage;
409f4a2713aSLionel Sambuc     }
410f4a2713aSLionel Sambuc 
411f4a2713aSLionel Sambuc     return AR_Deprecated;
412f4a2713aSLionel Sambuc   }
413f4a2713aSLionel Sambuc 
414f4a2713aSLionel Sambuc   return AR_Available;
415f4a2713aSLionel Sambuc }
416f4a2713aSLionel Sambuc 
getAvailability(std::string * Message) const417f4a2713aSLionel Sambuc AvailabilityResult Decl::getAvailability(std::string *Message) const {
418f4a2713aSLionel Sambuc   AvailabilityResult Result = AR_Available;
419f4a2713aSLionel Sambuc   std::string ResultMessage;
420f4a2713aSLionel Sambuc 
421*0a6a1f1dSLionel Sambuc   for (const auto *A : attrs()) {
422*0a6a1f1dSLionel Sambuc     if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
423f4a2713aSLionel Sambuc       if (Result >= AR_Deprecated)
424f4a2713aSLionel Sambuc         continue;
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc       if (Message)
427f4a2713aSLionel Sambuc         ResultMessage = Deprecated->getMessage();
428f4a2713aSLionel Sambuc 
429f4a2713aSLionel Sambuc       Result = AR_Deprecated;
430f4a2713aSLionel Sambuc       continue;
431f4a2713aSLionel Sambuc     }
432f4a2713aSLionel Sambuc 
433*0a6a1f1dSLionel Sambuc     if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
434f4a2713aSLionel Sambuc       if (Message)
435f4a2713aSLionel Sambuc         *Message = Unavailable->getMessage();
436f4a2713aSLionel Sambuc       return AR_Unavailable;
437f4a2713aSLionel Sambuc     }
438f4a2713aSLionel Sambuc 
439*0a6a1f1dSLionel Sambuc     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
440f4a2713aSLionel Sambuc       AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
441f4a2713aSLionel Sambuc                                                 Message);
442f4a2713aSLionel Sambuc 
443f4a2713aSLionel Sambuc       if (AR == AR_Unavailable)
444f4a2713aSLionel Sambuc         return AR_Unavailable;
445f4a2713aSLionel Sambuc 
446f4a2713aSLionel Sambuc       if (AR > Result) {
447f4a2713aSLionel Sambuc         Result = AR;
448f4a2713aSLionel Sambuc         if (Message)
449f4a2713aSLionel Sambuc           ResultMessage.swap(*Message);
450f4a2713aSLionel Sambuc       }
451f4a2713aSLionel Sambuc       continue;
452f4a2713aSLionel Sambuc     }
453f4a2713aSLionel Sambuc   }
454f4a2713aSLionel Sambuc 
455f4a2713aSLionel Sambuc   if (Message)
456f4a2713aSLionel Sambuc     Message->swap(ResultMessage);
457f4a2713aSLionel Sambuc   return Result;
458f4a2713aSLionel Sambuc }
459f4a2713aSLionel Sambuc 
canBeWeakImported(bool & IsDefinition) const460f4a2713aSLionel Sambuc bool Decl::canBeWeakImported(bool &IsDefinition) const {
461f4a2713aSLionel Sambuc   IsDefinition = false;
462f4a2713aSLionel Sambuc 
463f4a2713aSLionel Sambuc   // Variables, if they aren't definitions.
464f4a2713aSLionel Sambuc   if (const VarDecl *Var = dyn_cast<VarDecl>(this)) {
465f4a2713aSLionel Sambuc     if (Var->isThisDeclarationADefinition()) {
466f4a2713aSLionel Sambuc       IsDefinition = true;
467f4a2713aSLionel Sambuc       return false;
468f4a2713aSLionel Sambuc     }
469f4a2713aSLionel Sambuc     return true;
470f4a2713aSLionel Sambuc 
471f4a2713aSLionel Sambuc   // Functions, if they aren't definitions.
472f4a2713aSLionel Sambuc   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) {
473f4a2713aSLionel Sambuc     if (FD->hasBody()) {
474f4a2713aSLionel Sambuc       IsDefinition = true;
475f4a2713aSLionel Sambuc       return false;
476f4a2713aSLionel Sambuc     }
477f4a2713aSLionel Sambuc     return true;
478f4a2713aSLionel Sambuc 
479f4a2713aSLionel Sambuc   // Objective-C classes, if this is the non-fragile runtime.
480f4a2713aSLionel Sambuc   } else if (isa<ObjCInterfaceDecl>(this) &&
481f4a2713aSLionel Sambuc              getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {
482f4a2713aSLionel Sambuc     return true;
483f4a2713aSLionel Sambuc 
484f4a2713aSLionel Sambuc   // Nothing else.
485f4a2713aSLionel Sambuc   } else {
486f4a2713aSLionel Sambuc     return false;
487f4a2713aSLionel Sambuc   }
488f4a2713aSLionel Sambuc }
489f4a2713aSLionel Sambuc 
isWeakImported() const490f4a2713aSLionel Sambuc bool Decl::isWeakImported() const {
491f4a2713aSLionel Sambuc   bool IsDefinition;
492f4a2713aSLionel Sambuc   if (!canBeWeakImported(IsDefinition))
493f4a2713aSLionel Sambuc     return false;
494f4a2713aSLionel Sambuc 
495*0a6a1f1dSLionel Sambuc   for (const auto *A : attrs()) {
496*0a6a1f1dSLionel Sambuc     if (isa<WeakImportAttr>(A))
497f4a2713aSLionel Sambuc       return true;
498f4a2713aSLionel Sambuc 
499*0a6a1f1dSLionel Sambuc     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
500*0a6a1f1dSLionel Sambuc       if (CheckAvailability(getASTContext(), Availability,
501*0a6a1f1dSLionel Sambuc                             nullptr) == AR_NotYetIntroduced)
502f4a2713aSLionel Sambuc         return true;
503f4a2713aSLionel Sambuc     }
504f4a2713aSLionel Sambuc   }
505f4a2713aSLionel Sambuc 
506f4a2713aSLionel Sambuc   return false;
507f4a2713aSLionel Sambuc }
508f4a2713aSLionel Sambuc 
getIdentifierNamespaceForKind(Kind DeclKind)509f4a2713aSLionel Sambuc unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
510f4a2713aSLionel Sambuc   switch (DeclKind) {
511f4a2713aSLionel Sambuc     case Function:
512f4a2713aSLionel Sambuc     case CXXMethod:
513f4a2713aSLionel Sambuc     case CXXConstructor:
514f4a2713aSLionel Sambuc     case CXXDestructor:
515f4a2713aSLionel Sambuc     case CXXConversion:
516f4a2713aSLionel Sambuc     case EnumConstant:
517f4a2713aSLionel Sambuc     case Var:
518f4a2713aSLionel Sambuc     case ImplicitParam:
519f4a2713aSLionel Sambuc     case ParmVar:
520f4a2713aSLionel Sambuc     case NonTypeTemplateParm:
521f4a2713aSLionel Sambuc     case ObjCMethod:
522f4a2713aSLionel Sambuc     case ObjCProperty:
523f4a2713aSLionel Sambuc     case MSProperty:
524f4a2713aSLionel Sambuc       return IDNS_Ordinary;
525f4a2713aSLionel Sambuc     case Label:
526f4a2713aSLionel Sambuc       return IDNS_Label;
527f4a2713aSLionel Sambuc     case IndirectField:
528f4a2713aSLionel Sambuc       return IDNS_Ordinary | IDNS_Member;
529f4a2713aSLionel Sambuc 
530f4a2713aSLionel Sambuc     case ObjCCompatibleAlias:
531f4a2713aSLionel Sambuc     case ObjCInterface:
532f4a2713aSLionel Sambuc       return IDNS_Ordinary | IDNS_Type;
533f4a2713aSLionel Sambuc 
534f4a2713aSLionel Sambuc     case Typedef:
535f4a2713aSLionel Sambuc     case TypeAlias:
536f4a2713aSLionel Sambuc     case TypeAliasTemplate:
537f4a2713aSLionel Sambuc     case UnresolvedUsingTypename:
538f4a2713aSLionel Sambuc     case TemplateTypeParm:
539f4a2713aSLionel Sambuc       return IDNS_Ordinary | IDNS_Type;
540f4a2713aSLionel Sambuc 
541f4a2713aSLionel Sambuc     case UsingShadow:
542f4a2713aSLionel Sambuc       return 0; // we'll actually overwrite this later
543f4a2713aSLionel Sambuc 
544f4a2713aSLionel Sambuc     case UnresolvedUsingValue:
545f4a2713aSLionel Sambuc       return IDNS_Ordinary | IDNS_Using;
546f4a2713aSLionel Sambuc 
547f4a2713aSLionel Sambuc     case Using:
548f4a2713aSLionel Sambuc       return IDNS_Using;
549f4a2713aSLionel Sambuc 
550f4a2713aSLionel Sambuc     case ObjCProtocol:
551f4a2713aSLionel Sambuc       return IDNS_ObjCProtocol;
552f4a2713aSLionel Sambuc 
553f4a2713aSLionel Sambuc     case Field:
554f4a2713aSLionel Sambuc     case ObjCAtDefsField:
555f4a2713aSLionel Sambuc     case ObjCIvar:
556f4a2713aSLionel Sambuc       return IDNS_Member;
557f4a2713aSLionel Sambuc 
558f4a2713aSLionel Sambuc     case Record:
559f4a2713aSLionel Sambuc     case CXXRecord:
560f4a2713aSLionel Sambuc     case Enum:
561f4a2713aSLionel Sambuc       return IDNS_Tag | IDNS_Type;
562f4a2713aSLionel Sambuc 
563f4a2713aSLionel Sambuc     case Namespace:
564f4a2713aSLionel Sambuc     case NamespaceAlias:
565f4a2713aSLionel Sambuc       return IDNS_Namespace;
566f4a2713aSLionel Sambuc 
567f4a2713aSLionel Sambuc     case FunctionTemplate:
568f4a2713aSLionel Sambuc     case VarTemplate:
569f4a2713aSLionel Sambuc       return IDNS_Ordinary;
570f4a2713aSLionel Sambuc 
571f4a2713aSLionel Sambuc     case ClassTemplate:
572f4a2713aSLionel Sambuc     case TemplateTemplateParm:
573f4a2713aSLionel Sambuc       return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
574f4a2713aSLionel Sambuc 
575f4a2713aSLionel Sambuc     // Never have names.
576f4a2713aSLionel Sambuc     case Friend:
577f4a2713aSLionel Sambuc     case FriendTemplate:
578f4a2713aSLionel Sambuc     case AccessSpec:
579f4a2713aSLionel Sambuc     case LinkageSpec:
580f4a2713aSLionel Sambuc     case FileScopeAsm:
581f4a2713aSLionel Sambuc     case StaticAssert:
582f4a2713aSLionel Sambuc     case ObjCPropertyImpl:
583f4a2713aSLionel Sambuc     case Block:
584f4a2713aSLionel Sambuc     case Captured:
585f4a2713aSLionel Sambuc     case TranslationUnit:
586f4a2713aSLionel Sambuc 
587f4a2713aSLionel Sambuc     case UsingDirective:
588f4a2713aSLionel Sambuc     case ClassTemplateSpecialization:
589f4a2713aSLionel Sambuc     case ClassTemplatePartialSpecialization:
590f4a2713aSLionel Sambuc     case ClassScopeFunctionSpecialization:
591f4a2713aSLionel Sambuc     case VarTemplateSpecialization:
592f4a2713aSLionel Sambuc     case VarTemplatePartialSpecialization:
593f4a2713aSLionel Sambuc     case ObjCImplementation:
594f4a2713aSLionel Sambuc     case ObjCCategory:
595f4a2713aSLionel Sambuc     case ObjCCategoryImpl:
596f4a2713aSLionel Sambuc     case Import:
597f4a2713aSLionel Sambuc     case OMPThreadPrivate:
598f4a2713aSLionel Sambuc     case Empty:
599f4a2713aSLionel Sambuc       // Never looked up by name.
600f4a2713aSLionel Sambuc       return 0;
601f4a2713aSLionel Sambuc   }
602f4a2713aSLionel Sambuc 
603f4a2713aSLionel Sambuc   llvm_unreachable("Invalid DeclKind!");
604f4a2713aSLionel Sambuc }
605f4a2713aSLionel Sambuc 
setAttrsImpl(const AttrVec & attrs,ASTContext & Ctx)606f4a2713aSLionel Sambuc void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
607f4a2713aSLionel Sambuc   assert(!HasAttrs && "Decl already contains attrs.");
608f4a2713aSLionel Sambuc 
609f4a2713aSLionel Sambuc   AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
610f4a2713aSLionel Sambuc   assert(AttrBlank.empty() && "HasAttrs was wrong?");
611f4a2713aSLionel Sambuc 
612f4a2713aSLionel Sambuc   AttrBlank = attrs;
613f4a2713aSLionel Sambuc   HasAttrs = true;
614f4a2713aSLionel Sambuc }
615f4a2713aSLionel Sambuc 
dropAttrs()616f4a2713aSLionel Sambuc void Decl::dropAttrs() {
617f4a2713aSLionel Sambuc   if (!HasAttrs) return;
618f4a2713aSLionel Sambuc 
619f4a2713aSLionel Sambuc   HasAttrs = false;
620f4a2713aSLionel Sambuc   getASTContext().eraseDeclAttrs(this);
621f4a2713aSLionel Sambuc }
622f4a2713aSLionel Sambuc 
getAttrs() const623f4a2713aSLionel Sambuc const AttrVec &Decl::getAttrs() const {
624f4a2713aSLionel Sambuc   assert(HasAttrs && "No attrs to get!");
625f4a2713aSLionel Sambuc   return getASTContext().getDeclAttrs(this);
626f4a2713aSLionel Sambuc }
627f4a2713aSLionel Sambuc 
castFromDeclContext(const DeclContext * D)628f4a2713aSLionel Sambuc Decl *Decl::castFromDeclContext (const DeclContext *D) {
629f4a2713aSLionel Sambuc   Decl::Kind DK = D->getDeclKind();
630f4a2713aSLionel Sambuc   switch(DK) {
631f4a2713aSLionel Sambuc #define DECL(NAME, BASE)
632f4a2713aSLionel Sambuc #define DECL_CONTEXT(NAME) \
633f4a2713aSLionel Sambuc     case Decl::NAME:       \
634f4a2713aSLionel Sambuc       return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D));
635f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME)
636f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
637f4a2713aSLionel Sambuc     default:
638f4a2713aSLionel Sambuc #define DECL(NAME, BASE)
639f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME)                  \
640f4a2713aSLionel Sambuc       if (DK >= first##NAME && DK <= last##NAME) \
641f4a2713aSLionel Sambuc         return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D));
642f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
643f4a2713aSLionel Sambuc       llvm_unreachable("a decl that inherits DeclContext isn't handled");
644f4a2713aSLionel Sambuc   }
645f4a2713aSLionel Sambuc }
646f4a2713aSLionel Sambuc 
castToDeclContext(const Decl * D)647f4a2713aSLionel Sambuc DeclContext *Decl::castToDeclContext(const Decl *D) {
648f4a2713aSLionel Sambuc   Decl::Kind DK = D->getKind();
649f4a2713aSLionel Sambuc   switch(DK) {
650f4a2713aSLionel Sambuc #define DECL(NAME, BASE)
651f4a2713aSLionel Sambuc #define DECL_CONTEXT(NAME) \
652f4a2713aSLionel Sambuc     case Decl::NAME:       \
653f4a2713aSLionel Sambuc       return static_cast<NAME##Decl*>(const_cast<Decl*>(D));
654f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME)
655f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
656f4a2713aSLionel Sambuc     default:
657f4a2713aSLionel Sambuc #define DECL(NAME, BASE)
658f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME)                                   \
659f4a2713aSLionel Sambuc       if (DK >= first##NAME && DK <= last##NAME)                  \
660f4a2713aSLionel Sambuc         return static_cast<NAME##Decl*>(const_cast<Decl*>(D));
661f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
662f4a2713aSLionel Sambuc       llvm_unreachable("a decl that inherits DeclContext isn't handled");
663f4a2713aSLionel Sambuc   }
664f4a2713aSLionel Sambuc }
665f4a2713aSLionel Sambuc 
getBodyRBrace() const666f4a2713aSLionel Sambuc SourceLocation Decl::getBodyRBrace() const {
667f4a2713aSLionel Sambuc   // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
668f4a2713aSLionel Sambuc   // FunctionDecl stores EndRangeLoc for this purpose.
669f4a2713aSLionel Sambuc   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) {
670f4a2713aSLionel Sambuc     const FunctionDecl *Definition;
671f4a2713aSLionel Sambuc     if (FD->hasBody(Definition))
672f4a2713aSLionel Sambuc       return Definition->getSourceRange().getEnd();
673f4a2713aSLionel Sambuc     return SourceLocation();
674f4a2713aSLionel Sambuc   }
675f4a2713aSLionel Sambuc 
676f4a2713aSLionel Sambuc   if (Stmt *Body = getBody())
677f4a2713aSLionel Sambuc     return Body->getSourceRange().getEnd();
678f4a2713aSLionel Sambuc 
679f4a2713aSLionel Sambuc   return SourceLocation();
680f4a2713aSLionel Sambuc }
681f4a2713aSLionel Sambuc 
AccessDeclContextSanity() const682*0a6a1f1dSLionel Sambuc bool Decl::AccessDeclContextSanity() const {
683f4a2713aSLionel Sambuc #ifndef NDEBUG
684f4a2713aSLionel Sambuc   // Suppress this check if any of the following hold:
685f4a2713aSLionel Sambuc   // 1. this is the translation unit (and thus has no parent)
686f4a2713aSLionel Sambuc   // 2. this is a template parameter (and thus doesn't belong to its context)
687f4a2713aSLionel Sambuc   // 3. this is a non-type template parameter
688f4a2713aSLionel Sambuc   // 4. the context is not a record
689f4a2713aSLionel Sambuc   // 5. it's invalid
690f4a2713aSLionel Sambuc   // 6. it's a C++0x static_assert.
691f4a2713aSLionel Sambuc   if (isa<TranslationUnitDecl>(this) ||
692f4a2713aSLionel Sambuc       isa<TemplateTypeParmDecl>(this) ||
693f4a2713aSLionel Sambuc       isa<NonTypeTemplateParmDecl>(this) ||
694f4a2713aSLionel Sambuc       !isa<CXXRecordDecl>(getDeclContext()) ||
695f4a2713aSLionel Sambuc       isInvalidDecl() ||
696f4a2713aSLionel Sambuc       isa<StaticAssertDecl>(this) ||
697f4a2713aSLionel Sambuc       // FIXME: a ParmVarDecl can have ClassTemplateSpecialization
698f4a2713aSLionel Sambuc       // as DeclContext (?).
699f4a2713aSLionel Sambuc       isa<ParmVarDecl>(this) ||
700f4a2713aSLionel Sambuc       // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have
701f4a2713aSLionel Sambuc       // AS_none as access specifier.
702f4a2713aSLionel Sambuc       isa<CXXRecordDecl>(this) ||
703f4a2713aSLionel Sambuc       isa<ClassScopeFunctionSpecializationDecl>(this))
704*0a6a1f1dSLionel Sambuc     return true;
705f4a2713aSLionel Sambuc 
706f4a2713aSLionel Sambuc   assert(Access != AS_none &&
707f4a2713aSLionel Sambuc          "Access specifier is AS_none inside a record decl");
708f4a2713aSLionel Sambuc #endif
709*0a6a1f1dSLionel Sambuc   return true;
710f4a2713aSLionel Sambuc }
711f4a2713aSLionel Sambuc 
getKind(const Decl * D)712f4a2713aSLionel Sambuc static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
getKind(const DeclContext * DC)713f4a2713aSLionel Sambuc static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
714f4a2713aSLionel Sambuc 
getFunctionType(bool BlocksToo) const715*0a6a1f1dSLionel Sambuc const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
716*0a6a1f1dSLionel Sambuc   QualType Ty;
717*0a6a1f1dSLionel Sambuc   if (const ValueDecl *D = dyn_cast<ValueDecl>(this))
718*0a6a1f1dSLionel Sambuc     Ty = D->getType();
719*0a6a1f1dSLionel Sambuc   else if (const TypedefNameDecl *D = dyn_cast<TypedefNameDecl>(this))
720*0a6a1f1dSLionel Sambuc     Ty = D->getUnderlyingType();
721*0a6a1f1dSLionel Sambuc   else
722*0a6a1f1dSLionel Sambuc     return nullptr;
723*0a6a1f1dSLionel Sambuc 
724*0a6a1f1dSLionel Sambuc   if (Ty->isFunctionPointerType())
725*0a6a1f1dSLionel Sambuc     Ty = Ty->getAs<PointerType>()->getPointeeType();
726*0a6a1f1dSLionel Sambuc   else if (BlocksToo && Ty->isBlockPointerType())
727*0a6a1f1dSLionel Sambuc     Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
728*0a6a1f1dSLionel Sambuc 
729*0a6a1f1dSLionel Sambuc   return Ty->getAs<FunctionType>();
730*0a6a1f1dSLionel Sambuc }
731*0a6a1f1dSLionel Sambuc 
732*0a6a1f1dSLionel Sambuc 
733f4a2713aSLionel Sambuc /// Starting at a given context (a Decl or DeclContext), look for a
734f4a2713aSLionel Sambuc /// code context that is not a closure (a lambda, block, etc.).
getNonClosureContext(T * D)735f4a2713aSLionel Sambuc template <class T> static Decl *getNonClosureContext(T *D) {
736f4a2713aSLionel Sambuc   if (getKind(D) == Decl::CXXMethod) {
737f4a2713aSLionel Sambuc     CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
738f4a2713aSLionel Sambuc     if (MD->getOverloadedOperator() == OO_Call &&
739f4a2713aSLionel Sambuc         MD->getParent()->isLambda())
740f4a2713aSLionel Sambuc       return getNonClosureContext(MD->getParent()->getParent());
741f4a2713aSLionel Sambuc     return MD;
742f4a2713aSLionel Sambuc   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
743f4a2713aSLionel Sambuc     return FD;
744f4a2713aSLionel Sambuc   } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
745f4a2713aSLionel Sambuc     return MD;
746f4a2713aSLionel Sambuc   } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
747f4a2713aSLionel Sambuc     return getNonClosureContext(BD->getParent());
748f4a2713aSLionel Sambuc   } else if (CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
749f4a2713aSLionel Sambuc     return getNonClosureContext(CD->getParent());
750f4a2713aSLionel Sambuc   } else {
751*0a6a1f1dSLionel Sambuc     return nullptr;
752f4a2713aSLionel Sambuc   }
753f4a2713aSLionel Sambuc }
754f4a2713aSLionel Sambuc 
getNonClosureContext()755f4a2713aSLionel Sambuc Decl *Decl::getNonClosureContext() {
756f4a2713aSLionel Sambuc   return ::getNonClosureContext(this);
757f4a2713aSLionel Sambuc }
758f4a2713aSLionel Sambuc 
getNonClosureAncestor()759f4a2713aSLionel Sambuc Decl *DeclContext::getNonClosureAncestor() {
760f4a2713aSLionel Sambuc   return ::getNonClosureContext(this);
761f4a2713aSLionel Sambuc }
762f4a2713aSLionel Sambuc 
763f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
764f4a2713aSLionel Sambuc // DeclContext Implementation
765f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
766f4a2713aSLionel Sambuc 
classof(const Decl * D)767f4a2713aSLionel Sambuc bool DeclContext::classof(const Decl *D) {
768f4a2713aSLionel Sambuc   switch (D->getKind()) {
769f4a2713aSLionel Sambuc #define DECL(NAME, BASE)
770f4a2713aSLionel Sambuc #define DECL_CONTEXT(NAME) case Decl::NAME:
771f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME)
772f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
773f4a2713aSLionel Sambuc       return true;
774f4a2713aSLionel Sambuc     default:
775f4a2713aSLionel Sambuc #define DECL(NAME, BASE)
776f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME)                 \
777f4a2713aSLionel Sambuc       if (D->getKind() >= Decl::first##NAME &&  \
778f4a2713aSLionel Sambuc           D->getKind() <= Decl::last##NAME)     \
779f4a2713aSLionel Sambuc         return true;
780f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
781f4a2713aSLionel Sambuc       return false;
782f4a2713aSLionel Sambuc   }
783f4a2713aSLionel Sambuc }
784f4a2713aSLionel Sambuc 
~DeclContext()785f4a2713aSLionel Sambuc DeclContext::~DeclContext() { }
786f4a2713aSLionel Sambuc 
787f4a2713aSLionel Sambuc /// \brief Find the parent context of this context that will be
788f4a2713aSLionel Sambuc /// used for unqualified name lookup.
789f4a2713aSLionel Sambuc ///
790f4a2713aSLionel Sambuc /// Generally, the parent lookup context is the semantic context. However, for
791f4a2713aSLionel Sambuc /// a friend function the parent lookup context is the lexical context, which
792f4a2713aSLionel Sambuc /// is the class in which the friend is declared.
getLookupParent()793f4a2713aSLionel Sambuc DeclContext *DeclContext::getLookupParent() {
794f4a2713aSLionel Sambuc   // FIXME: Find a better way to identify friends
795f4a2713aSLionel Sambuc   if (isa<FunctionDecl>(this))
796f4a2713aSLionel Sambuc     if (getParent()->getRedeclContext()->isFileContext() &&
797f4a2713aSLionel Sambuc         getLexicalParent()->getRedeclContext()->isRecord())
798f4a2713aSLionel Sambuc       return getLexicalParent();
799f4a2713aSLionel Sambuc 
800f4a2713aSLionel Sambuc   return getParent();
801f4a2713aSLionel Sambuc }
802f4a2713aSLionel Sambuc 
isInlineNamespace() const803f4a2713aSLionel Sambuc bool DeclContext::isInlineNamespace() const {
804f4a2713aSLionel Sambuc   return isNamespace() &&
805f4a2713aSLionel Sambuc          cast<NamespaceDecl>(this)->isInline();
806f4a2713aSLionel Sambuc }
807f4a2713aSLionel Sambuc 
isStdNamespace() const808*0a6a1f1dSLionel Sambuc bool DeclContext::isStdNamespace() const {
809*0a6a1f1dSLionel Sambuc   if (!isNamespace())
810*0a6a1f1dSLionel Sambuc     return false;
811*0a6a1f1dSLionel Sambuc 
812*0a6a1f1dSLionel Sambuc   const NamespaceDecl *ND = cast<NamespaceDecl>(this);
813*0a6a1f1dSLionel Sambuc   if (ND->isInline()) {
814*0a6a1f1dSLionel Sambuc     return ND->getParent()->isStdNamespace();
815*0a6a1f1dSLionel Sambuc   }
816*0a6a1f1dSLionel Sambuc 
817*0a6a1f1dSLionel Sambuc   if (!getParent()->getRedeclContext()->isTranslationUnit())
818*0a6a1f1dSLionel Sambuc     return false;
819*0a6a1f1dSLionel Sambuc 
820*0a6a1f1dSLionel Sambuc   const IdentifierInfo *II = ND->getIdentifier();
821*0a6a1f1dSLionel Sambuc   return II && II->isStr("std");
822*0a6a1f1dSLionel Sambuc }
823*0a6a1f1dSLionel Sambuc 
isDependentContext() const824f4a2713aSLionel Sambuc bool DeclContext::isDependentContext() const {
825f4a2713aSLionel Sambuc   if (isFileContext())
826f4a2713aSLionel Sambuc     return false;
827f4a2713aSLionel Sambuc 
828f4a2713aSLionel Sambuc   if (isa<ClassTemplatePartialSpecializationDecl>(this))
829f4a2713aSLionel Sambuc     return true;
830f4a2713aSLionel Sambuc 
831f4a2713aSLionel Sambuc   if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) {
832f4a2713aSLionel Sambuc     if (Record->getDescribedClassTemplate())
833f4a2713aSLionel Sambuc       return true;
834f4a2713aSLionel Sambuc 
835f4a2713aSLionel Sambuc     if (Record->isDependentLambda())
836f4a2713aSLionel Sambuc       return true;
837f4a2713aSLionel Sambuc   }
838f4a2713aSLionel Sambuc 
839f4a2713aSLionel Sambuc   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) {
840f4a2713aSLionel Sambuc     if (Function->getDescribedFunctionTemplate())
841f4a2713aSLionel Sambuc       return true;
842f4a2713aSLionel Sambuc 
843f4a2713aSLionel Sambuc     // Friend function declarations are dependent if their *lexical*
844f4a2713aSLionel Sambuc     // context is dependent.
845f4a2713aSLionel Sambuc     if (cast<Decl>(this)->getFriendObjectKind())
846f4a2713aSLionel Sambuc       return getLexicalParent()->isDependentContext();
847f4a2713aSLionel Sambuc   }
848f4a2713aSLionel Sambuc 
849f4a2713aSLionel Sambuc   return getParent() && getParent()->isDependentContext();
850f4a2713aSLionel Sambuc }
851f4a2713aSLionel Sambuc 
isTransparentContext() const852f4a2713aSLionel Sambuc bool DeclContext::isTransparentContext() const {
853f4a2713aSLionel Sambuc   if (DeclKind == Decl::Enum)
854f4a2713aSLionel Sambuc     return !cast<EnumDecl>(this)->isScoped();
855f4a2713aSLionel Sambuc   else if (DeclKind == Decl::LinkageSpec)
856f4a2713aSLionel Sambuc     return true;
857f4a2713aSLionel Sambuc 
858f4a2713aSLionel Sambuc   return false;
859f4a2713aSLionel Sambuc }
860f4a2713aSLionel Sambuc 
isLinkageSpecContext(const DeclContext * DC,LinkageSpecDecl::LanguageIDs ID)861f4a2713aSLionel Sambuc static bool isLinkageSpecContext(const DeclContext *DC,
862f4a2713aSLionel Sambuc                                  LinkageSpecDecl::LanguageIDs ID) {
863f4a2713aSLionel Sambuc   while (DC->getDeclKind() != Decl::TranslationUnit) {
864f4a2713aSLionel Sambuc     if (DC->getDeclKind() == Decl::LinkageSpec)
865f4a2713aSLionel Sambuc       return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
866*0a6a1f1dSLionel Sambuc     DC = DC->getLexicalParent();
867f4a2713aSLionel Sambuc   }
868f4a2713aSLionel Sambuc   return false;
869f4a2713aSLionel Sambuc }
870f4a2713aSLionel Sambuc 
isExternCContext() const871f4a2713aSLionel Sambuc bool DeclContext::isExternCContext() const {
872f4a2713aSLionel Sambuc   return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_c);
873f4a2713aSLionel Sambuc }
874f4a2713aSLionel Sambuc 
isExternCXXContext() const875f4a2713aSLionel Sambuc bool DeclContext::isExternCXXContext() const {
876f4a2713aSLionel Sambuc   return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_cxx);
877f4a2713aSLionel Sambuc }
878f4a2713aSLionel Sambuc 
Encloses(const DeclContext * DC) const879f4a2713aSLionel Sambuc bool DeclContext::Encloses(const DeclContext *DC) const {
880f4a2713aSLionel Sambuc   if (getPrimaryContext() != this)
881f4a2713aSLionel Sambuc     return getPrimaryContext()->Encloses(DC);
882f4a2713aSLionel Sambuc 
883f4a2713aSLionel Sambuc   for (; DC; DC = DC->getParent())
884f4a2713aSLionel Sambuc     if (DC->getPrimaryContext() == this)
885f4a2713aSLionel Sambuc       return true;
886f4a2713aSLionel Sambuc   return false;
887f4a2713aSLionel Sambuc }
888f4a2713aSLionel Sambuc 
getPrimaryContext()889f4a2713aSLionel Sambuc DeclContext *DeclContext::getPrimaryContext() {
890f4a2713aSLionel Sambuc   switch (DeclKind) {
891f4a2713aSLionel Sambuc   case Decl::TranslationUnit:
892f4a2713aSLionel Sambuc   case Decl::LinkageSpec:
893f4a2713aSLionel Sambuc   case Decl::Block:
894f4a2713aSLionel Sambuc   case Decl::Captured:
895f4a2713aSLionel Sambuc     // There is only one DeclContext for these entities.
896f4a2713aSLionel Sambuc     return this;
897f4a2713aSLionel Sambuc 
898f4a2713aSLionel Sambuc   case Decl::Namespace:
899f4a2713aSLionel Sambuc     // The original namespace is our primary context.
900f4a2713aSLionel Sambuc     return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
901f4a2713aSLionel Sambuc 
902f4a2713aSLionel Sambuc   case Decl::ObjCMethod:
903f4a2713aSLionel Sambuc     return this;
904f4a2713aSLionel Sambuc 
905f4a2713aSLionel Sambuc   case Decl::ObjCInterface:
906f4a2713aSLionel Sambuc     if (ObjCInterfaceDecl *Def = cast<ObjCInterfaceDecl>(this)->getDefinition())
907f4a2713aSLionel Sambuc       return Def;
908f4a2713aSLionel Sambuc 
909f4a2713aSLionel Sambuc     return this;
910f4a2713aSLionel Sambuc 
911f4a2713aSLionel Sambuc   case Decl::ObjCProtocol:
912f4a2713aSLionel Sambuc     if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(this)->getDefinition())
913f4a2713aSLionel Sambuc       return Def;
914f4a2713aSLionel Sambuc 
915f4a2713aSLionel Sambuc     return this;
916f4a2713aSLionel Sambuc 
917f4a2713aSLionel Sambuc   case Decl::ObjCCategory:
918f4a2713aSLionel Sambuc     return this;
919f4a2713aSLionel Sambuc 
920f4a2713aSLionel Sambuc   case Decl::ObjCImplementation:
921f4a2713aSLionel Sambuc   case Decl::ObjCCategoryImpl:
922f4a2713aSLionel Sambuc     return this;
923f4a2713aSLionel Sambuc 
924f4a2713aSLionel Sambuc   default:
925f4a2713aSLionel Sambuc     if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) {
926f4a2713aSLionel Sambuc       // If this is a tag type that has a definition or is currently
927f4a2713aSLionel Sambuc       // being defined, that definition is our primary context.
928f4a2713aSLionel Sambuc       TagDecl *Tag = cast<TagDecl>(this);
929f4a2713aSLionel Sambuc 
930f4a2713aSLionel Sambuc       if (TagDecl *Def = Tag->getDefinition())
931f4a2713aSLionel Sambuc         return Def;
932f4a2713aSLionel Sambuc 
933*0a6a1f1dSLionel Sambuc       if (const TagType *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
934*0a6a1f1dSLionel Sambuc         // Note, TagType::getDecl returns the (partial) definition one exists.
935*0a6a1f1dSLionel Sambuc         TagDecl *PossiblePartialDef = TagTy->getDecl();
936*0a6a1f1dSLionel Sambuc         if (PossiblePartialDef->isBeingDefined())
937*0a6a1f1dSLionel Sambuc           return PossiblePartialDef;
938*0a6a1f1dSLionel Sambuc       } else {
939*0a6a1f1dSLionel Sambuc         assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
940f4a2713aSLionel Sambuc       }
941f4a2713aSLionel Sambuc 
942f4a2713aSLionel Sambuc       return Tag;
943f4a2713aSLionel Sambuc     }
944f4a2713aSLionel Sambuc 
945f4a2713aSLionel Sambuc     assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction &&
946f4a2713aSLionel Sambuc           "Unknown DeclContext kind");
947f4a2713aSLionel Sambuc     return this;
948f4a2713aSLionel Sambuc   }
949f4a2713aSLionel Sambuc }
950f4a2713aSLionel Sambuc 
951f4a2713aSLionel Sambuc void
collectAllContexts(SmallVectorImpl<DeclContext * > & Contexts)952f4a2713aSLionel Sambuc DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts){
953f4a2713aSLionel Sambuc   Contexts.clear();
954f4a2713aSLionel Sambuc 
955f4a2713aSLionel Sambuc   if (DeclKind != Decl::Namespace) {
956f4a2713aSLionel Sambuc     Contexts.push_back(this);
957f4a2713aSLionel Sambuc     return;
958f4a2713aSLionel Sambuc   }
959f4a2713aSLionel Sambuc 
960f4a2713aSLionel Sambuc   NamespaceDecl *Self = static_cast<NamespaceDecl *>(this);
961f4a2713aSLionel Sambuc   for (NamespaceDecl *N = Self->getMostRecentDecl(); N;
962f4a2713aSLionel Sambuc        N = N->getPreviousDecl())
963f4a2713aSLionel Sambuc     Contexts.push_back(N);
964f4a2713aSLionel Sambuc 
965f4a2713aSLionel Sambuc   std::reverse(Contexts.begin(), Contexts.end());
966f4a2713aSLionel Sambuc }
967f4a2713aSLionel Sambuc 
968f4a2713aSLionel Sambuc std::pair<Decl *, Decl *>
BuildDeclChain(ArrayRef<Decl * > Decls,bool FieldsAlreadyLoaded)969f4a2713aSLionel Sambuc DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls,
970f4a2713aSLionel Sambuc                             bool FieldsAlreadyLoaded) {
971f4a2713aSLionel Sambuc   // Build up a chain of declarations via the Decl::NextInContextAndBits field.
972*0a6a1f1dSLionel Sambuc   Decl *FirstNewDecl = nullptr;
973*0a6a1f1dSLionel Sambuc   Decl *PrevDecl = nullptr;
974f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
975f4a2713aSLionel Sambuc     if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I]))
976f4a2713aSLionel Sambuc       continue;
977f4a2713aSLionel Sambuc 
978f4a2713aSLionel Sambuc     Decl *D = Decls[I];
979f4a2713aSLionel Sambuc     if (PrevDecl)
980f4a2713aSLionel Sambuc       PrevDecl->NextInContextAndBits.setPointer(D);
981f4a2713aSLionel Sambuc     else
982f4a2713aSLionel Sambuc       FirstNewDecl = D;
983f4a2713aSLionel Sambuc 
984f4a2713aSLionel Sambuc     PrevDecl = D;
985f4a2713aSLionel Sambuc   }
986f4a2713aSLionel Sambuc 
987f4a2713aSLionel Sambuc   return std::make_pair(FirstNewDecl, PrevDecl);
988f4a2713aSLionel Sambuc }
989f4a2713aSLionel Sambuc 
990f4a2713aSLionel Sambuc /// \brief We have just acquired external visible storage, and we already have
991f4a2713aSLionel Sambuc /// built a lookup map. For every name in the map, pull in the new names from
992f4a2713aSLionel Sambuc /// the external storage.
reconcileExternalVisibleStorage() const993*0a6a1f1dSLionel Sambuc void DeclContext::reconcileExternalVisibleStorage() const {
994f4a2713aSLionel Sambuc   assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer());
995f4a2713aSLionel Sambuc   NeedToReconcileExternalVisibleStorage = false;
996f4a2713aSLionel Sambuc 
997*0a6a1f1dSLionel Sambuc   for (auto &Lookup : *LookupPtr.getPointer())
998*0a6a1f1dSLionel Sambuc     Lookup.second.setHasExternalDecls();
999f4a2713aSLionel Sambuc }
1000f4a2713aSLionel Sambuc 
1001f4a2713aSLionel Sambuc /// \brief Load the declarations within this lexical storage from an
1002f4a2713aSLionel Sambuc /// external source.
1003f4a2713aSLionel Sambuc void
LoadLexicalDeclsFromExternalStorage() const1004f4a2713aSLionel Sambuc DeclContext::LoadLexicalDeclsFromExternalStorage() const {
1005f4a2713aSLionel Sambuc   ExternalASTSource *Source = getParentASTContext().getExternalSource();
1006f4a2713aSLionel Sambuc   assert(hasExternalLexicalStorage() && Source && "No external storage?");
1007f4a2713aSLionel Sambuc 
1008f4a2713aSLionel Sambuc   // Notify that we have a DeclContext that is initializing.
1009f4a2713aSLionel Sambuc   ExternalASTSource::Deserializing ADeclContext(Source);
1010f4a2713aSLionel Sambuc 
1011f4a2713aSLionel Sambuc   // Load the external declarations, if any.
1012f4a2713aSLionel Sambuc   SmallVector<Decl*, 64> Decls;
1013f4a2713aSLionel Sambuc   ExternalLexicalStorage = false;
1014f4a2713aSLionel Sambuc   switch (Source->FindExternalLexicalDecls(this, Decls)) {
1015f4a2713aSLionel Sambuc   case ELR_Success:
1016f4a2713aSLionel Sambuc     break;
1017f4a2713aSLionel Sambuc 
1018f4a2713aSLionel Sambuc   case ELR_Failure:
1019f4a2713aSLionel Sambuc   case ELR_AlreadyLoaded:
1020f4a2713aSLionel Sambuc     return;
1021f4a2713aSLionel Sambuc   }
1022f4a2713aSLionel Sambuc 
1023f4a2713aSLionel Sambuc   if (Decls.empty())
1024f4a2713aSLionel Sambuc     return;
1025f4a2713aSLionel Sambuc 
1026f4a2713aSLionel Sambuc   // We may have already loaded just the fields of this record, in which case
1027f4a2713aSLionel Sambuc   // we need to ignore them.
1028f4a2713aSLionel Sambuc   bool FieldsAlreadyLoaded = false;
1029f4a2713aSLionel Sambuc   if (const RecordDecl *RD = dyn_cast<RecordDecl>(this))
1030f4a2713aSLionel Sambuc     FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage;
1031f4a2713aSLionel Sambuc 
1032f4a2713aSLionel Sambuc   // Splice the newly-read declarations into the beginning of the list
1033f4a2713aSLionel Sambuc   // of declarations.
1034f4a2713aSLionel Sambuc   Decl *ExternalFirst, *ExternalLast;
1035*0a6a1f1dSLionel Sambuc   std::tie(ExternalFirst, ExternalLast) =
1036*0a6a1f1dSLionel Sambuc       BuildDeclChain(Decls, FieldsAlreadyLoaded);
1037f4a2713aSLionel Sambuc   ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
1038f4a2713aSLionel Sambuc   FirstDecl = ExternalFirst;
1039f4a2713aSLionel Sambuc   if (!LastDecl)
1040f4a2713aSLionel Sambuc     LastDecl = ExternalLast;
1041f4a2713aSLionel Sambuc }
1042f4a2713aSLionel Sambuc 
1043f4a2713aSLionel Sambuc DeclContext::lookup_result
SetNoExternalVisibleDeclsForName(const DeclContext * DC,DeclarationName Name)1044f4a2713aSLionel Sambuc ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
1045f4a2713aSLionel Sambuc                                                     DeclarationName Name) {
1046f4a2713aSLionel Sambuc   ASTContext &Context = DC->getParentASTContext();
1047f4a2713aSLionel Sambuc   StoredDeclsMap *Map;
1048f4a2713aSLionel Sambuc   if (!(Map = DC->LookupPtr.getPointer()))
1049f4a2713aSLionel Sambuc     Map = DC->CreateStoredDeclsMap(Context);
1050*0a6a1f1dSLionel Sambuc   if (DC->NeedToReconcileExternalVisibleStorage)
1051*0a6a1f1dSLionel Sambuc     DC->reconcileExternalVisibleStorage();
1052f4a2713aSLionel Sambuc 
1053f4a2713aSLionel Sambuc   (*Map)[Name].removeExternalDecls();
1054f4a2713aSLionel Sambuc 
1055f4a2713aSLionel Sambuc   return DeclContext::lookup_result();
1056f4a2713aSLionel Sambuc }
1057f4a2713aSLionel Sambuc 
1058f4a2713aSLionel Sambuc DeclContext::lookup_result
SetExternalVisibleDeclsForName(const DeclContext * DC,DeclarationName Name,ArrayRef<NamedDecl * > Decls)1059f4a2713aSLionel Sambuc ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
1060f4a2713aSLionel Sambuc                                                   DeclarationName Name,
1061f4a2713aSLionel Sambuc                                                   ArrayRef<NamedDecl*> Decls) {
1062f4a2713aSLionel Sambuc   ASTContext &Context = DC->getParentASTContext();
1063f4a2713aSLionel Sambuc   StoredDeclsMap *Map;
1064f4a2713aSLionel Sambuc   if (!(Map = DC->LookupPtr.getPointer()))
1065f4a2713aSLionel Sambuc     Map = DC->CreateStoredDeclsMap(Context);
1066*0a6a1f1dSLionel Sambuc   if (DC->NeedToReconcileExternalVisibleStorage)
1067*0a6a1f1dSLionel Sambuc     DC->reconcileExternalVisibleStorage();
1068f4a2713aSLionel Sambuc 
1069f4a2713aSLionel Sambuc   StoredDeclsList &List = (*Map)[Name];
1070f4a2713aSLionel Sambuc 
1071f4a2713aSLionel Sambuc   // Clear out any old external visible declarations, to avoid quadratic
1072f4a2713aSLionel Sambuc   // performance in the redeclaration checks below.
1073f4a2713aSLionel Sambuc   List.removeExternalDecls();
1074f4a2713aSLionel Sambuc 
1075f4a2713aSLionel Sambuc   if (!List.isNull()) {
1076f4a2713aSLionel Sambuc     // We have both existing declarations and new declarations for this name.
1077f4a2713aSLionel Sambuc     // Some of the declarations may simply replace existing ones. Handle those
1078f4a2713aSLionel Sambuc     // first.
1079f4a2713aSLionel Sambuc     llvm::SmallVector<unsigned, 8> Skip;
1080f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Decls.size(); I != N; ++I)
1081f4a2713aSLionel Sambuc       if (List.HandleRedeclaration(Decls[I]))
1082f4a2713aSLionel Sambuc         Skip.push_back(I);
1083f4a2713aSLionel Sambuc     Skip.push_back(Decls.size());
1084f4a2713aSLionel Sambuc 
1085f4a2713aSLionel Sambuc     // Add in any new declarations.
1086f4a2713aSLionel Sambuc     unsigned SkipPos = 0;
1087f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
1088f4a2713aSLionel Sambuc       if (I == Skip[SkipPos])
1089f4a2713aSLionel Sambuc         ++SkipPos;
1090f4a2713aSLionel Sambuc       else
1091f4a2713aSLionel Sambuc         List.AddSubsequentDecl(Decls[I]);
1092f4a2713aSLionel Sambuc     }
1093f4a2713aSLionel Sambuc   } else {
1094f4a2713aSLionel Sambuc     // Convert the array to a StoredDeclsList.
1095f4a2713aSLionel Sambuc     for (ArrayRef<NamedDecl*>::iterator
1096f4a2713aSLionel Sambuc            I = Decls.begin(), E = Decls.end(); I != E; ++I) {
1097f4a2713aSLionel Sambuc       if (List.isNull())
1098f4a2713aSLionel Sambuc         List.setOnlyValue(*I);
1099f4a2713aSLionel Sambuc       else
1100f4a2713aSLionel Sambuc         List.AddSubsequentDecl(*I);
1101f4a2713aSLionel Sambuc     }
1102f4a2713aSLionel Sambuc   }
1103f4a2713aSLionel Sambuc 
1104f4a2713aSLionel Sambuc   return List.getLookupResult();
1105f4a2713aSLionel Sambuc }
1106f4a2713aSLionel Sambuc 
decls_begin() const1107f4a2713aSLionel Sambuc DeclContext::decl_iterator DeclContext::decls_begin() const {
1108f4a2713aSLionel Sambuc   if (hasExternalLexicalStorage())
1109f4a2713aSLionel Sambuc     LoadLexicalDeclsFromExternalStorage();
1110f4a2713aSLionel Sambuc   return decl_iterator(FirstDecl);
1111f4a2713aSLionel Sambuc }
1112f4a2713aSLionel Sambuc 
decls_empty() const1113f4a2713aSLionel Sambuc bool DeclContext::decls_empty() const {
1114f4a2713aSLionel Sambuc   if (hasExternalLexicalStorage())
1115f4a2713aSLionel Sambuc     LoadLexicalDeclsFromExternalStorage();
1116f4a2713aSLionel Sambuc 
1117f4a2713aSLionel Sambuc   return !FirstDecl;
1118f4a2713aSLionel Sambuc }
1119f4a2713aSLionel Sambuc 
containsDecl(Decl * D) const1120f4a2713aSLionel Sambuc bool DeclContext::containsDecl(Decl *D) const {
1121f4a2713aSLionel Sambuc   return (D->getLexicalDeclContext() == this &&
1122f4a2713aSLionel Sambuc           (D->NextInContextAndBits.getPointer() || D == LastDecl));
1123f4a2713aSLionel Sambuc }
1124f4a2713aSLionel Sambuc 
removeDecl(Decl * D)1125f4a2713aSLionel Sambuc void DeclContext::removeDecl(Decl *D) {
1126f4a2713aSLionel Sambuc   assert(D->getLexicalDeclContext() == this &&
1127f4a2713aSLionel Sambuc          "decl being removed from non-lexical context");
1128f4a2713aSLionel Sambuc   assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
1129f4a2713aSLionel Sambuc          "decl is not in decls list");
1130f4a2713aSLionel Sambuc 
1131f4a2713aSLionel Sambuc   // Remove D from the decl chain.  This is O(n) but hopefully rare.
1132f4a2713aSLionel Sambuc   if (D == FirstDecl) {
1133f4a2713aSLionel Sambuc     if (D == LastDecl)
1134*0a6a1f1dSLionel Sambuc       FirstDecl = LastDecl = nullptr;
1135f4a2713aSLionel Sambuc     else
1136f4a2713aSLionel Sambuc       FirstDecl = D->NextInContextAndBits.getPointer();
1137f4a2713aSLionel Sambuc   } else {
1138f4a2713aSLionel Sambuc     for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {
1139f4a2713aSLionel Sambuc       assert(I && "decl not found in linked list");
1140f4a2713aSLionel Sambuc       if (I->NextInContextAndBits.getPointer() == D) {
1141f4a2713aSLionel Sambuc         I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
1142f4a2713aSLionel Sambuc         if (D == LastDecl) LastDecl = I;
1143f4a2713aSLionel Sambuc         break;
1144f4a2713aSLionel Sambuc       }
1145f4a2713aSLionel Sambuc     }
1146f4a2713aSLionel Sambuc   }
1147f4a2713aSLionel Sambuc 
1148f4a2713aSLionel Sambuc   // Mark that D is no longer in the decl chain.
1149*0a6a1f1dSLionel Sambuc   D->NextInContextAndBits.setPointer(nullptr);
1150f4a2713aSLionel Sambuc 
1151f4a2713aSLionel Sambuc   // Remove D from the lookup table if necessary.
1152f4a2713aSLionel Sambuc   if (isa<NamedDecl>(D)) {
1153f4a2713aSLionel Sambuc     NamedDecl *ND = cast<NamedDecl>(D);
1154f4a2713aSLionel Sambuc 
1155f4a2713aSLionel Sambuc     // Remove only decls that have a name
1156f4a2713aSLionel Sambuc     if (!ND->getDeclName()) return;
1157f4a2713aSLionel Sambuc 
1158f4a2713aSLionel Sambuc     StoredDeclsMap *Map = getPrimaryContext()->LookupPtr.getPointer();
1159f4a2713aSLionel Sambuc     if (!Map) return;
1160f4a2713aSLionel Sambuc 
1161f4a2713aSLionel Sambuc     StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1162f4a2713aSLionel Sambuc     assert(Pos != Map->end() && "no lookup entry for decl");
1163f4a2713aSLionel Sambuc     if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
1164f4a2713aSLionel Sambuc       Pos->second.remove(ND);
1165f4a2713aSLionel Sambuc   }
1166f4a2713aSLionel Sambuc }
1167f4a2713aSLionel Sambuc 
addHiddenDecl(Decl * D)1168f4a2713aSLionel Sambuc void DeclContext::addHiddenDecl(Decl *D) {
1169f4a2713aSLionel Sambuc   assert(D->getLexicalDeclContext() == this &&
1170f4a2713aSLionel Sambuc          "Decl inserted into wrong lexical context");
1171f4a2713aSLionel Sambuc   assert(!D->getNextDeclInContext() && D != LastDecl &&
1172f4a2713aSLionel Sambuc          "Decl already inserted into a DeclContext");
1173f4a2713aSLionel Sambuc 
1174f4a2713aSLionel Sambuc   if (FirstDecl) {
1175f4a2713aSLionel Sambuc     LastDecl->NextInContextAndBits.setPointer(D);
1176f4a2713aSLionel Sambuc     LastDecl = D;
1177f4a2713aSLionel Sambuc   } else {
1178f4a2713aSLionel Sambuc     FirstDecl = LastDecl = D;
1179f4a2713aSLionel Sambuc   }
1180f4a2713aSLionel Sambuc 
1181f4a2713aSLionel Sambuc   // Notify a C++ record declaration that we've added a member, so it can
1182f4a2713aSLionel Sambuc   // update it's class-specific state.
1183f4a2713aSLionel Sambuc   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
1184f4a2713aSLionel Sambuc     Record->addedMember(D);
1185f4a2713aSLionel Sambuc 
1186f4a2713aSLionel Sambuc   // If this is a newly-created (not de-serialized) import declaration, wire
1187f4a2713aSLionel Sambuc   // it in to the list of local import declarations.
1188f4a2713aSLionel Sambuc   if (!D->isFromASTFile()) {
1189f4a2713aSLionel Sambuc     if (ImportDecl *Import = dyn_cast<ImportDecl>(D))
1190f4a2713aSLionel Sambuc       D->getASTContext().addedLocalImportDecl(Import);
1191f4a2713aSLionel Sambuc   }
1192f4a2713aSLionel Sambuc }
1193f4a2713aSLionel Sambuc 
addDecl(Decl * D)1194f4a2713aSLionel Sambuc void DeclContext::addDecl(Decl *D) {
1195f4a2713aSLionel Sambuc   addHiddenDecl(D);
1196f4a2713aSLionel Sambuc 
1197f4a2713aSLionel Sambuc   if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
1198f4a2713aSLionel Sambuc     ND->getDeclContext()->getPrimaryContext()->
1199f4a2713aSLionel Sambuc         makeDeclVisibleInContextWithFlags(ND, false, true);
1200f4a2713aSLionel Sambuc }
1201f4a2713aSLionel Sambuc 
addDeclInternal(Decl * D)1202f4a2713aSLionel Sambuc void DeclContext::addDeclInternal(Decl *D) {
1203f4a2713aSLionel Sambuc   addHiddenDecl(D);
1204f4a2713aSLionel Sambuc 
1205f4a2713aSLionel Sambuc   if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
1206f4a2713aSLionel Sambuc     ND->getDeclContext()->getPrimaryContext()->
1207f4a2713aSLionel Sambuc         makeDeclVisibleInContextWithFlags(ND, true, true);
1208f4a2713aSLionel Sambuc }
1209f4a2713aSLionel Sambuc 
1210f4a2713aSLionel Sambuc /// shouldBeHidden - Determine whether a declaration which was declared
1211f4a2713aSLionel Sambuc /// within its semantic context should be invisible to qualified name lookup.
shouldBeHidden(NamedDecl * D)1212f4a2713aSLionel Sambuc static bool shouldBeHidden(NamedDecl *D) {
1213f4a2713aSLionel Sambuc   // Skip unnamed declarations.
1214f4a2713aSLionel Sambuc   if (!D->getDeclName())
1215f4a2713aSLionel Sambuc     return true;
1216f4a2713aSLionel Sambuc 
1217f4a2713aSLionel Sambuc   // Skip entities that can't be found by name lookup into a particular
1218f4a2713aSLionel Sambuc   // context.
1219f4a2713aSLionel Sambuc   if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
1220f4a2713aSLionel Sambuc       D->isTemplateParameter())
1221f4a2713aSLionel Sambuc     return true;
1222f4a2713aSLionel Sambuc 
1223f4a2713aSLionel Sambuc   // Skip template specializations.
1224f4a2713aSLionel Sambuc   // FIXME: This feels like a hack. Should DeclarationName support
1225f4a2713aSLionel Sambuc   // template-ids, or is there a better way to keep specializations
1226f4a2713aSLionel Sambuc   // from being visible?
1227f4a2713aSLionel Sambuc   if (isa<ClassTemplateSpecializationDecl>(D))
1228f4a2713aSLionel Sambuc     return true;
1229f4a2713aSLionel Sambuc   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1230f4a2713aSLionel Sambuc     if (FD->isFunctionTemplateSpecialization())
1231f4a2713aSLionel Sambuc       return true;
1232f4a2713aSLionel Sambuc 
1233f4a2713aSLionel Sambuc   return false;
1234f4a2713aSLionel Sambuc }
1235f4a2713aSLionel Sambuc 
1236f4a2713aSLionel Sambuc /// buildLookup - Build the lookup data structure with all of the
1237f4a2713aSLionel Sambuc /// declarations in this DeclContext (and any other contexts linked
1238f4a2713aSLionel Sambuc /// to it or transparent contexts nested within it) and return it.
1239*0a6a1f1dSLionel Sambuc ///
1240*0a6a1f1dSLionel Sambuc /// Note that the produced map may miss out declarations from an
1241*0a6a1f1dSLionel Sambuc /// external source. If it does, those entries will be marked with
1242*0a6a1f1dSLionel Sambuc /// the 'hasExternalDecls' flag.
buildLookup()1243f4a2713aSLionel Sambuc StoredDeclsMap *DeclContext::buildLookup() {
1244f4a2713aSLionel Sambuc   assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
1245f4a2713aSLionel Sambuc 
1246f4a2713aSLionel Sambuc   // FIXME: Should we keep going if hasExternalVisibleStorage?
1247f4a2713aSLionel Sambuc   if (!LookupPtr.getInt())
1248f4a2713aSLionel Sambuc     return LookupPtr.getPointer();
1249f4a2713aSLionel Sambuc 
1250f4a2713aSLionel Sambuc   SmallVector<DeclContext *, 2> Contexts;
1251f4a2713aSLionel Sambuc   collectAllContexts(Contexts);
1252f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Contexts.size(); I != N; ++I)
1253f4a2713aSLionel Sambuc     buildLookupImpl<&DeclContext::decls_begin,
1254f4a2713aSLionel Sambuc                     &DeclContext::decls_end>(Contexts[I]);
1255f4a2713aSLionel Sambuc 
1256f4a2713aSLionel Sambuc   // We no longer have any lazy decls.
1257f4a2713aSLionel Sambuc   LookupPtr.setInt(false);
1258f4a2713aSLionel Sambuc   return LookupPtr.getPointer();
1259f4a2713aSLionel Sambuc }
1260f4a2713aSLionel Sambuc 
1261f4a2713aSLionel Sambuc /// buildLookupImpl - Build part of the lookup data structure for the
1262f4a2713aSLionel Sambuc /// declarations contained within DCtx, which will either be this
1263f4a2713aSLionel Sambuc /// DeclContext, a DeclContext linked to it, or a transparent context
1264f4a2713aSLionel Sambuc /// nested within it.
1265f4a2713aSLionel Sambuc template<DeclContext::decl_iterator (DeclContext::*Begin)() const,
1266f4a2713aSLionel Sambuc          DeclContext::decl_iterator (DeclContext::*End)() const>
buildLookupImpl(DeclContext * DCtx)1267f4a2713aSLionel Sambuc void DeclContext::buildLookupImpl(DeclContext *DCtx) {
1268f4a2713aSLionel Sambuc   for (decl_iterator I = (DCtx->*Begin)(), E = (DCtx->*End)();
1269f4a2713aSLionel Sambuc        I != E; ++I) {
1270f4a2713aSLionel Sambuc     Decl *D = *I;
1271f4a2713aSLionel Sambuc 
1272f4a2713aSLionel Sambuc     // Insert this declaration into the lookup structure, but only if
1273f4a2713aSLionel Sambuc     // it's semantically within its decl context. Any other decls which
1274f4a2713aSLionel Sambuc     // should be found in this context are added eagerly.
1275f4a2713aSLionel Sambuc     //
1276f4a2713aSLionel Sambuc     // If it's from an AST file, don't add it now. It'll get handled by
1277f4a2713aSLionel Sambuc     // FindExternalVisibleDeclsByName if needed. Exception: if we're not
1278f4a2713aSLionel Sambuc     // in C++, we do not track external visible decls for the TU, so in
1279f4a2713aSLionel Sambuc     // that case we need to collect them all here.
1280f4a2713aSLionel Sambuc     if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
1281f4a2713aSLionel Sambuc       if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&
1282f4a2713aSLionel Sambuc           (!ND->isFromASTFile() ||
1283f4a2713aSLionel Sambuc            (isTranslationUnit() &&
1284f4a2713aSLionel Sambuc             !getParentASTContext().getLangOpts().CPlusPlus)))
1285f4a2713aSLionel Sambuc         makeDeclVisibleInContextImpl(ND, false);
1286f4a2713aSLionel Sambuc 
1287f4a2713aSLionel Sambuc     // If this declaration is itself a transparent declaration context
1288f4a2713aSLionel Sambuc     // or inline namespace, add the members of this declaration of that
1289f4a2713aSLionel Sambuc     // context (recursively).
1290f4a2713aSLionel Sambuc     if (DeclContext *InnerCtx = dyn_cast<DeclContext>(D))
1291f4a2713aSLionel Sambuc       if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1292f4a2713aSLionel Sambuc         buildLookupImpl<Begin, End>(InnerCtx);
1293f4a2713aSLionel Sambuc   }
1294f4a2713aSLionel Sambuc }
1295f4a2713aSLionel Sambuc 
1296f4a2713aSLionel Sambuc DeclContext::lookup_result
lookup(DeclarationName Name)1297f4a2713aSLionel Sambuc DeclContext::lookup(DeclarationName Name) {
1298f4a2713aSLionel Sambuc   assert(DeclKind != Decl::LinkageSpec &&
1299f4a2713aSLionel Sambuc          "Should not perform lookups into linkage specs!");
1300f4a2713aSLionel Sambuc 
1301f4a2713aSLionel Sambuc   DeclContext *PrimaryContext = getPrimaryContext();
1302f4a2713aSLionel Sambuc   if (PrimaryContext != this)
1303f4a2713aSLionel Sambuc     return PrimaryContext->lookup(Name);
1304f4a2713aSLionel Sambuc 
1305*0a6a1f1dSLionel Sambuc   // If this is a namespace, ensure that any later redeclarations of it have
1306*0a6a1f1dSLionel Sambuc   // been loaded, since they may add names to the result of this lookup.
1307*0a6a1f1dSLionel Sambuc   if (auto *ND = dyn_cast<NamespaceDecl>(this))
1308*0a6a1f1dSLionel Sambuc     (void)ND->getMostRecentDecl();
1309*0a6a1f1dSLionel Sambuc 
1310f4a2713aSLionel Sambuc   if (hasExternalVisibleStorage()) {
1311*0a6a1f1dSLionel Sambuc     if (NeedToReconcileExternalVisibleStorage)
1312*0a6a1f1dSLionel Sambuc       reconcileExternalVisibleStorage();
1313*0a6a1f1dSLionel Sambuc 
1314f4a2713aSLionel Sambuc     StoredDeclsMap *Map = LookupPtr.getPointer();
1315*0a6a1f1dSLionel Sambuc 
1316f4a2713aSLionel Sambuc     if (LookupPtr.getInt())
1317f4a2713aSLionel Sambuc       Map = buildLookup();
1318f4a2713aSLionel Sambuc 
1319f4a2713aSLionel Sambuc     if (!Map)
1320f4a2713aSLionel Sambuc       Map = CreateStoredDeclsMap(getParentASTContext());
1321f4a2713aSLionel Sambuc 
1322f4a2713aSLionel Sambuc     // If we have a lookup result with no external decls, we are done.
1323f4a2713aSLionel Sambuc     std::pair<StoredDeclsMap::iterator, bool> R =
1324f4a2713aSLionel Sambuc         Map->insert(std::make_pair(Name, StoredDeclsList()));
1325f4a2713aSLionel Sambuc     if (!R.second && !R.first->second.hasExternalDecls())
1326f4a2713aSLionel Sambuc       return R.first->second.getLookupResult();
1327f4a2713aSLionel Sambuc 
1328f4a2713aSLionel Sambuc     ExternalASTSource *Source = getParentASTContext().getExternalSource();
1329*0a6a1f1dSLionel Sambuc     if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
1330f4a2713aSLionel Sambuc       if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
1331f4a2713aSLionel Sambuc         StoredDeclsMap::iterator I = Map->find(Name);
1332f4a2713aSLionel Sambuc         if (I != Map->end())
1333f4a2713aSLionel Sambuc           return I->second.getLookupResult();
1334f4a2713aSLionel Sambuc       }
1335f4a2713aSLionel Sambuc     }
1336f4a2713aSLionel Sambuc 
1337*0a6a1f1dSLionel Sambuc     return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
1338f4a2713aSLionel Sambuc   }
1339f4a2713aSLionel Sambuc 
1340f4a2713aSLionel Sambuc   StoredDeclsMap *Map = LookupPtr.getPointer();
1341f4a2713aSLionel Sambuc   if (LookupPtr.getInt())
1342f4a2713aSLionel Sambuc     Map = buildLookup();
1343f4a2713aSLionel Sambuc 
1344f4a2713aSLionel Sambuc   if (!Map)
1345*0a6a1f1dSLionel Sambuc     return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
1346f4a2713aSLionel Sambuc 
1347f4a2713aSLionel Sambuc   StoredDeclsMap::iterator I = Map->find(Name);
1348f4a2713aSLionel Sambuc   if (I == Map->end())
1349*0a6a1f1dSLionel Sambuc     return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
1350f4a2713aSLionel Sambuc 
1351f4a2713aSLionel Sambuc   return I->second.getLookupResult();
1352f4a2713aSLionel Sambuc }
1353f4a2713aSLionel Sambuc 
1354f4a2713aSLionel Sambuc DeclContext::lookup_result
noload_lookup(DeclarationName Name)1355f4a2713aSLionel Sambuc DeclContext::noload_lookup(DeclarationName Name) {
1356f4a2713aSLionel Sambuc   assert(DeclKind != Decl::LinkageSpec &&
1357f4a2713aSLionel Sambuc          "Should not perform lookups into linkage specs!");
1358f4a2713aSLionel Sambuc   if (!hasExternalVisibleStorage())
1359f4a2713aSLionel Sambuc     return lookup(Name);
1360f4a2713aSLionel Sambuc 
1361f4a2713aSLionel Sambuc   DeclContext *PrimaryContext = getPrimaryContext();
1362f4a2713aSLionel Sambuc   if (PrimaryContext != this)
1363f4a2713aSLionel Sambuc     return PrimaryContext->noload_lookup(Name);
1364f4a2713aSLionel Sambuc 
1365f4a2713aSLionel Sambuc   StoredDeclsMap *Map = LookupPtr.getPointer();
1366f4a2713aSLionel Sambuc   if (LookupPtr.getInt()) {
1367f4a2713aSLionel Sambuc     // Carefully build the lookup map, without deserializing anything.
1368f4a2713aSLionel Sambuc     SmallVector<DeclContext *, 2> Contexts;
1369f4a2713aSLionel Sambuc     collectAllContexts(Contexts);
1370f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Contexts.size(); I != N; ++I)
1371f4a2713aSLionel Sambuc       buildLookupImpl<&DeclContext::noload_decls_begin,
1372f4a2713aSLionel Sambuc                       &DeclContext::noload_decls_end>(Contexts[I]);
1373f4a2713aSLionel Sambuc 
1374f4a2713aSLionel Sambuc     // We no longer have any lazy decls.
1375f4a2713aSLionel Sambuc     LookupPtr.setInt(false);
1376f4a2713aSLionel Sambuc 
1377f4a2713aSLionel Sambuc     // There may now be names for which we have local decls but are
1378f4a2713aSLionel Sambuc     // missing the external decls. FIXME: Just set the hasExternalDecls
1379f4a2713aSLionel Sambuc     // flag on those names that have external decls.
1380f4a2713aSLionel Sambuc     NeedToReconcileExternalVisibleStorage = true;
1381f4a2713aSLionel Sambuc 
1382f4a2713aSLionel Sambuc     Map = LookupPtr.getPointer();
1383f4a2713aSLionel Sambuc   }
1384f4a2713aSLionel Sambuc 
1385f4a2713aSLionel Sambuc   if (!Map)
1386*0a6a1f1dSLionel Sambuc     return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
1387f4a2713aSLionel Sambuc 
1388f4a2713aSLionel Sambuc   StoredDeclsMap::iterator I = Map->find(Name);
1389*0a6a1f1dSLionel Sambuc   return I != Map->end() ? I->second.getLookupResult()
1390*0a6a1f1dSLionel Sambuc                          : lookup_result(lookup_iterator(nullptr),
1391*0a6a1f1dSLionel Sambuc                                          lookup_iterator(nullptr));
1392f4a2713aSLionel Sambuc }
1393f4a2713aSLionel Sambuc 
localUncachedLookup(DeclarationName Name,SmallVectorImpl<NamedDecl * > & Results)1394f4a2713aSLionel Sambuc void DeclContext::localUncachedLookup(DeclarationName Name,
1395f4a2713aSLionel Sambuc                                       SmallVectorImpl<NamedDecl *> &Results) {
1396f4a2713aSLionel Sambuc   Results.clear();
1397f4a2713aSLionel Sambuc 
1398f4a2713aSLionel Sambuc   // If there's no external storage, just perform a normal lookup and copy
1399f4a2713aSLionel Sambuc   // the results.
1400f4a2713aSLionel Sambuc   if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
1401f4a2713aSLionel Sambuc     lookup_result LookupResults = lookup(Name);
1402f4a2713aSLionel Sambuc     Results.insert(Results.end(), LookupResults.begin(), LookupResults.end());
1403f4a2713aSLionel Sambuc     return;
1404f4a2713aSLionel Sambuc   }
1405f4a2713aSLionel Sambuc 
1406f4a2713aSLionel Sambuc   // If we have a lookup table, check there first. Maybe we'll get lucky.
1407f4a2713aSLionel Sambuc   if (Name && !LookupPtr.getInt()) {
1408f4a2713aSLionel Sambuc     if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
1409f4a2713aSLionel Sambuc       StoredDeclsMap::iterator Pos = Map->find(Name);
1410f4a2713aSLionel Sambuc       if (Pos != Map->end()) {
1411f4a2713aSLionel Sambuc         Results.insert(Results.end(),
1412f4a2713aSLionel Sambuc                        Pos->second.getLookupResult().begin(),
1413f4a2713aSLionel Sambuc                        Pos->second.getLookupResult().end());
1414f4a2713aSLionel Sambuc         return;
1415f4a2713aSLionel Sambuc       }
1416f4a2713aSLionel Sambuc     }
1417f4a2713aSLionel Sambuc   }
1418f4a2713aSLionel Sambuc 
1419f4a2713aSLionel Sambuc   // Slow case: grovel through the declarations in our chain looking for
1420f4a2713aSLionel Sambuc   // matches.
1421f4a2713aSLionel Sambuc   for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {
1422f4a2713aSLionel Sambuc     if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
1423f4a2713aSLionel Sambuc       if (ND->getDeclName() == Name)
1424f4a2713aSLionel Sambuc         Results.push_back(ND);
1425f4a2713aSLionel Sambuc   }
1426f4a2713aSLionel Sambuc }
1427f4a2713aSLionel Sambuc 
getRedeclContext()1428f4a2713aSLionel Sambuc DeclContext *DeclContext::getRedeclContext() {
1429f4a2713aSLionel Sambuc   DeclContext *Ctx = this;
1430f4a2713aSLionel Sambuc   // Skip through transparent contexts.
1431f4a2713aSLionel Sambuc   while (Ctx->isTransparentContext())
1432f4a2713aSLionel Sambuc     Ctx = Ctx->getParent();
1433f4a2713aSLionel Sambuc   return Ctx;
1434f4a2713aSLionel Sambuc }
1435f4a2713aSLionel Sambuc 
getEnclosingNamespaceContext()1436f4a2713aSLionel Sambuc DeclContext *DeclContext::getEnclosingNamespaceContext() {
1437f4a2713aSLionel Sambuc   DeclContext *Ctx = this;
1438f4a2713aSLionel Sambuc   // Skip through non-namespace, non-translation-unit contexts.
1439f4a2713aSLionel Sambuc   while (!Ctx->isFileContext())
1440f4a2713aSLionel Sambuc     Ctx = Ctx->getParent();
1441f4a2713aSLionel Sambuc   return Ctx->getPrimaryContext();
1442f4a2713aSLionel Sambuc }
1443f4a2713aSLionel Sambuc 
getOuterLexicalRecordContext()1444*0a6a1f1dSLionel Sambuc RecordDecl *DeclContext::getOuterLexicalRecordContext() {
1445*0a6a1f1dSLionel Sambuc   // Loop until we find a non-record context.
1446*0a6a1f1dSLionel Sambuc   RecordDecl *OutermostRD = nullptr;
1447*0a6a1f1dSLionel Sambuc   DeclContext *DC = this;
1448*0a6a1f1dSLionel Sambuc   while (DC->isRecord()) {
1449*0a6a1f1dSLionel Sambuc     OutermostRD = cast<RecordDecl>(DC);
1450*0a6a1f1dSLionel Sambuc     DC = DC->getLexicalParent();
1451*0a6a1f1dSLionel Sambuc   }
1452*0a6a1f1dSLionel Sambuc   return OutermostRD;
1453*0a6a1f1dSLionel Sambuc }
1454*0a6a1f1dSLionel Sambuc 
InEnclosingNamespaceSetOf(const DeclContext * O) const1455f4a2713aSLionel Sambuc bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const {
1456f4a2713aSLionel Sambuc   // For non-file contexts, this is equivalent to Equals.
1457f4a2713aSLionel Sambuc   if (!isFileContext())
1458f4a2713aSLionel Sambuc     return O->Equals(this);
1459f4a2713aSLionel Sambuc 
1460f4a2713aSLionel Sambuc   do {
1461f4a2713aSLionel Sambuc     if (O->Equals(this))
1462f4a2713aSLionel Sambuc       return true;
1463f4a2713aSLionel Sambuc 
1464f4a2713aSLionel Sambuc     const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(O);
1465f4a2713aSLionel Sambuc     if (!NS || !NS->isInline())
1466f4a2713aSLionel Sambuc       break;
1467f4a2713aSLionel Sambuc     O = NS->getParent();
1468f4a2713aSLionel Sambuc   } while (O);
1469f4a2713aSLionel Sambuc 
1470f4a2713aSLionel Sambuc   return false;
1471f4a2713aSLionel Sambuc }
1472f4a2713aSLionel Sambuc 
makeDeclVisibleInContext(NamedDecl * D)1473f4a2713aSLionel Sambuc void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
1474f4a2713aSLionel Sambuc   DeclContext *PrimaryDC = this->getPrimaryContext();
1475f4a2713aSLionel Sambuc   DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();
1476f4a2713aSLionel Sambuc   // If the decl is being added outside of its semantic decl context, we
1477f4a2713aSLionel Sambuc   // need to ensure that we eagerly build the lookup information for it.
1478f4a2713aSLionel Sambuc   PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);
1479f4a2713aSLionel Sambuc }
1480f4a2713aSLionel Sambuc 
makeDeclVisibleInContextWithFlags(NamedDecl * D,bool Internal,bool Recoverable)1481f4a2713aSLionel Sambuc void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
1482f4a2713aSLionel Sambuc                                                     bool Recoverable) {
1483f4a2713aSLionel Sambuc   assert(this == getPrimaryContext() && "expected a primary DC");
1484f4a2713aSLionel Sambuc 
1485f4a2713aSLionel Sambuc   // Skip declarations within functions.
1486f4a2713aSLionel Sambuc   if (isFunctionOrMethod())
1487f4a2713aSLionel Sambuc     return;
1488f4a2713aSLionel Sambuc 
1489f4a2713aSLionel Sambuc   // Skip declarations which should be invisible to name lookup.
1490f4a2713aSLionel Sambuc   if (shouldBeHidden(D))
1491f4a2713aSLionel Sambuc     return;
1492f4a2713aSLionel Sambuc 
1493f4a2713aSLionel Sambuc   // If we already have a lookup data structure, perform the insertion into
1494f4a2713aSLionel Sambuc   // it. If we might have externally-stored decls with this name, look them
1495f4a2713aSLionel Sambuc   // up and perform the insertion. If this decl was declared outside its
1496f4a2713aSLionel Sambuc   // semantic context, buildLookup won't add it, so add it now.
1497f4a2713aSLionel Sambuc   //
1498f4a2713aSLionel Sambuc   // FIXME: As a performance hack, don't add such decls into the translation
1499f4a2713aSLionel Sambuc   // unit unless we're in C++, since qualified lookup into the TU is never
1500f4a2713aSLionel Sambuc   // performed.
1501f4a2713aSLionel Sambuc   if (LookupPtr.getPointer() || hasExternalVisibleStorage() ||
1502f4a2713aSLionel Sambuc       ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&
1503f4a2713aSLionel Sambuc        (getParentASTContext().getLangOpts().CPlusPlus ||
1504f4a2713aSLionel Sambuc         !isTranslationUnit()))) {
1505f4a2713aSLionel Sambuc     // If we have lazily omitted any decls, they might have the same name as
1506f4a2713aSLionel Sambuc     // the decl which we are adding, so build a full lookup table before adding
1507f4a2713aSLionel Sambuc     // this decl.
1508f4a2713aSLionel Sambuc     buildLookup();
1509f4a2713aSLionel Sambuc     makeDeclVisibleInContextImpl(D, Internal);
1510f4a2713aSLionel Sambuc   } else {
1511f4a2713aSLionel Sambuc     LookupPtr.setInt(true);
1512f4a2713aSLionel Sambuc   }
1513f4a2713aSLionel Sambuc 
1514f4a2713aSLionel Sambuc   // If we are a transparent context or inline namespace, insert into our
1515f4a2713aSLionel Sambuc   // parent context, too. This operation is recursive.
1516f4a2713aSLionel Sambuc   if (isTransparentContext() || isInlineNamespace())
1517f4a2713aSLionel Sambuc     getParent()->getPrimaryContext()->
1518f4a2713aSLionel Sambuc         makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1519f4a2713aSLionel Sambuc 
1520f4a2713aSLionel Sambuc   Decl *DCAsDecl = cast<Decl>(this);
1521f4a2713aSLionel Sambuc   // Notify that a decl was made visible unless we are a Tag being defined.
1522f4a2713aSLionel Sambuc   if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1523f4a2713aSLionel Sambuc     if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())
1524f4a2713aSLionel Sambuc       L->AddedVisibleDecl(this, D);
1525f4a2713aSLionel Sambuc }
1526f4a2713aSLionel Sambuc 
makeDeclVisibleInContextImpl(NamedDecl * D,bool Internal)1527f4a2713aSLionel Sambuc void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
1528f4a2713aSLionel Sambuc   // Find or create the stored declaration map.
1529f4a2713aSLionel Sambuc   StoredDeclsMap *Map = LookupPtr.getPointer();
1530f4a2713aSLionel Sambuc   if (!Map) {
1531f4a2713aSLionel Sambuc     ASTContext *C = &getParentASTContext();
1532f4a2713aSLionel Sambuc     Map = CreateStoredDeclsMap(*C);
1533f4a2713aSLionel Sambuc   }
1534f4a2713aSLionel Sambuc 
1535f4a2713aSLionel Sambuc   // If there is an external AST source, load any declarations it knows about
1536f4a2713aSLionel Sambuc   // with this declaration's name.
1537f4a2713aSLionel Sambuc   // If the lookup table contains an entry about this name it means that we
1538f4a2713aSLionel Sambuc   // have already checked the external source.
1539f4a2713aSLionel Sambuc   if (!Internal)
1540f4a2713aSLionel Sambuc     if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
1541f4a2713aSLionel Sambuc       if (hasExternalVisibleStorage() &&
1542f4a2713aSLionel Sambuc           Map->find(D->getDeclName()) == Map->end())
1543f4a2713aSLionel Sambuc         Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
1544f4a2713aSLionel Sambuc 
1545f4a2713aSLionel Sambuc   // Insert this declaration into the map.
1546f4a2713aSLionel Sambuc   StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];
1547f4a2713aSLionel Sambuc 
1548f4a2713aSLionel Sambuc   if (Internal) {
1549f4a2713aSLionel Sambuc     // If this is being added as part of loading an external declaration,
1550f4a2713aSLionel Sambuc     // this may not be the only external declaration with this name.
1551f4a2713aSLionel Sambuc     // In this case, we never try to replace an existing declaration; we'll
1552f4a2713aSLionel Sambuc     // handle that when we finalize the list of declarations for this name.
1553f4a2713aSLionel Sambuc     DeclNameEntries.setHasExternalDecls();
1554f4a2713aSLionel Sambuc     DeclNameEntries.AddSubsequentDecl(D);
1555f4a2713aSLionel Sambuc     return;
1556f4a2713aSLionel Sambuc   }
1557f4a2713aSLionel Sambuc 
1558f4a2713aSLionel Sambuc   else if (DeclNameEntries.isNull()) {
1559f4a2713aSLionel Sambuc     DeclNameEntries.setOnlyValue(D);
1560f4a2713aSLionel Sambuc     return;
1561f4a2713aSLionel Sambuc   }
1562f4a2713aSLionel Sambuc 
1563f4a2713aSLionel Sambuc   if (DeclNameEntries.HandleRedeclaration(D)) {
1564f4a2713aSLionel Sambuc     // This declaration has replaced an existing one for which
1565f4a2713aSLionel Sambuc     // declarationReplaces returns true.
1566f4a2713aSLionel Sambuc     return;
1567f4a2713aSLionel Sambuc   }
1568f4a2713aSLionel Sambuc 
1569f4a2713aSLionel Sambuc   // Put this declaration into the appropriate slot.
1570f4a2713aSLionel Sambuc   DeclNameEntries.AddSubsequentDecl(D);
1571f4a2713aSLionel Sambuc }
1572f4a2713aSLionel Sambuc 
1573f4a2713aSLionel Sambuc /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
1574f4a2713aSLionel Sambuc /// this context.
using_directives() const1575*0a6a1f1dSLionel Sambuc DeclContext::udir_range DeclContext::using_directives() const {
1576f4a2713aSLionel Sambuc   // FIXME: Use something more efficient than normal lookup for using
1577f4a2713aSLionel Sambuc   // directives. In C++, using directives are looked up more than anything else.
1578f4a2713aSLionel Sambuc   lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
1579*0a6a1f1dSLionel Sambuc   return udir_range(
1580*0a6a1f1dSLionel Sambuc       reinterpret_cast<UsingDirectiveDecl *const *>(Result.begin()),
1581*0a6a1f1dSLionel Sambuc       reinterpret_cast<UsingDirectiveDecl *const *>(Result.end()));
1582f4a2713aSLionel Sambuc }
1583f4a2713aSLionel Sambuc 
1584f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1585f4a2713aSLionel Sambuc // Creation and Destruction of StoredDeclsMaps.                               //
1586f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1587f4a2713aSLionel Sambuc 
CreateStoredDeclsMap(ASTContext & C) const1588f4a2713aSLionel Sambuc StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {
1589f4a2713aSLionel Sambuc   assert(!LookupPtr.getPointer() && "context already has a decls map");
1590f4a2713aSLionel Sambuc   assert(getPrimaryContext() == this &&
1591f4a2713aSLionel Sambuc          "creating decls map on non-primary context");
1592f4a2713aSLionel Sambuc 
1593f4a2713aSLionel Sambuc   StoredDeclsMap *M;
1594f4a2713aSLionel Sambuc   bool Dependent = isDependentContext();
1595f4a2713aSLionel Sambuc   if (Dependent)
1596f4a2713aSLionel Sambuc     M = new DependentStoredDeclsMap();
1597f4a2713aSLionel Sambuc   else
1598f4a2713aSLionel Sambuc     M = new StoredDeclsMap();
1599f4a2713aSLionel Sambuc   M->Previous = C.LastSDM;
1600f4a2713aSLionel Sambuc   C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1601f4a2713aSLionel Sambuc   LookupPtr.setPointer(M);
1602f4a2713aSLionel Sambuc   return M;
1603f4a2713aSLionel Sambuc }
1604f4a2713aSLionel Sambuc 
ReleaseDeclContextMaps()1605f4a2713aSLionel Sambuc void ASTContext::ReleaseDeclContextMaps() {
1606f4a2713aSLionel Sambuc   // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap
1607f4a2713aSLionel Sambuc   // pointer because the subclass doesn't add anything that needs to
1608f4a2713aSLionel Sambuc   // be deleted.
1609f4a2713aSLionel Sambuc   StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());
1610f4a2713aSLionel Sambuc }
1611f4a2713aSLionel Sambuc 
DestroyAll(StoredDeclsMap * Map,bool Dependent)1612f4a2713aSLionel Sambuc void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {
1613f4a2713aSLionel Sambuc   while (Map) {
1614f4a2713aSLionel Sambuc     // Advance the iteration before we invalidate memory.
1615f4a2713aSLionel Sambuc     llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1616f4a2713aSLionel Sambuc 
1617f4a2713aSLionel Sambuc     if (Dependent)
1618f4a2713aSLionel Sambuc       delete static_cast<DependentStoredDeclsMap*>(Map);
1619f4a2713aSLionel Sambuc     else
1620f4a2713aSLionel Sambuc       delete Map;
1621f4a2713aSLionel Sambuc 
1622f4a2713aSLionel Sambuc     Map = Next.getPointer();
1623f4a2713aSLionel Sambuc     Dependent = Next.getInt();
1624f4a2713aSLionel Sambuc   }
1625f4a2713aSLionel Sambuc }
1626f4a2713aSLionel Sambuc 
Create(ASTContext & C,DeclContext * Parent,const PartialDiagnostic & PDiag)1627f4a2713aSLionel Sambuc DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
1628f4a2713aSLionel Sambuc                                                  DeclContext *Parent,
1629f4a2713aSLionel Sambuc                                            const PartialDiagnostic &PDiag) {
1630f4a2713aSLionel Sambuc   assert(Parent->isDependentContext()
1631f4a2713aSLionel Sambuc          && "cannot iterate dependent diagnostics of non-dependent context");
1632f4a2713aSLionel Sambuc   Parent = Parent->getPrimaryContext();
1633f4a2713aSLionel Sambuc   if (!Parent->LookupPtr.getPointer())
1634f4a2713aSLionel Sambuc     Parent->CreateStoredDeclsMap(C);
1635f4a2713aSLionel Sambuc 
1636f4a2713aSLionel Sambuc   DependentStoredDeclsMap *Map
1637f4a2713aSLionel Sambuc     = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr.getPointer());
1638f4a2713aSLionel Sambuc 
1639f4a2713aSLionel Sambuc   // Allocate the copy of the PartialDiagnostic via the ASTContext's
1640f4a2713aSLionel Sambuc   // BumpPtrAllocator, rather than the ASTContext itself.
1641*0a6a1f1dSLionel Sambuc   PartialDiagnostic::Storage *DiagStorage = nullptr;
1642f4a2713aSLionel Sambuc   if (PDiag.hasStorage())
1643f4a2713aSLionel Sambuc     DiagStorage = new (C) PartialDiagnostic::Storage;
1644f4a2713aSLionel Sambuc 
1645f4a2713aSLionel Sambuc   DependentDiagnostic *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);
1646f4a2713aSLionel Sambuc 
1647f4a2713aSLionel Sambuc   // TODO: Maybe we shouldn't reverse the order during insertion.
1648f4a2713aSLionel Sambuc   DD->NextDiagnostic = Map->FirstDiagnostic;
1649f4a2713aSLionel Sambuc   Map->FirstDiagnostic = DD;
1650f4a2713aSLionel Sambuc 
1651f4a2713aSLionel Sambuc   return DD;
1652f4a2713aSLionel Sambuc }
1653