10d00c899SEugene Zelenko //===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//
26301884dSArgyrios Kyrtzidis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66301884dSArgyrios Kyrtzidis //
76301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
86301884dSArgyrios Kyrtzidis //
96301884dSArgyrios Kyrtzidis // This file implements the Decl and DeclContext classes.
106301884dSArgyrios Kyrtzidis //
116301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
126301884dSArgyrios Kyrtzidis 
136301884dSArgyrios Kyrtzidis #include "clang/AST/DeclBase.h"
143a02247dSChandler Carruth #include "clang/AST/ASTContext.h"
157ac42374SRichard Smith #include "clang/AST/ASTLambda.h"
163a02247dSChandler Carruth #include "clang/AST/ASTMutationListener.h"
173a02247dSChandler Carruth #include "clang/AST/Attr.h"
180d00c899SEugene Zelenko #include "clang/AST/AttrIterator.h"
198bd3c2ebSDouglas Gregor #include "clang/AST/Decl.h"
202951e145SArgyrios Kyrtzidis #include "clang/AST/DeclCXX.h"
213a02247dSChandler Carruth #include "clang/AST/DeclContextInternals.h"
22bbbbe4eaSJohn McCall #include "clang/AST/DeclFriend.h"
23ded2d7b0SDouglas Gregor #include "clang/AST/DeclObjC.h"
24a769e072SAlexey Bataev #include "clang/AST/DeclOpenMP.h"
25ded2d7b0SDouglas Gregor #include "clang/AST/DeclTemplate.h"
26c62bb64cSJohn McCall #include "clang/AST/DependentDiagnostic.h"
27ea70eb30SBenjamin Kramer #include "clang/AST/ExternalASTSource.h"
28a7b98a77SSebastian Redl #include "clang/AST/Stmt.h"
29ea70eb30SBenjamin Kramer #include "clang/AST/Type.h"
300d00c899SEugene Zelenko #include "clang/Basic/IdentifierTable.h"
310d00c899SEugene Zelenko #include "clang/Basic/LLVM.h"
320d00c899SEugene Zelenko #include "clang/Basic/LangOptions.h"
330d00c899SEugene Zelenko #include "clang/Basic/ObjCRuntime.h"
340d00c899SEugene Zelenko #include "clang/Basic/PartialDiagnostic.h"
350d00c899SEugene Zelenko #include "clang/Basic/SourceLocation.h"
3620b2ebd7SDouglas Gregor #include "clang/Basic/TargetInfo.h"
370d00c899SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
380d00c899SEugene Zelenko #include "llvm/ADT/PointerIntPair.h"
390d00c899SEugene Zelenko #include "llvm/ADT/SmallVector.h"
400d00c899SEugene Zelenko #include "llvm/ADT/StringRef.h"
410d00c899SEugene Zelenko #include "llvm/Support/Casting.h"
420d00c899SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
430d00c899SEugene Zelenko #include "llvm/Support/MathExtras.h"
44d8c6290bSPavel Labath #include "llvm/Support/VersionTuple.h"
45eae6cb61SChris Lattner #include "llvm/Support/raw_ostream.h"
468b9ccca5SDouglas Gregor #include <algorithm>
470d00c899SEugene Zelenko #include <cassert>
480d00c899SEugene Zelenko #include <cstddef>
490d00c899SEugene Zelenko #include <string>
500d00c899SEugene Zelenko #include <tuple>
510d00c899SEugene Zelenko #include <utility>
520d00c899SEugene Zelenko 
536301884dSArgyrios Kyrtzidis using namespace clang;
546301884dSArgyrios Kyrtzidis 
556301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
566301884dSArgyrios Kyrtzidis //  Statistics
576301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
586301884dSArgyrios Kyrtzidis 
59ed05325dSAlexis Hunt #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
60ed05325dSAlexis Hunt #define ABSTRACT_DECL(DECL)
61ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
626301884dSArgyrios Kyrtzidis 
updateOutOfDate(IdentifierInfo & II) const637dab26b8SDouglas Gregor void Decl::updateOutOfDate(IdentifierInfo &II) const {
647dab26b8SDouglas Gregor   getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
657dab26b8SDouglas Gregor }
667dab26b8SDouglas Gregor 
6753c7616eSJames Y Knight #define DECL(DERIVED, BASE)                                                    \
68c3f89253SBenjamin Kramer   static_assert(alignof(Decl) >= alignof(DERIVED##Decl),                       \
6953c7616eSJames Y Knight                 "Alignment sufficient after objects prepended to " #DERIVED);
7053c7616eSJames Y Knight #define ABSTRACT_DECL(DECL)
7153c7616eSJames Y Knight #include "clang/AST/DeclNodes.inc"
7253c7616eSJames Y Knight 
operator new(std::size_t Size,const ASTContext & Context,unsigned ID,std::size_t Extra)73f7981724SRichard Smith void *Decl::operator new(std::size_t Size, const ASTContext &Context,
74f7981724SRichard Smith                          unsigned ID, std::size_t Extra) {
7552261fd2SDouglas Gregor   // Allocate an extra 8 bytes worth of storage, which ensures that the
76cfe7dc6bSDouglas Gregor   // resulting pointer will still be 8-byte aligned.
77c3f89253SBenjamin Kramer   static_assert(sizeof(unsigned) * 2 >= alignof(Decl),
7853c7616eSJames Y Knight                 "Decl won't be misaligned");
79f7981724SRichard Smith   void *Start = Context.Allocate(Size + Extra + 8);
8052261fd2SDouglas Gregor   void *Result = (char*)Start + 8;
8164af53c3SDouglas Gregor 
82cfe7dc6bSDouglas Gregor   unsigned *PrefixPtr = (unsigned *)Result - 2;
83cfe7dc6bSDouglas Gregor 
84cfe7dc6bSDouglas Gregor   // Zero out the first 4 bytes; this is used to store the owning module ID.
85cfe7dc6bSDouglas Gregor   PrefixPtr[0] = 0;
86cfe7dc6bSDouglas Gregor 
87cfe7dc6bSDouglas Gregor   // Store the global declaration ID in the second 4 bytes.
88cfe7dc6bSDouglas Gregor   PrefixPtr[1] = ID;
8964af53c3SDouglas Gregor 
9064af53c3SDouglas Gregor   return Result;
9172172e90SDouglas Gregor }
9272172e90SDouglas Gregor 
operator new(std::size_t Size,const ASTContext & Ctx,DeclContext * Parent,std::size_t Extra)93f7981724SRichard Smith void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
94f7981724SRichard Smith                          DeclContext *Parent, std::size_t Extra) {
95f7981724SRichard Smith   assert(!Parent || &Parent->getParentASTContext() == &Ctx);
9642413141SRichard Smith   // With local visibility enabled, we track the owning module even for local
97debbaefbSRichard Smith   // declarations. We create the TU decl early and may not yet know what the
98debbaefbSRichard Smith   // LangOpts are, so conservatively allocate the storage.
99debbaefbSRichard Smith   if (Ctx.getLangOpts().trackLocalOwningModule() || !Parent) {
10053c7616eSJames Y Knight     // Ensure required alignment of the resulting object by adding extra
10153c7616eSJames Y Knight     // padding at the start if required.
10253c7616eSJames Y Knight     size_t ExtraAlign =
103af11cc7eSGuillaume Chatelet         llvm::offsetToAlignment(sizeof(Module *), llvm::Align(alignof(Decl)));
1042a1ba94fSEugene Zelenko     auto *Buffer = reinterpret_cast<char *>(
10553c7616eSJames Y Knight         ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));
10653c7616eSJames Y Knight     Buffer += ExtraAlign;
10726342f91SRichard Smith     auto *ParentModule =
10826342f91SRichard Smith         Parent ? cast<Decl>(Parent)->getOwningModule() : nullptr;
10926342f91SRichard Smith     return new (Buffer) Module*(ParentModule) + 1;
11042413141SRichard Smith   }
111f7981724SRichard Smith   return ::operator new(Size + Extra, Ctx);
112f7981724SRichard Smith }
113f7981724SRichard Smith 
getOwningModuleSlow() const114c147b0bcSDouglas Gregor Module *Decl::getOwningModuleSlow() const {
115c147b0bcSDouglas Gregor   assert(isFromASTFile() && "Not from AST file?");
116c147b0bcSDouglas Gregor   return getASTContext().getExternalSource()->getModule(getOwningModuleID());
117c147b0bcSDouglas Gregor }
118c147b0bcSDouglas Gregor 
hasLocalOwningModuleStorage() const11987bb5698SRichard Smith bool Decl::hasLocalOwningModuleStorage() const {
12026342f91SRichard Smith   return getASTContext().getLangOpts().trackLocalOwningModule();
12187bb5698SRichard Smith }
12287bb5698SRichard Smith 
getDeclKindName() const1236301884dSArgyrios Kyrtzidis const char *Decl::getDeclKindName() const {
1246301884dSArgyrios Kyrtzidis   switch (DeclKind) {
12583d382b1SDavid Blaikie   default: llvm_unreachable("Declaration not in DeclNodes.inc!");
126ed05325dSAlexis Hunt #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
127ed05325dSAlexis Hunt #define ABSTRACT_DECL(DECL)
128ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1296301884dSArgyrios Kyrtzidis   }
1306301884dSArgyrios Kyrtzidis }
1316301884dSArgyrios Kyrtzidis 
setInvalidDecl(bool Invalid)13290d47177SDouglas Gregor void Decl::setInvalidDecl(bool Invalid) {
13390d47177SDouglas Gregor   InvalidDecl = Invalid;
134a5d64597SAlp Toker   assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
135cbd54304SRichard Trieu   if (!Invalid) {
136cbd54304SRichard Trieu     return;
137cbd54304SRichard Trieu   }
138cbd54304SRichard Trieu 
139cbd54304SRichard Trieu   if (!isa<ParmVarDecl>(this)) {
14090d47177SDouglas Gregor     // Defensive maneuver for ill-formed code: we're likely not to make it to
14190d47177SDouglas Gregor     // a point where we set the access specifier, so default it to "public"
14290d47177SDouglas Gregor     // to avoid triggering asserts elsewhere in the front end.
14390d47177SDouglas Gregor     setAccess(AS_public);
14490d47177SDouglas Gregor   }
145cbd54304SRichard Trieu 
146cbd54304SRichard Trieu   // Marking a DecompositionDecl as invalid implies all the child BindingDecl's
147cbd54304SRichard Trieu   // are invalid too.
1482a1ba94fSEugene Zelenko   if (auto *DD = dyn_cast<DecompositionDecl>(this)) {
1492a1ba94fSEugene Zelenko     for (auto *Binding : DD->bindings()) {
150cbd54304SRichard Trieu       Binding->setInvalidDecl();
151cbd54304SRichard Trieu     }
152cbd54304SRichard Trieu   }
15390d47177SDouglas Gregor }
15490d47177SDouglas Gregor 
getDeclKindName() const1555faaef76SSteve Naroff const char *DeclContext::getDeclKindName() const {
156f92f31c6SErich Keane   switch (getDeclKind()) {
157ed05325dSAlexis Hunt #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
158ed05325dSAlexis Hunt #define ABSTRACT_DECL(DECL)
159ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1605faaef76SSteve Naroff   }
161ce3efe57SReid Kleckner   llvm_unreachable("Declaration context not in DeclNodes.inc!");
1625faaef76SSteve Naroff }
1635faaef76SSteve Naroff 
16462905578SDaniel Dunbar bool Decl::StatisticsEnabled = false;
EnableStatistics()16562905578SDaniel Dunbar void Decl::EnableStatistics() {
16662905578SDaniel Dunbar   StatisticsEnabled = true;
1676301884dSArgyrios Kyrtzidis }
1686301884dSArgyrios Kyrtzidis 
PrintStats()1696301884dSArgyrios Kyrtzidis void Decl::PrintStats() {
170bfb154adSChandler Carruth   llvm::errs() << "\n*** Decl Stats:\n";
1716301884dSArgyrios Kyrtzidis 
1728bd3c2ebSDouglas Gregor   int totalDecls = 0;
173ed05325dSAlexis Hunt #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
174ed05325dSAlexis Hunt #define ABSTRACT_DECL(DECL)
175ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
176bfb154adSChandler Carruth   llvm::errs() << "  " << totalDecls << " decls total.\n";
1776301884dSArgyrios Kyrtzidis 
1788bd3c2ebSDouglas Gregor   int totalBytes = 0;
179ed05325dSAlexis Hunt #define DECL(DERIVED, BASE)                                             \
180ed05325dSAlexis Hunt   if (n##DERIVED##s > 0) {                                              \
181ed05325dSAlexis Hunt     totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl));         \
182bfb154adSChandler Carruth     llvm::errs() << "    " << n##DERIVED##s << " " #DERIVED " decls, "  \
183bfb154adSChandler Carruth                  << sizeof(DERIVED##Decl) << " each ("                  \
184bfb154adSChandler Carruth                  << n##DERIVED##s * sizeof(DERIVED##Decl)               \
185bfb154adSChandler Carruth                  << " bytes)\n";                                        \
1868bd3c2ebSDouglas Gregor   }
187ed05325dSAlexis Hunt #define ABSTRACT_DECL(DECL)
188ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1896301884dSArgyrios Kyrtzidis 
190bfb154adSChandler Carruth   llvm::errs() << "Total bytes = " << totalBytes << "\n";
1916301884dSArgyrios Kyrtzidis }
1926301884dSArgyrios Kyrtzidis 
add(Kind k)193ed05325dSAlexis Hunt void Decl::add(Kind k) {
1946301884dSArgyrios Kyrtzidis   switch (k) {
195ed05325dSAlexis Hunt #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
196ed05325dSAlexis Hunt #define ABSTRACT_DECL(DECL)
197ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1986301884dSArgyrios Kyrtzidis   }
1996301884dSArgyrios Kyrtzidis }
2006301884dSArgyrios Kyrtzidis 
isTemplateParameterPack() const201aa73b913SAnders Carlsson bool Decl::isTemplateParameterPack() const {
2022a1ba94fSEugene Zelenko   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(this))
203aa73b913SAnders Carlsson     return TTP->isParameterPack();
2042a1ba94fSEugene Zelenko   if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(this))
205da3cc0d3SDouglas Gregor     return NTTP->isParameterPack();
2062a1ba94fSEugene Zelenko   if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(this))
207f550077eSDouglas Gregor     return TTP->isParameterPack();
208aa73b913SAnders Carlsson   return false;
209aa73b913SAnders Carlsson }
210aa73b913SAnders Carlsson 
isParameterPack() const2113c6bd2adSDouglas Gregor bool Decl::isParameterPack() const {
212b2997f57SRichard Smith   if (const auto *Var = dyn_cast<VarDecl>(this))
213b2997f57SRichard Smith     return Var->isParameterPack();
2143c6bd2adSDouglas Gregor 
2153c6bd2adSDouglas Gregor   return isTemplateParameterPack();
2163c6bd2adSDouglas Gregor }
2173c6bd2adSDouglas Gregor 
getAsFunction()218a2794f9fSAlp Toker FunctionDecl *Decl::getAsFunction() {
2192a1ba94fSEugene Zelenko   if (auto *FD = dyn_cast<FunctionDecl>(this))
220a2794f9fSAlp Toker     return FD;
2212a1ba94fSEugene Zelenko   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
222a2794f9fSAlp Toker     return FTD->getTemplatedDecl();
22336250ad6SCraig Topper   return nullptr;
224ad3f2fcfSDouglas Gregor }
225ad3f2fcfSDouglas Gregor 
isTemplateDecl() const226990d5712SCaitlin Sadowski bool Decl::isTemplateDecl() const {
227990d5712SCaitlin Sadowski   return isa<TemplateDecl>(this);
228990d5712SCaitlin Sadowski }
229990d5712SCaitlin Sadowski 
getDescribedTemplate() const2307dcc97e7SSerge Pavlov TemplateDecl *Decl::getDescribedTemplate() const {
2317dcc97e7SSerge Pavlov   if (auto *FD = dyn_cast<FunctionDecl>(this))
2327dcc97e7SSerge Pavlov     return FD->getDescribedFunctionTemplate();
233c8d2ae52SKirill Bobyrev   if (auto *RD = dyn_cast<CXXRecordDecl>(this))
2347dcc97e7SSerge Pavlov     return RD->getDescribedClassTemplate();
235c8d2ae52SKirill Bobyrev   if (auto *VD = dyn_cast<VarDecl>(this))
2367dcc97e7SSerge Pavlov     return VD->getDescribedVarTemplate();
237c8d2ae52SKirill Bobyrev   if (auto *AD = dyn_cast<TypeAliasDecl>(this))
23832b615c2SRichard Smith     return AD->getDescribedAliasTemplate();
2397dcc97e7SSerge Pavlov 
2407dcc97e7SSerge Pavlov   return nullptr;
2417dcc97e7SSerge Pavlov }
2427dcc97e7SSerge Pavlov 
getDescribedTemplateParams() const2432a3b86c1SRichard Smith const TemplateParameterList *Decl::getDescribedTemplateParams() const {
2442a3b86c1SRichard Smith   if (auto *TD = getDescribedTemplate())
2452a3b86c1SRichard Smith     return TD->getTemplateParameters();
2462a3b86c1SRichard Smith   if (auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(this))
2472a3b86c1SRichard Smith     return CTPSD->getTemplateParameters();
2482a3b86c1SRichard Smith   if (auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(this))
2492a3b86c1SRichard Smith     return VTPSD->getTemplateParameters();
2502a3b86c1SRichard Smith   return nullptr;
2512a3b86c1SRichard Smith }
2522a3b86c1SRichard Smith 
isTemplated() const25332b615c2SRichard Smith bool Decl::isTemplated() const {
254d1446017SRichard Smith   // A declaration is templated if it is a template or a template pattern, or
25532b615c2SRichard Smith   // is within (lexcially for a friend, semantically otherwise) a dependent
25632b615c2SRichard Smith   // context.
25732b615c2SRichard Smith   // FIXME: Should local extern declarations be treated like friends?
25832b615c2SRichard Smith   if (auto *AsDC = dyn_cast<DeclContext>(this))
25932b615c2SRichard Smith     return AsDC->isDependentContext();
26032b615c2SRichard Smith   auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
2612a3b86c1SRichard Smith   return DC->isDependentContext() || isTemplateDecl() ||
2622a3b86c1SRichard Smith          getDescribedTemplateParams();
2632a3b86c1SRichard Smith }
2642a3b86c1SRichard Smith 
getTemplateDepth() const2652a3b86c1SRichard Smith unsigned Decl::getTemplateDepth() const {
2662a3b86c1SRichard Smith   if (auto *DC = dyn_cast<DeclContext>(this))
2672a3b86c1SRichard Smith     if (DC->isFileContext())
2682a3b86c1SRichard Smith       return 0;
2692a3b86c1SRichard Smith 
2702a3b86c1SRichard Smith   if (auto *TPL = getDescribedTemplateParams())
2712a3b86c1SRichard Smith     return TPL->getDepth() + 1;
2722a3b86c1SRichard Smith 
2732a3b86c1SRichard Smith   // If this is a dependent lambda, there might be an enclosing variable
2742a3b86c1SRichard Smith   // template. In this case, the next step is not the parent DeclContext (or
2752a3b86c1SRichard Smith   // even a DeclContext at all).
2762a3b86c1SRichard Smith   auto *RD = dyn_cast<CXXRecordDecl>(this);
2772a3b86c1SRichard Smith   if (RD && RD->isDependentLambda())
2782a3b86c1SRichard Smith     if (Decl *Context = RD->getLambdaContextDecl())
2792a3b86c1SRichard Smith       return Context->getTemplateDepth();
2802a3b86c1SRichard Smith 
2812a3b86c1SRichard Smith   const DeclContext *DC =
2822a3b86c1SRichard Smith       getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
2832a3b86c1SRichard Smith   return cast<Decl>(DC)->getTemplateDepth();
28432b615c2SRichard Smith }
28532b615c2SRichard Smith 
getParentFunctionOrMethod(bool LexicalParent) const286*70c62f4cSErich Keane const DeclContext *Decl::getParentFunctionOrMethod(bool LexicalParent) const {
287*70c62f4cSErich Keane   for (const DeclContext *DC = LexicalParent ? getLexicalDeclContext()
288*70c62f4cSErich Keane                                              : getDeclContext();
2890ce4c9abSArgyrios Kyrtzidis        DC && !DC->isTranslationUnit() && !DC->isNamespace();
290f5974fa0SDouglas Gregor        DC = DC->getParent())
291f5974fa0SDouglas Gregor     if (DC->isFunctionOrMethod())
2920ce4c9abSArgyrios Kyrtzidis       return DC;
293f5974fa0SDouglas Gregor 
29436250ad6SCraig Topper   return nullptr;
295f5974fa0SDouglas Gregor }
296f5974fa0SDouglas Gregor 
2976301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
298eae6cb61SChris Lattner // PrettyStackTraceDecl Implementation
299eae6cb61SChris Lattner //===----------------------------------------------------------------------===//
300eae6cb61SChris Lattner 
print(raw_ostream & OS) const3010e62c1ccSChris Lattner void PrettyStackTraceDecl::print(raw_ostream &OS) const {
302eae6cb61SChris Lattner   SourceLocation TheLoc = Loc;
303eae6cb61SChris Lattner   if (TheLoc.isInvalid() && TheDecl)
304eae6cb61SChris Lattner     TheLoc = TheDecl->getLocation();
305eae6cb61SChris Lattner 
306eae6cb61SChris Lattner   if (TheLoc.isValid()) {
307eae6cb61SChris Lattner     TheLoc.print(OS, SM);
308eae6cb61SChris Lattner     OS << ": ";
309eae6cb61SChris Lattner   }
310eae6cb61SChris Lattner 
311eae6cb61SChris Lattner   OS << Message;
312eae6cb61SChris Lattner 
3132a1ba94fSEugene Zelenko   if (const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
31424ebf7c9SBenjamin Kramer     OS << " '";
31524ebf7c9SBenjamin Kramer     DN->printQualifiedName(OS);
31624ebf7c9SBenjamin Kramer     OS << '\'';
31724ebf7c9SBenjamin Kramer   }
318eae6cb61SChris Lattner   OS << '\n';
319eae6cb61SChris Lattner }
320eae6cb61SChris Lattner 
321eae6cb61SChris Lattner //===----------------------------------------------------------------------===//
3226301884dSArgyrios Kyrtzidis // Decl Implementation
3236301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
3246301884dSArgyrios Kyrtzidis 
325b11aad8cSDouglas Gregor // Out-of-line virtual method providing a home for Decl.
3260d00c899SEugene Zelenko Decl::~Decl() = default;
327a43942a4SDouglas Gregor 
setDeclContext(DeclContext * DC)3286e6ad602SDouglas Gregor void Decl::setDeclContext(DeclContext *DC) {
329b81eb052SChris Lattner   DeclCtx = DC;
3306e6ad602SDouglas Gregor }
3316e6ad602SDouglas Gregor 
setLexicalDeclContext(DeclContext * DC)3326e6ad602SDouglas Gregor void Decl::setLexicalDeclContext(DeclContext *DC) {
3336e6ad602SDouglas Gregor   if (DC == getLexicalDeclContext())
3346e6ad602SDouglas Gregor     return;
3356e6ad602SDouglas Gregor 
3366e6ad602SDouglas Gregor   if (isInSemaDC()) {
3376f40eb7eSArgyrios Kyrtzidis     setDeclContextsImpl(getDeclContext(), DC, getASTContext());
3386e6ad602SDouglas Gregor   } else {
3396e6ad602SDouglas Gregor     getMultipleDC()->LexicalDC = DC;
3406e6ad602SDouglas Gregor   }
341ae50c56dSRichard Smith 
342ae50c56dSRichard Smith   // FIXME: We shouldn't be changing the lexical context of declarations
343ae50c56dSRichard Smith   // imported from AST files.
344ae50c56dSRichard Smith   if (!isFromASTFile()) {
34590dc5254SRichard Smith     setModuleOwnershipKind(getModuleOwnershipKindForChildOf(DC));
34690dc5254SRichard Smith     if (hasOwningModule())
34726342f91SRichard Smith       setLocalOwningModule(cast<Decl>(DC)->getOwningModule());
3486e6ad602SDouglas Gregor   }
3496e6ad602SDouglas Gregor 
350d19389a3SRichard Smith   assert(
351d19389a3SRichard Smith       (getModuleOwnershipKind() != ModuleOwnershipKind::VisibleWhenImported ||
352d19389a3SRichard Smith        getOwningModule()) &&
353ae50c56dSRichard Smith       "hidden declaration has no owning module");
354ae50c56dSRichard Smith }
355ae50c56dSRichard Smith 
setDeclContextsImpl(DeclContext * SemaDC,DeclContext * LexicalDC,ASTContext & Ctx)3566f40eb7eSArgyrios Kyrtzidis void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
3576f40eb7eSArgyrios Kyrtzidis                                ASTContext &Ctx) {
3586f40eb7eSArgyrios Kyrtzidis   if (SemaDC == LexicalDC) {
3596f40eb7eSArgyrios Kyrtzidis     DeclCtx = SemaDC;
3606f40eb7eSArgyrios Kyrtzidis   } else {
3612a1ba94fSEugene Zelenko     auto *MDC = new (Ctx) Decl::MultipleDC();
3626f40eb7eSArgyrios Kyrtzidis     MDC->SemanticDC = SemaDC;
3636f40eb7eSArgyrios Kyrtzidis     MDC->LexicalDC = LexicalDC;
3646f40eb7eSArgyrios Kyrtzidis     DeclCtx = MDC;
3656f40eb7eSArgyrios Kyrtzidis   }
3666f40eb7eSArgyrios Kyrtzidis }
3676f40eb7eSArgyrios Kyrtzidis 
isInLocalScopeForInstantiation() const368f721e058SRichard Smith bool Decl::isInLocalScopeForInstantiation() const {
36973c6a244SSerge Pavlov   const DeclContext *LDC = getLexicalDeclContext();
370f721e058SRichard Smith   if (!LDC->isDependentContext())
371f721e058SRichard Smith     return false;
372b24a7111SSerge Pavlov   while (true) {
37373c6a244SSerge Pavlov     if (LDC->isFunctionOrMethod())
37473c6a244SSerge Pavlov       return true;
37573c6a244SSerge Pavlov     if (!isa<TagDecl>(LDC))
37673c6a244SSerge Pavlov       return false;
377f43859a0SAaron Puchert     if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))
378f43859a0SAaron Puchert       if (CRD->isLambda())
379f43859a0SAaron Puchert         return true;
380b24a7111SSerge Pavlov     LDC = LDC->getLexicalParent();
381b24a7111SSerge Pavlov   }
38273c6a244SSerge Pavlov   return false;
38373c6a244SSerge Pavlov }
38473c6a244SSerge Pavlov 
isInAnonymousNamespace() const3854fa53427SJohn McCall bool Decl::isInAnonymousNamespace() const {
386becb92deSRichard Smith   for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {
3872a1ba94fSEugene Zelenko     if (const auto *ND = dyn_cast<NamespaceDecl>(DC))
3884fa53427SJohn McCall       if (ND->isAnonymousNamespace())
3894fa53427SJohn McCall         return true;
390becb92deSRichard Smith   }
3914fa53427SJohn McCall 
3924fa53427SJohn McCall   return false;
3934fa53427SJohn McCall }
3944fa53427SJohn McCall 
isInStdNamespace() const395c771d5d7SRichard Trieu bool Decl::isInStdNamespace() const {
396b641b914SDmitri Gribenko   const DeclContext *DC = getDeclContext();
397b641b914SDmitri Gribenko   return DC && DC->isStdNamespace();
398c771d5d7SRichard Trieu }
399c771d5d7SRichard Trieu 
getTranslationUnitDecl()400743e7db7SArgyrios Kyrtzidis TranslationUnitDecl *Decl::getTranslationUnitDecl() {
4012a1ba94fSEugene Zelenko   if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
4024e1a72b3SArgyrios Kyrtzidis     return TUD;
4034e1a72b3SArgyrios Kyrtzidis 
404743e7db7SArgyrios Kyrtzidis   DeclContext *DC = getDeclContext();
405743e7db7SArgyrios Kyrtzidis   assert(DC && "This decl is not contained in a translation unit!");
406743e7db7SArgyrios Kyrtzidis 
407743e7db7SArgyrios Kyrtzidis   while (!DC->isTranslationUnit()) {
408743e7db7SArgyrios Kyrtzidis     DC = DC->getParent();
409743e7db7SArgyrios Kyrtzidis     assert(DC && "This decl is not contained in a translation unit!");
410743e7db7SArgyrios Kyrtzidis   }
411743e7db7SArgyrios Kyrtzidis 
412743e7db7SArgyrios Kyrtzidis   return cast<TranslationUnitDecl>(DC);
413743e7db7SArgyrios Kyrtzidis }
414743e7db7SArgyrios Kyrtzidis 
getASTContext() const415743e7db7SArgyrios Kyrtzidis ASTContext &Decl::getASTContext() const {
416743e7db7SArgyrios Kyrtzidis   return getTranslationUnitDecl()->getASTContext();
417743e7db7SArgyrios Kyrtzidis }
418743e7db7SArgyrios Kyrtzidis 
419b36c19bcSReid Kleckner /// Helper to get the language options from the ASTContext.
420b36c19bcSReid Kleckner /// Defined out of line to avoid depending on ASTContext.h.
getLangOpts() const421b36c19bcSReid Kleckner const LangOptions &Decl::getLangOpts() const {
422b36c19bcSReid Kleckner   return getASTContext().getLangOpts();
423b36c19bcSReid Kleckner }
424b36c19bcSReid Kleckner 
getASTMutationListener() const42565ad5691SArgyrios Kyrtzidis ASTMutationListener *Decl::getASTMutationListener() const {
42665ad5691SArgyrios Kyrtzidis   return getASTContext().getASTMutationListener();
42765ad5691SArgyrios Kyrtzidis }
42865ad5691SArgyrios Kyrtzidis 
getMaxAlignment() const429ea70eb30SBenjamin Kramer unsigned Decl::getMaxAlignment() const {
430ea70eb30SBenjamin Kramer   if (!hasAttrs())
431ea70eb30SBenjamin Kramer     return 0;
432ea70eb30SBenjamin Kramer 
433ea70eb30SBenjamin Kramer   unsigned Align = 0;
434ea70eb30SBenjamin Kramer   const AttrVec &V = getAttrs();
435ea70eb30SBenjamin Kramer   ASTContext &Ctx = getASTContext();
436ea70eb30SBenjamin Kramer   specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());
43717198dfaSHaojian Wu   for (; I != E; ++I) {
43817198dfaSHaojian Wu     if (!I->isAlignmentErrorDependent())
439ea70eb30SBenjamin Kramer       Align = std::max(Align, I->getAlignment(Ctx));
44017198dfaSHaojian Wu   }
441ea70eb30SBenjamin Kramer   return Align;
442ea70eb30SBenjamin Kramer }
443ea70eb30SBenjamin Kramer 
isUsed(bool CheckUsedAttr) const444ebada077SDouglas Gregor bool Decl::isUsed(bool CheckUsedAttr) const {
445928c8254SVassil Vassilev   const Decl *CanonD = getCanonicalDecl();
446928c8254SVassil Vassilev   if (CanonD->Used)
4478aefcbedSTanya Lattner     return true;
4488aefcbedSTanya Lattner 
4498aefcbedSTanya Lattner   // Check for used attribute.
450928c8254SVassil Vassilev   // Ask the most recent decl, since attributes accumulate in the redecl chain.
451928c8254SVassil Vassilev   if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>())
4528aefcbedSTanya Lattner     return true;
4538aefcbedSTanya Lattner 
454928c8254SVassil Vassilev   // The information may have not been deserialized yet. Force deserialization
455928c8254SVassil Vassilev   // to complete the needed information.
456928c8254SVassil Vassilev   return getMostRecentDecl()->getCanonicalDecl()->Used;
4578aefcbedSTanya Lattner }
4588aefcbedSTanya Lattner 
markUsed(ASTContext & C)459276dd188SEli Friedman void Decl::markUsed(ASTContext &C) {
460928c8254SVassil Vassilev   if (isUsed(false))
461276dd188SEli Friedman     return;
462276dd188SEli Friedman 
463276dd188SEli Friedman   if (C.getASTMutationListener())
464276dd188SEli Friedman     C.getASTMutationListener()->DeclarationMarkedUsed(this);
465276dd188SEli Friedman 
466928c8254SVassil Vassilev   setIsUsed();
467276dd188SEli Friedman }
468276dd188SEli Friedman 
isReferenced() const46916180230SArgyrios Kyrtzidis bool Decl::isReferenced() const {
47016180230SArgyrios Kyrtzidis   if (Referenced)
47116180230SArgyrios Kyrtzidis     return true;
47216180230SArgyrios Kyrtzidis 
47316180230SArgyrios Kyrtzidis   // Check redeclarations.
4742a1ba94fSEugene Zelenko   for (const auto *I : redecls())
47516180230SArgyrios Kyrtzidis     if (I->Referenced)
47616180230SArgyrios Kyrtzidis       return true;
47716180230SArgyrios Kyrtzidis 
47816180230SArgyrios Kyrtzidis   return false;
47916180230SArgyrios Kyrtzidis }
48016180230SArgyrios Kyrtzidis 
getExternalSourceSymbolAttr() const48111d70483SArgyrios Kyrtzidis ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
48211d70483SArgyrios Kyrtzidis   const Decl *Definition = nullptr;
4832a1ba94fSEugene Zelenko   if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
48411d70483SArgyrios Kyrtzidis     Definition = ID->getDefinition();
4852a1ba94fSEugene Zelenko   } else if (auto *PD = dyn_cast<ObjCProtocolDecl>(this)) {
48611d70483SArgyrios Kyrtzidis     Definition = PD->getDefinition();
4872a1ba94fSEugene Zelenko   } else if (auto *TD = dyn_cast<TagDecl>(this)) {
48811d70483SArgyrios Kyrtzidis     Definition = TD->getDefinition();
48911d70483SArgyrios Kyrtzidis   }
49011d70483SArgyrios Kyrtzidis   if (!Definition)
49111d70483SArgyrios Kyrtzidis     Definition = this;
49211d70483SArgyrios Kyrtzidis 
49311d70483SArgyrios Kyrtzidis   if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())
49411d70483SArgyrios Kyrtzidis     return attr;
49511d70483SArgyrios Kyrtzidis   if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {
49611d70483SArgyrios Kyrtzidis     return dcd->getAttr<ExternalSourceSymbolAttr>();
49711d70483SArgyrios Kyrtzidis   }
49811d70483SArgyrios Kyrtzidis 
49911d70483SArgyrios Kyrtzidis   return nullptr;
50011d70483SArgyrios Kyrtzidis }
50111d70483SArgyrios Kyrtzidis 
hasDefiningAttr() const50285eda12dSDmitry Polukhin bool Decl::hasDefiningAttr() const {
503c45eaeabSJon Chesterfield   return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
504c45eaeabSJon Chesterfield          hasAttr<LoaderUninitializedAttr>();
50585eda12dSDmitry Polukhin }
50685eda12dSDmitry Polukhin 
getDefiningAttr() const50785eda12dSDmitry Polukhin const Attr *Decl::getDefiningAttr() const {
5082a1ba94fSEugene Zelenko   if (auto *AA = getAttr<AliasAttr>())
50985eda12dSDmitry Polukhin     return AA;
5102a1ba94fSEugene Zelenko   if (auto *IFA = getAttr<IFuncAttr>())
51185eda12dSDmitry Polukhin     return IFA;
512c45eaeabSJon Chesterfield   if (auto *NZA = getAttr<LoaderUninitializedAttr>())
513c45eaeabSJon Chesterfield     return NZA;
51485eda12dSDmitry Polukhin   return nullptr;
51585eda12dSDmitry Polukhin }
51685eda12dSDmitry Polukhin 
getRealizedPlatform(const AvailabilityAttr * A,const ASTContext & Context)517674d5792SBenjamin Kramer static StringRef getRealizedPlatform(const AvailabilityAttr *A,
518a8a372d8SAlex Lorenz                                      const ASTContext &Context) {
519a8a372d8SAlex Lorenz   // Check if this is an App Extension "platform", and if so chop off
520a8a372d8SAlex Lorenz   // the suffix for matching with the actual platform.
521a8a372d8SAlex Lorenz   StringRef RealizedPlatform = A->getPlatform()->getName();
522a8a372d8SAlex Lorenz   if (!Context.getLangOpts().AppExt)
523a8a372d8SAlex Lorenz     return RealizedPlatform;
524a8a372d8SAlex Lorenz   size_t suffix = RealizedPlatform.rfind("_app_extension");
525a8a372d8SAlex Lorenz   if (suffix != StringRef::npos)
526a8a372d8SAlex Lorenz     return RealizedPlatform.slice(0, suffix);
527a8a372d8SAlex Lorenz   return RealizedPlatform;
528a8a372d8SAlex Lorenz }
529a8a372d8SAlex Lorenz 
5309fc8faf9SAdrian Prantl /// Determine the availability of the given declaration based on
53120b2ebd7SDouglas Gregor /// the target platform.
53220b2ebd7SDouglas Gregor ///
53320b2ebd7SDouglas Gregor /// When it returns an availability result other than \c AR_Available,
53420b2ebd7SDouglas Gregor /// if the \p Message parameter is non-NULL, it will be set to a
53520b2ebd7SDouglas Gregor /// string describing why the entity is unavailable.
53620b2ebd7SDouglas Gregor ///
53720b2ebd7SDouglas Gregor /// FIXME: Make these strings localizable, since they end up in
53820b2ebd7SDouglas Gregor /// diagnostics.
CheckAvailability(ASTContext & Context,const AvailabilityAttr * A,std::string * Message,VersionTuple EnclosingVersion)53920b2ebd7SDouglas Gregor static AvailabilityResult CheckAvailability(ASTContext &Context,
54020b2ebd7SDouglas Gregor                                             const AvailabilityAttr *A,
54148c7cc9bSErik Pilkington                                             std::string *Message,
54248c7cc9bSErik Pilkington                                             VersionTuple EnclosingVersion) {
54348c7cc9bSErik Pilkington   if (EnclosingVersion.empty())
54448c7cc9bSErik Pilkington     EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();
54520b2ebd7SDouglas Gregor 
54648c7cc9bSErik Pilkington   if (EnclosingVersion.empty())
54720b2ebd7SDouglas Gregor     return AR_Available;
54820b2ebd7SDouglas Gregor 
549b111ec94SBob Wilson   StringRef ActualPlatform = A->getPlatform()->getName();
550b111ec94SBob Wilson   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
551b111ec94SBob Wilson 
55220b2ebd7SDouglas Gregor   // Match the platform name.
553a8a372d8SAlex Lorenz   if (getRealizedPlatform(A, Context) != TargetPlatform)
55420b2ebd7SDouglas Gregor     return AR_Available;
55520b2ebd7SDouglas Gregor 
556b111ec94SBob Wilson   StringRef PrettyPlatformName
557b111ec94SBob Wilson     = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
558b111ec94SBob Wilson 
559b111ec94SBob Wilson   if (PrettyPlatformName.empty())
560b111ec94SBob Wilson     PrettyPlatformName = ActualPlatform;
561b111ec94SBob Wilson 
56288d510daSFariborz Jahanian   std::string HintMessage;
56388d510daSFariborz Jahanian   if (!A->getMessage().empty()) {
56488d510daSFariborz Jahanian     HintMessage = " - ";
56588d510daSFariborz Jahanian     HintMessage += A->getMessage();
56688d510daSFariborz Jahanian   }
56788d510daSFariborz Jahanian 
5687ab142b5SDouglas Gregor   // Make sure that this declaration has not been marked 'unavailable'.
5697ab142b5SDouglas Gregor   if (A->getUnavailable()) {
5707ab142b5SDouglas Gregor     if (Message) {
5717ab142b5SDouglas Gregor       Message->clear();
5727ab142b5SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
57388d510daSFariborz Jahanian       Out << "not available on " << PrettyPlatformName
57488d510daSFariborz Jahanian           << HintMessage;
5757ab142b5SDouglas Gregor     }
5767ab142b5SDouglas Gregor 
5777ab142b5SDouglas Gregor     return AR_Unavailable;
5787ab142b5SDouglas Gregor   }
5797ab142b5SDouglas Gregor 
58020b2ebd7SDouglas Gregor   // Make sure that this declaration has already been introduced.
58120b2ebd7SDouglas Gregor   if (!A->getIntroduced().empty() &&
58248c7cc9bSErik Pilkington       EnclosingVersion < A->getIntroduced()) {
58320b2ebd7SDouglas Gregor     if (Message) {
58420b2ebd7SDouglas Gregor       Message->clear();
58520b2ebd7SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
5862618dbafSFariborz Jahanian       VersionTuple VTI(A->getIntroduced());
58720b2ebd7SDouglas Gregor       Out << "introduced in " << PrettyPlatformName << ' '
5882618dbafSFariborz Jahanian           << VTI << HintMessage;
58920b2ebd7SDouglas Gregor     }
59020b2ebd7SDouglas Gregor 
5915d6790c7SDuncan P. N. Exon Smith     return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced;
59220b2ebd7SDouglas Gregor   }
59320b2ebd7SDouglas Gregor 
59420b2ebd7SDouglas Gregor   // Make sure that this declaration hasn't been obsoleted.
59548c7cc9bSErik Pilkington   if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
59620b2ebd7SDouglas Gregor     if (Message) {
59720b2ebd7SDouglas Gregor       Message->clear();
59820b2ebd7SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
5992618dbafSFariborz Jahanian       VersionTuple VTO(A->getObsoleted());
60020b2ebd7SDouglas Gregor       Out << "obsoleted in " << PrettyPlatformName << ' '
6012618dbafSFariborz Jahanian           << VTO << HintMessage;
60220b2ebd7SDouglas Gregor     }
60320b2ebd7SDouglas Gregor 
60420b2ebd7SDouglas Gregor     return AR_Unavailable;
60520b2ebd7SDouglas Gregor   }
60620b2ebd7SDouglas Gregor 
60720b2ebd7SDouglas Gregor   // Make sure that this declaration hasn't been deprecated.
60848c7cc9bSErik Pilkington   if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
60920b2ebd7SDouglas Gregor     if (Message) {
61020b2ebd7SDouglas Gregor       Message->clear();
61120b2ebd7SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
6122618dbafSFariborz Jahanian       VersionTuple VTD(A->getDeprecated());
61320b2ebd7SDouglas Gregor       Out << "first deprecated in " << PrettyPlatformName << ' '
6142618dbafSFariborz Jahanian           << VTD << HintMessage;
61520b2ebd7SDouglas Gregor     }
61620b2ebd7SDouglas Gregor 
61720b2ebd7SDouglas Gregor     return AR_Deprecated;
61820b2ebd7SDouglas Gregor   }
61920b2ebd7SDouglas Gregor 
62020b2ebd7SDouglas Gregor   return AR_Available;
62120b2ebd7SDouglas Gregor }
62220b2ebd7SDouglas Gregor 
getAvailability(std::string * Message,VersionTuple EnclosingVersion,StringRef * RealizedPlatform) const62348c7cc9bSErik Pilkington AvailabilityResult Decl::getAvailability(std::string *Message,
624f4d4cfbeSAlex Lorenz                                          VersionTuple EnclosingVersion,
625f4d4cfbeSAlex Lorenz                                          StringRef *RealizedPlatform) const {
626ec599a90SDuncan P. N. Exon Smith   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
627f4d4cfbeSAlex Lorenz     return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
628f4d4cfbeSAlex Lorenz                                                     RealizedPlatform);
629ec599a90SDuncan P. N. Exon Smith 
63020b2ebd7SDouglas Gregor   AvailabilityResult Result = AR_Available;
63120b2ebd7SDouglas Gregor   std::string ResultMessage;
63220b2ebd7SDouglas Gregor 
633b97112e4SAaron Ballman   for (const auto *A : attrs()) {
634b97112e4SAaron Ballman     if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
63520b2ebd7SDouglas Gregor       if (Result >= AR_Deprecated)
63620b2ebd7SDouglas Gregor         continue;
63720b2ebd7SDouglas Gregor 
63820b2ebd7SDouglas Gregor       if (Message)
639adcd0268SBenjamin Kramer         ResultMessage = std::string(Deprecated->getMessage());
64020b2ebd7SDouglas Gregor 
64120b2ebd7SDouglas Gregor       Result = AR_Deprecated;
64220b2ebd7SDouglas Gregor       continue;
64320b2ebd7SDouglas Gregor     }
64420b2ebd7SDouglas Gregor 
645b97112e4SAaron Ballman     if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
64620b2ebd7SDouglas Gregor       if (Message)
647adcd0268SBenjamin Kramer         *Message = std::string(Unavailable->getMessage());
64820b2ebd7SDouglas Gregor       return AR_Unavailable;
64920b2ebd7SDouglas Gregor     }
65020b2ebd7SDouglas Gregor 
651b97112e4SAaron Ballman     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
65220b2ebd7SDouglas Gregor       AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
65348c7cc9bSErik Pilkington                                                 Message, EnclosingVersion);
65420b2ebd7SDouglas Gregor 
655f4d4cfbeSAlex Lorenz       if (AR == AR_Unavailable) {
656f4d4cfbeSAlex Lorenz         if (RealizedPlatform)
657f4d4cfbeSAlex Lorenz           *RealizedPlatform = Availability->getPlatform()->getName();
65820b2ebd7SDouglas Gregor         return AR_Unavailable;
659f4d4cfbeSAlex Lorenz       }
66020b2ebd7SDouglas Gregor 
66120b2ebd7SDouglas Gregor       if (AR > Result) {
66220b2ebd7SDouglas Gregor         Result = AR;
66320b2ebd7SDouglas Gregor         if (Message)
66420b2ebd7SDouglas Gregor           ResultMessage.swap(*Message);
66520b2ebd7SDouglas Gregor       }
66620b2ebd7SDouglas Gregor       continue;
66720b2ebd7SDouglas Gregor     }
66820b2ebd7SDouglas Gregor   }
66920b2ebd7SDouglas Gregor 
67020b2ebd7SDouglas Gregor   if (Message)
67120b2ebd7SDouglas Gregor     Message->swap(ResultMessage);
67220b2ebd7SDouglas Gregor   return Result;
67320b2ebd7SDouglas Gregor }
67420b2ebd7SDouglas Gregor 
getVersionIntroduced() const675a8a372d8SAlex Lorenz VersionTuple Decl::getVersionIntroduced() const {
676a8a372d8SAlex Lorenz   const ASTContext &Context = getASTContext();
677a8a372d8SAlex Lorenz   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
678a8a372d8SAlex Lorenz   for (const auto *A : attrs()) {
679a8a372d8SAlex Lorenz     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
680a8a372d8SAlex Lorenz       if (getRealizedPlatform(Availability, Context) != TargetPlatform)
681a8a372d8SAlex Lorenz         continue;
682a8a372d8SAlex Lorenz       if (!Availability->getIntroduced().empty())
683a8a372d8SAlex Lorenz         return Availability->getIntroduced();
684a8a372d8SAlex Lorenz     }
685a8a372d8SAlex Lorenz   }
6862a1ba94fSEugene Zelenko   return {};
687a8a372d8SAlex Lorenz }
688a8a372d8SAlex Lorenz 
canBeWeakImported(bool & IsDefinition) const68920b2ebd7SDouglas Gregor bool Decl::canBeWeakImported(bool &IsDefinition) const {
69020b2ebd7SDouglas Gregor   IsDefinition = false;
6915fb5df9cSJohn McCall 
6925fb5df9cSJohn McCall   // Variables, if they aren't definitions.
6932a1ba94fSEugene Zelenko   if (const auto *Var = dyn_cast<VarDecl>(this)) {
6946ae7e50bSRafael Espindola     if (Var->isThisDeclarationADefinition()) {
69520b2ebd7SDouglas Gregor       IsDefinition = true;
69620b2ebd7SDouglas Gregor       return false;
69720b2ebd7SDouglas Gregor     }
6985fb5df9cSJohn McCall     return true;
699c8d2ae52SKirill Bobyrev   }
7005fb5df9cSJohn McCall   // Functions, if they aren't definitions.
701c8d2ae52SKirill Bobyrev   if (const auto *FD = dyn_cast<FunctionDecl>(this)) {
70220b2ebd7SDouglas Gregor     if (FD->hasBody()) {
70320b2ebd7SDouglas Gregor       IsDefinition = true;
70420b2ebd7SDouglas Gregor       return false;
70520b2ebd7SDouglas Gregor     }
70620b2ebd7SDouglas Gregor     return true;
7075fb5df9cSJohn McCall 
708c8d2ae52SKirill Bobyrev   }
7095fb5df9cSJohn McCall   // Objective-C classes, if this is the non-fragile runtime.
710c8d2ae52SKirill Bobyrev   if (isa<ObjCInterfaceDecl>(this) &&
71118ac1632SJohn McCall              getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {
7125fb5df9cSJohn McCall     return true;
7135fb5df9cSJohn McCall   }
714c8d2ae52SKirill Bobyrev   // Nothing else.
715c8d2ae52SKirill Bobyrev   return false;
71620b2ebd7SDouglas Gregor }
71720b2ebd7SDouglas Gregor 
isWeakImported() const71820b2ebd7SDouglas Gregor bool Decl::isWeakImported() const {
71920b2ebd7SDouglas Gregor   bool IsDefinition;
72020b2ebd7SDouglas Gregor   if (!canBeWeakImported(IsDefinition))
72120b2ebd7SDouglas Gregor     return false;
72220b2ebd7SDouglas Gregor 
723913f6005SRichard Smith   for (const auto *A : getMostRecentDecl()->attrs()) {
724b97112e4SAaron Ballman     if (isa<WeakImportAttr>(A))
72520b2ebd7SDouglas Gregor       return true;
72620b2ebd7SDouglas Gregor 
727b97112e4SAaron Ballman     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
72848c7cc9bSErik Pilkington       if (CheckAvailability(getASTContext(), Availability, nullptr,
72948c7cc9bSErik Pilkington                             VersionTuple()) == AR_NotYetIntroduced)
73020b2ebd7SDouglas Gregor         return true;
73120b2ebd7SDouglas Gregor     }
73220b2ebd7SDouglas Gregor   }
73320b2ebd7SDouglas Gregor 
73420b2ebd7SDouglas Gregor   return false;
73520b2ebd7SDouglas Gregor }
7368aefcbedSTanya Lattner 
getIdentifierNamespaceForKind(Kind DeclKind)7378e097198SChris Lattner unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
7388e097198SChris Lattner   switch (DeclKind) {
7393f746828SJohn McCall     case Function:
740bc491203SRichard Smith     case CXXDeductionGuide:
7413f746828SJohn McCall     case CXXMethod:
7423f746828SJohn McCall     case CXXConstructor:
7435179eb78SRichard Smith     case ConstructorUsingShadow:
7443f746828SJohn McCall     case CXXDestructor:
7453f746828SJohn McCall     case CXXConversion:
7468e097198SChris Lattner     case EnumConstant:
7478e097198SChris Lattner     case Var:
7488e097198SChris Lattner     case ImplicitParam:
7498e097198SChris Lattner     case ParmVar:
7508e097198SChris Lattner     case ObjCMethod:
75145b2d8abSDaniel Dunbar     case ObjCProperty:
7525e77d76cSJohn McCall     case MSProperty:
75345b2d8abSDaniel Dunbar       return IDNS_Ordinary;
754c8e630e4SChris Lattner     case Label:
755c8e630e4SChris Lattner       return IDNS_Label;
756783dd6ecSFrancois Pichet     case IndirectField:
757783dd6ecSFrancois Pichet       return IDNS_Ordinary | IDNS_Member;
758783dd6ecSFrancois Pichet 
759b8c41908SRichard Smith     case Binding:
7609f951826SRichard Smith     case NonTypeTemplateParm:
761b8c41908SRichard Smith     case VarTemplate:
762d7aae33aSSaar Raz     case Concept:
763b8c41908SRichard Smith       // These (C++-only) declarations are found by redeclaration lookup for
764b8c41908SRichard Smith       // tag types, so we include them in the tag namespace.
7659f951826SRichard Smith       return IDNS_Ordinary | IDNS_Tag;
7669f951826SRichard Smith 
767e87beb25SJohn McCall     case ObjCCompatibleAlias:
768e87beb25SJohn McCall     case ObjCInterface:
769e87beb25SJohn McCall       return IDNS_Ordinary | IDNS_Type;
770e87beb25SJohn McCall 
771e87beb25SJohn McCall     case Typedef:
772dda56e4bSRichard Smith     case TypeAlias:
773e87beb25SJohn McCall     case TemplateTypeParm:
77485f3f951SDouglas Gregor     case ObjCTypeParam:
775e87beb25SJohn McCall       return IDNS_Ordinary | IDNS_Type;
776e87beb25SJohn McCall 
777151c4568SRichard Smith     case UnresolvedUsingTypename:
778151c4568SRichard Smith       return IDNS_Ordinary | IDNS_Type | IDNS_Using;
779151c4568SRichard Smith 
7803f746828SJohn McCall     case UsingShadow:
7813f746828SJohn McCall       return 0; // we'll actually overwrite this later
7823f746828SJohn McCall 
783e61f2ba7SJohn McCall     case UnresolvedUsingValue:
784e61f2ba7SJohn McCall       return IDNS_Ordinary | IDNS_Using;
7853f746828SJohn McCall 
7863f746828SJohn McCall     case Using:
787151c4568SRichard Smith     case UsingPack:
788b2d0c16eSNathan Sidwell     case UsingEnum:
7893f746828SJohn McCall       return IDNS_Using;
7903f746828SJohn McCall 
7918e097198SChris Lattner     case ObjCProtocol:
79279947a24SDouglas Gregor       return IDNS_ObjCProtocol;
79379947a24SDouglas Gregor 
7948e097198SChris Lattner     case Field:
7958e097198SChris Lattner     case ObjCAtDefsField:
7968e097198SChris Lattner     case ObjCIvar:
7978e097198SChris Lattner       return IDNS_Member;
7988e097198SChris Lattner 
7998e097198SChris Lattner     case Record:
8008e097198SChris Lattner     case CXXRecord:
8018e097198SChris Lattner     case Enum:
802e87beb25SJohn McCall       return IDNS_Tag | IDNS_Type;
8038e097198SChris Lattner 
8048e097198SChris Lattner     case Namespace:
805e87beb25SJohn McCall     case NamespaceAlias:
806e87beb25SJohn McCall       return IDNS_Namespace;
807e87beb25SJohn McCall 
8088e097198SChris Lattner     case FunctionTemplate:
809e87beb25SJohn McCall       return IDNS_Ordinary;
810e87beb25SJohn McCall 
8118e097198SChris Lattner     case ClassTemplate:
8128e097198SChris Lattner     case TemplateTemplateParm:
813b8c41908SRichard Smith     case TypeAliasTemplate:
814e87beb25SJohn McCall       return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
8158e097198SChris Lattner 
816369c6483SErik Pilkington     case UnresolvedUsingIfExists:
817369c6483SErik Pilkington       return IDNS_Type | IDNS_Ordinary;
818369c6483SErik Pilkington 
81994a4f0cbSAlexey Bataev     case OMPDeclareReduction:
82094a4f0cbSAlexey Bataev       return IDNS_OMPReduction;
82194a4f0cbSAlexey Bataev 
822251e1488SMichael Kruse     case OMPDeclareMapper:
823251e1488SMichael Kruse       return IDNS_OMPMapper;
824251e1488SMichael Kruse 
8258e097198SChris Lattner     // Never have names.
826aa74a0c3SJohn McCall     case Friend:
82711083da4SJohn McCall     case FriendTemplate:
828d7340582SAbramo Bagnara     case AccessSpec:
8298e097198SChris Lattner     case LinkageSpec:
8308df390f9SRichard Smith     case Export:
8318e097198SChris Lattner     case FileScopeAsm:
8328e097198SChris Lattner     case StaticAssert:
8338e097198SChris Lattner     case ObjCPropertyImpl:
8346622029dSNico Weber     case PragmaComment:
835cbbaeb13SNico Weber     case PragmaDetectMismatch:
8368e097198SChris Lattner     case Block:
8376dfa25a1STareq A. Siraj     case Captured:
8388e097198SChris Lattner     case TranslationUnit:
839f19e1279SRichard Smith     case ExternCContext:
840bdb84f37SRichard Smith     case Decomposition:
841bab6df86SRichard Smith     case MSGuid:
842d6148749SJames Y Knight     case UnnamedGlobalConstant:
843ba4768c9SRichard Smith     case TemplateParamObject:
8448e097198SChris Lattner 
8458e097198SChris Lattner     case UsingDirective:
846d9b1a4fbSDavid Majnemer     case BuiltinTemplate:
8478e097198SChris Lattner     case ClassTemplateSpecialization:
8482373c599SDouglas Gregor     case ClassTemplatePartialSpecialization:
84900c7e6ceSFrancois Pichet     case ClassScopeFunctionSpecialization:
85039a1e507SLarisse Voufo     case VarTemplateSpecialization:
85139a1e507SLarisse Voufo     case VarTemplatePartialSpecialization:
852e93525edSDouglas Gregor     case ObjCImplementation:
853e93525edSDouglas Gregor     case ObjCCategory:
854e93525edSDouglas Gregor     case ObjCCategoryImpl:
855ba34552eSDouglas Gregor     case Import:
856a769e072SAlexey Bataev     case OMPThreadPrivate:
85725ed0c07SAlexey Bataev     case OMPAllocate:
8581408f91aSKelvin Li     case OMPRequires:
8594244be25SAlexey Bataev     case OMPCapturedExpr:
86084324357SMichael Han     case Empty:
861b0561b33STyker     case LifetimeExtendedTemporary:
862a0f50d73SSaar Raz     case RequiresExprBody:
863e93525edSDouglas Gregor       // Never looked up by name.
8648e097198SChris Lattner       return 0;
8658e097198SChris Lattner   }
8663f746828SJohn McCall 
867e4d798f0SDavid Blaikie   llvm_unreachable("Invalid DeclKind!");
8686301884dSArgyrios Kyrtzidis }
8696301884dSArgyrios Kyrtzidis 
setAttrsImpl(const AttrVec & attrs,ASTContext & Ctx)8706f40eb7eSArgyrios Kyrtzidis void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
87191167171SArgyrios Kyrtzidis   assert(!HasAttrs && "Decl already contains attrs.");
87291167171SArgyrios Kyrtzidis 
8736f40eb7eSArgyrios Kyrtzidis   AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
874dcfba7b3SAlexis Hunt   assert(AttrBlank.empty() && "HasAttrs was wrong?");
87591167171SArgyrios Kyrtzidis 
87691167171SArgyrios Kyrtzidis   AttrBlank = attrs;
87791167171SArgyrios Kyrtzidis   HasAttrs = true;
87891167171SArgyrios Kyrtzidis }
87991167171SArgyrios Kyrtzidis 
dropAttrs()880dcfba7b3SAlexis Hunt void Decl::dropAttrs() {
8816301884dSArgyrios Kyrtzidis   if (!HasAttrs) return;
8826301884dSArgyrios Kyrtzidis 
8836301884dSArgyrios Kyrtzidis   HasAttrs = false;
884b4b64ca7SArgyrios Kyrtzidis   getASTContext().eraseDeclAttrs(this);
8856301884dSArgyrios Kyrtzidis }
8866301884dSArgyrios Kyrtzidis 
addAttr(Attr * A)8874c99f5feSMichael Kruse void Decl::addAttr(Attr *A) {
8884c99f5feSMichael Kruse   if (!hasAttrs()) {
8894c99f5feSMichael Kruse     setAttrs(AttrVec(1, A));
8904c99f5feSMichael Kruse     return;
8914c99f5feSMichael Kruse   }
8924c99f5feSMichael Kruse 
8934c99f5feSMichael Kruse   AttrVec &Attrs = getAttrs();
8944c99f5feSMichael Kruse   if (!A->isInherited()) {
8954c99f5feSMichael Kruse     Attrs.push_back(A);
8964c99f5feSMichael Kruse     return;
8974c99f5feSMichael Kruse   }
8984c99f5feSMichael Kruse 
8994c99f5feSMichael Kruse   // Attribute inheritance is processed after attribute parsing. To keep the
9004c99f5feSMichael Kruse   // order as in the source code, add inherited attributes before non-inherited
9014c99f5feSMichael Kruse   // ones.
9024c99f5feSMichael Kruse   auto I = Attrs.begin(), E = Attrs.end();
9034c99f5feSMichael Kruse   for (; I != E; ++I) {
9044c99f5feSMichael Kruse     if (!(*I)->isInherited())
9054c99f5feSMichael Kruse       break;
9064c99f5feSMichael Kruse   }
9074c99f5feSMichael Kruse   Attrs.insert(I, A);
9084c99f5feSMichael Kruse }
9094c99f5feSMichael Kruse 
getAttrs() const910dcfba7b3SAlexis Hunt const AttrVec &Decl::getAttrs() const {
911dcfba7b3SAlexis Hunt   assert(HasAttrs && "No attrs to get!");
912b4b64ca7SArgyrios Kyrtzidis   return getASTContext().getDeclAttrs(this);
9136301884dSArgyrios Kyrtzidis }
9146301884dSArgyrios Kyrtzidis 
castFromDeclContext(const DeclContext * D)9153768ad6dSArgyrios Kyrtzidis Decl *Decl::castFromDeclContext (const DeclContext *D) {
916afe24c88SArgyrios Kyrtzidis   Decl::Kind DK = D->getDeclKind();
917afe24c88SArgyrios Kyrtzidis   switch(DK) {
918ed05325dSAlexis Hunt #define DECL(NAME, BASE)
919ed05325dSAlexis Hunt #define DECL_CONTEXT(NAME) \
920ed05325dSAlexis Hunt     case Decl::NAME:       \
921ed05325dSAlexis Hunt       return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
922ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)
923ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
924afe24c88SArgyrios Kyrtzidis     default:
925ed05325dSAlexis Hunt #define DECL(NAME, BASE)
926ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)                  \
927ed05325dSAlexis Hunt       if (DK >= first##NAME && DK <= last##NAME) \
928ed05325dSAlexis Hunt         return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
929ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
93083d382b1SDavid Blaikie       llvm_unreachable("a decl that inherits DeclContext isn't handled");
931afe24c88SArgyrios Kyrtzidis   }
9323768ad6dSArgyrios Kyrtzidis }
9333768ad6dSArgyrios Kyrtzidis 
castToDeclContext(const Decl * D)9343768ad6dSArgyrios Kyrtzidis DeclContext *Decl::castToDeclContext(const Decl *D) {
935afe24c88SArgyrios Kyrtzidis   Decl::Kind DK = D->getKind();
936afe24c88SArgyrios Kyrtzidis   switch(DK) {
937ed05325dSAlexis Hunt #define DECL(NAME, BASE)
938ed05325dSAlexis Hunt #define DECL_CONTEXT(NAME) \
939ed05325dSAlexis Hunt     case Decl::NAME:       \
940ed05325dSAlexis Hunt       return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
941ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)
942ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
943afe24c88SArgyrios Kyrtzidis     default:
944ed05325dSAlexis Hunt #define DECL(NAME, BASE)
945ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)                                   \
946ed05325dSAlexis Hunt       if (DK >= first##NAME && DK <= last##NAME)                  \
947ed05325dSAlexis Hunt         return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
948ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
94983d382b1SDavid Blaikie       llvm_unreachable("a decl that inherits DeclContext isn't handled");
950afe24c88SArgyrios Kyrtzidis   }
9513768ad6dSArgyrios Kyrtzidis }
9523768ad6dSArgyrios Kyrtzidis 
getBodyRBrace() const953ddcd132aSArgyrios Kyrtzidis SourceLocation Decl::getBodyRBrace() const {
95436ea3225SArgyrios Kyrtzidis   // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
95536ea3225SArgyrios Kyrtzidis   // FunctionDecl stores EndRangeLoc for this purpose.
9562a1ba94fSEugene Zelenko   if (const auto *FD = dyn_cast<FunctionDecl>(this)) {
95736ea3225SArgyrios Kyrtzidis     const FunctionDecl *Definition;
95836ea3225SArgyrios Kyrtzidis     if (FD->hasBody(Definition))
95936ea3225SArgyrios Kyrtzidis       return Definition->getSourceRange().getEnd();
9602a1ba94fSEugene Zelenko     return {};
96136ea3225SArgyrios Kyrtzidis   }
96236ea3225SArgyrios Kyrtzidis 
9636fbc8fa5SArgyrios Kyrtzidis   if (Stmt *Body = getBody())
9646fbc8fa5SArgyrios Kyrtzidis     return Body->getSourceRange().getEnd();
9656fbc8fa5SArgyrios Kyrtzidis 
9662a1ba94fSEugene Zelenko   return {};
967a7b98a77SSebastian Redl }
968a7b98a77SSebastian Redl 
AccessDeclContextCheck() const9695162b558SZarko Todorovski bool Decl::AccessDeclContextCheck() const {
9704b00d3b5SDouglas Gregor #ifndef NDEBUG
971401982f5SJohn McCall   // Suppress this check if any of the following hold:
972401982f5SJohn McCall   // 1. this is the translation unit (and thus has no parent)
973401982f5SJohn McCall   // 2. this is a template parameter (and thus doesn't belong to its context)
974e177863aSArgyrios Kyrtzidis   // 3. this is a non-type template parameter
975e177863aSArgyrios Kyrtzidis   // 4. the context is not a record
976e177863aSArgyrios Kyrtzidis   // 5. it's invalid
977e177863aSArgyrios Kyrtzidis   // 6. it's a C++0x static_assert.
978758d7a5aSRichard Trieu   // 7. it's a block literal declaration
979196cc96fSAdam Czachorowski   // 8. it's a temporary with lifetime extended due to being default value.
980196cc96fSAdam Czachorowski   if (isa<TranslationUnitDecl>(this) || isa<TemplateTypeParmDecl>(this) ||
981196cc96fSAdam Czachorowski       isa<NonTypeTemplateParmDecl>(this) || !getDeclContext() ||
982196cc96fSAdam Czachorowski       !isa<CXXRecordDecl>(getDeclContext()) || isInvalidDecl() ||
983196cc96fSAdam Czachorowski       isa<StaticAssertDecl>(this) || isa<BlockDecl>(this) ||
984260b4a8eSArgyrios Kyrtzidis       // FIXME: a ParmVarDecl can have ClassTemplateSpecialization
985260b4a8eSArgyrios Kyrtzidis       // as DeclContext (?).
986e177863aSArgyrios Kyrtzidis       isa<ParmVarDecl>(this) ||
987e177863aSArgyrios Kyrtzidis       // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have
988e177863aSArgyrios Kyrtzidis       // AS_none as access specifier.
98909af8c36SFrancois Pichet       isa<CXXRecordDecl>(this) ||
990196cc96fSAdam Czachorowski       isa<ClassScopeFunctionSpecializationDecl>(this) ||
991196cc96fSAdam Czachorowski       isa<LifetimeExtendedTemporaryDecl>(this))
992c1086768SAlp Toker     return true;
993adf36b23SAnders Carlsson 
994adf36b23SAnders Carlsson   assert(Access != AS_none &&
995a28908d5SAnders Carlsson          "Access specifier is AS_none inside a record decl");
9964b00d3b5SDouglas Gregor #endif
997c1086768SAlp Toker   return true;
998a28908d5SAnders Carlsson }
999a28908d5SAnders Carlsson 
isInExportDeclContext() const10003a3af2bbSChuanqi Xu bool Decl::isInExportDeclContext() const {
10013a3af2bbSChuanqi Xu   const DeclContext *DC = getLexicalDeclContext();
10023a3af2bbSChuanqi Xu 
10033a3af2bbSChuanqi Xu   while (DC && !isa<ExportDecl>(DC))
10043a3af2bbSChuanqi Xu     DC = DC->getLexicalParent();
10053a3af2bbSChuanqi Xu 
10063a3af2bbSChuanqi Xu   return DC && isa<ExportDecl>(DC);
10073a3af2bbSChuanqi Xu }
10083a3af2bbSChuanqi Xu 
getKind(const Decl * D)1009dec348f7SJohn McCall static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
getKind(const DeclContext * DC)1010dec348f7SJohn McCall static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
1011dec348f7SJohn McCall 
getID() const1012e3c99427SGeorge Karpenkov int64_t Decl::getID() const {
1013057647d8SArtem Dergachev   return getASTContext().getAllocator().identifyKnownAlignedObject<Decl>(this);
1014e3c99427SGeorge Karpenkov }
1015e3c99427SGeorge Karpenkov 
getFunctionType(bool BlocksToo) const101612b9f653SAaron Ballman const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
101712b9f653SAaron Ballman   QualType Ty;
10182a1ba94fSEugene Zelenko   if (const auto *D = dyn_cast<ValueDecl>(this))
101912b9f653SAaron Ballman     Ty = D->getType();
10202a1ba94fSEugene Zelenko   else if (const auto *D = dyn_cast<TypedefNameDecl>(this))
102112b9f653SAaron Ballman     Ty = D->getUnderlyingType();
102212b9f653SAaron Ballman   else
102336250ad6SCraig Topper     return nullptr;
102412b9f653SAaron Ballman 
102512b9f653SAaron Ballman   if (Ty->isFunctionPointerType())
102686976c91SSimon Pilgrim     Ty = Ty->castAs<PointerType>()->getPointeeType();
1027bf37536aSErich Keane   else if (Ty->isFunctionReferenceType())
102886976c91SSimon Pilgrim     Ty = Ty->castAs<ReferenceType>()->getPointeeType();
102912b9f653SAaron Ballman   else if (BlocksToo && Ty->isBlockPointerType())
103086976c91SSimon Pilgrim     Ty = Ty->castAs<BlockPointerType>()->getPointeeType();
103112b9f653SAaron Ballman 
103212b9f653SAaron Ballman   return Ty->getAs<FunctionType>();
103312b9f653SAaron Ballman }
103412b9f653SAaron Ballman 
1035dec348f7SJohn McCall /// Starting at a given context (a Decl or DeclContext), look for a
1036dec348f7SJohn McCall /// code context that is not a closure (a lambda, block, etc.).
getNonClosureContext(T * D)1037dec348f7SJohn McCall template <class T> static Decl *getNonClosureContext(T *D) {
1038dec348f7SJohn McCall   if (getKind(D) == Decl::CXXMethod) {
10392a1ba94fSEugene Zelenko     auto *MD = cast<CXXMethodDecl>(D);
104055c0ceecSJohn McCall     if (MD->getOverloadedOperator() == OO_Call &&
104155c0ceecSJohn McCall         MD->getParent()->isLambda())
1042dec348f7SJohn McCall       return getNonClosureContext(MD->getParent()->getParent());
1043dec348f7SJohn McCall     return MD;
1044c8d2ae52SKirill Bobyrev   }
1045c8d2ae52SKirill Bobyrev   if (auto *FD = dyn_cast<FunctionDecl>(D))
1046dec348f7SJohn McCall     return FD;
1047c8d2ae52SKirill Bobyrev   if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
1048dec348f7SJohn McCall     return MD;
1049c8d2ae52SKirill Bobyrev   if (auto *BD = dyn_cast<BlockDecl>(D))
1050dec348f7SJohn McCall     return getNonClosureContext(BD->getParent());
1051c8d2ae52SKirill Bobyrev   if (auto *CD = dyn_cast<CapturedDecl>(D))
1052dec348f7SJohn McCall     return getNonClosureContext(CD->getParent());
105336250ad6SCraig Topper   return nullptr;
1054dec348f7SJohn McCall }
1055fe96e0b6SJohn McCall 
getNonClosureContext()1056dec348f7SJohn McCall Decl *Decl::getNonClosureContext() {
1057dec348f7SJohn McCall   return ::getNonClosureContext(this);
1058dec348f7SJohn McCall }
1059b67608feSJohn McCall 
getNonClosureAncestor()1060dec348f7SJohn McCall Decl *DeclContext::getNonClosureAncestor() {
1061dec348f7SJohn McCall   return ::getNonClosureContext(this);
1062b67608feSJohn McCall }
1063a28908d5SAnders Carlsson 
10646301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
10656301884dSArgyrios Kyrtzidis // DeclContext Implementation
10666301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
10676301884dSArgyrios Kyrtzidis 
DeclContext(Decl::Kind K)1068f92f31c6SErich Keane DeclContext::DeclContext(Decl::Kind K) {
1069f92f31c6SErich Keane   DeclContextBits.DeclKind = K;
1070f92f31c6SErich Keane   setHasExternalLexicalStorage(false);
1071f92f31c6SErich Keane   setHasExternalVisibleStorage(false);
1072f92f31c6SErich Keane   setNeedToReconcileExternalVisibleStorage(false);
1073f92f31c6SErich Keane   setHasLazyLocalLexicalLookups(false);
1074f92f31c6SErich Keane   setHasLazyExternalLexicalLookups(false);
1075f92f31c6SErich Keane   setUseQualifiedLookup(false);
1076f92f31c6SErich Keane }
1077f92f31c6SErich Keane 
classof(const Decl * D)1078afe24c88SArgyrios Kyrtzidis bool DeclContext::classof(const Decl *D) {
1079afe24c88SArgyrios Kyrtzidis   switch (D->getKind()) {
1080ed05325dSAlexis Hunt #define DECL(NAME, BASE)
1081ed05325dSAlexis Hunt #define DECL_CONTEXT(NAME) case Decl::NAME:
1082ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)
1083ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1084afe24c88SArgyrios Kyrtzidis       return true;
1085afe24c88SArgyrios Kyrtzidis     default:
1086ed05325dSAlexis Hunt #define DECL(NAME, BASE)
1087ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)                 \
1088ed05325dSAlexis Hunt       if (D->getKind() >= Decl::first##NAME &&  \
1089ed05325dSAlexis Hunt           D->getKind() <= Decl::last##NAME)     \
1090afe24c88SArgyrios Kyrtzidis         return true;
1091ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1092afe24c88SArgyrios Kyrtzidis       return false;
1093afe24c88SArgyrios Kyrtzidis   }
1094afe24c88SArgyrios Kyrtzidis }
1095afe24c88SArgyrios Kyrtzidis 
10960d00c899SEugene Zelenko DeclContext::~DeclContext() = default;
109791f84216SDouglas Gregor 
10989fc8faf9SAdrian Prantl /// Find the parent context of this context that will be
10997f737c00SDouglas Gregor /// used for unqualified name lookup.
11007f737c00SDouglas Gregor ///
11017f737c00SDouglas Gregor /// Generally, the parent lookup context is the semantic context. However, for
11027f737c00SDouglas Gregor /// a friend function the parent lookup context is the lexical context, which
11037f737c00SDouglas Gregor /// is the class in which the friend is declared.
getLookupParent()11047f737c00SDouglas Gregor DeclContext *DeclContext::getLookupParent() {
1105cfd22580SBruno Ricci   // FIXME: Find a better way to identify friends.
11067f737c00SDouglas Gregor   if (isa<FunctionDecl>(this))
110750c68258SSebastian Redl     if (getParent()->getRedeclContext()->isFileContext() &&
110850c68258SSebastian Redl         getLexicalParent()->getRedeclContext()->isRecord())
11097f737c00SDouglas Gregor       return getLexicalParent();
11107f737c00SDouglas Gregor 
11117ac42374SRichard Smith   // A lookup within the call operator of a lambda never looks in the lambda
11127ac42374SRichard Smith   // class; instead, skip to the context in which that closure type is
11137ac42374SRichard Smith   // declared.
11147ac42374SRichard Smith   if (isLambdaCallOperator(this))
11157ac42374SRichard Smith     return getParent()->getParent();
11167ac42374SRichard Smith 
11177f737c00SDouglas Gregor   return getParent();
11187f737c00SDouglas Gregor }
11197f737c00SDouglas Gregor 
getInnermostBlockDecl() const1120f8268f67SAkira Hatanaka const BlockDecl *DeclContext::getInnermostBlockDecl() const {
1121f8268f67SAkira Hatanaka   const DeclContext *Ctx = this;
1122f8268f67SAkira Hatanaka 
1123f8268f67SAkira Hatanaka   do {
1124f8268f67SAkira Hatanaka     if (Ctx->isClosure())
1125f8268f67SAkira Hatanaka       return cast<BlockDecl>(Ctx);
1126f8268f67SAkira Hatanaka     Ctx = Ctx->getParent();
1127f8268f67SAkira Hatanaka   } while (Ctx);
1128f8268f67SAkira Hatanaka 
1129f8268f67SAkira Hatanaka   return nullptr;
1130f8268f67SAkira Hatanaka }
1131f8268f67SAkira Hatanaka 
isInlineNamespace() const1132bd595765SSebastian Redl bool DeclContext::isInlineNamespace() const {
1133bd595765SSebastian Redl   return isNamespace() &&
1134bd595765SSebastian Redl          cast<NamespaceDecl>(this)->isInline();
1135bd595765SSebastian Redl }
1136bd595765SSebastian Redl 
isStdNamespace() const1137c771d5d7SRichard Trieu bool DeclContext::isStdNamespace() const {
1138c771d5d7SRichard Trieu   if (!isNamespace())
1139c771d5d7SRichard Trieu     return false;
1140c771d5d7SRichard Trieu 
11412a1ba94fSEugene Zelenko   const auto *ND = cast<NamespaceDecl>(this);
1142c771d5d7SRichard Trieu   if (ND->isInline()) {
1143c771d5d7SRichard Trieu     return ND->getParent()->isStdNamespace();
1144c771d5d7SRichard Trieu   }
1145c771d5d7SRichard Trieu 
1146c771d5d7SRichard Trieu   if (!getParent()->getRedeclContext()->isTranslationUnit())
1147c771d5d7SRichard Trieu     return false;
1148c771d5d7SRichard Trieu 
1149c771d5d7SRichard Trieu   const IdentifierInfo *II = ND->getIdentifier();
1150c771d5d7SRichard Trieu   return II && II->isStr("std");
1151c771d5d7SRichard Trieu }
1152c771d5d7SRichard Trieu 
isDependentContext() const11539e927abcSDouglas Gregor bool DeclContext::isDependentContext() const {
11549e927abcSDouglas Gregor   if (isFileContext())
11559e927abcSDouglas Gregor     return false;
11569e927abcSDouglas Gregor 
11572373c599SDouglas Gregor   if (isa<ClassTemplatePartialSpecializationDecl>(this))
11582373c599SDouglas Gregor     return true;
11592373c599SDouglas Gregor 
11602a1ba94fSEugene Zelenko   if (const auto *Record = dyn_cast<CXXRecordDecl>(this)) {
11619e927abcSDouglas Gregor     if (Record->getDescribedClassTemplate())
11629e927abcSDouglas Gregor       return true;
11639e927abcSDouglas Gregor 
1164680e9e01SDouglas Gregor     if (Record->isDependentLambda())
1165680e9e01SDouglas Gregor       return true;
11663784e8ccSCorentin Jabot     if (Record->isNeverDependentLambda())
11673784e8ccSCorentin Jabot       return false;
1168680e9e01SDouglas Gregor   }
1169680e9e01SDouglas Gregor 
11702a1ba94fSEugene Zelenko   if (const auto *Function = dyn_cast<FunctionDecl>(this)) {
11719e927abcSDouglas Gregor     if (Function->getDescribedFunctionTemplate())
11729e927abcSDouglas Gregor       return true;
11739e927abcSDouglas Gregor 
1174c62bb64cSJohn McCall     // Friend function declarations are dependent if their *lexical*
1175c62bb64cSJohn McCall     // context is dependent.
1176c62bb64cSJohn McCall     if (cast<Decl>(this)->getFriendObjectKind())
1177c62bb64cSJohn McCall       return getLexicalParent()->isDependentContext();
1178c62bb64cSJohn McCall   }
1179c62bb64cSJohn McCall 
11802b560575SRichard Smith   // FIXME: A variable template is a dependent context, but is not a
11812b560575SRichard Smith   // DeclContext. A context within it (such as a lambda-expression)
11822b560575SRichard Smith   // should be considered dependent.
11832b560575SRichard Smith 
11849e927abcSDouglas Gregor   return getParent() && getParent()->isDependentContext();
11859e927abcSDouglas Gregor }
11869e927abcSDouglas Gregor 
isTransparentContext() const118707665a69SDouglas Gregor bool DeclContext::isTransparentContext() const {
1188f92f31c6SErich Keane   if (getDeclKind() == Decl::Enum)
11890bf31404SDouglas Gregor     return !cast<EnumDecl>(this)->isScoped();
119007665a69SDouglas Gregor 
11917e5d41a6SKirill Bobyrev   return getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export;
119207665a69SDouglas Gregor }
119307665a69SDouglas Gregor 
isLinkageSpecContext(const DeclContext * DC,LinkageSpecDecl::LanguageIDs ID)11943cb80228SSerge Pavlov static bool isLinkageSpecContext(const DeclContext *DC,
11953cb80228SSerge Pavlov                                  LinkageSpecDecl::LanguageIDs ID) {
11963cb80228SSerge Pavlov   while (DC->getDeclKind() != Decl::TranslationUnit) {
11973cb80228SSerge Pavlov     if (DC->getDeclKind() == Decl::LinkageSpec)
11983cb80228SSerge Pavlov       return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
1199ac9c9a00SRichard Smith     DC = DC->getLexicalParent();
12003cb80228SSerge Pavlov   }
12013cb80228SSerge Pavlov   return false;
12023cb80228SSerge Pavlov }
12033cb80228SSerge Pavlov 
isExternCContext() const12043cb80228SSerge Pavlov bool DeclContext::isExternCContext() const {
12050d00c899SEugene Zelenko   return isLinkageSpecContext(this, LinkageSpecDecl::lang_c);
12063cb80228SSerge Pavlov }
12073cb80228SSerge Pavlov 
getExternCContext() const1208560ae565SAlex Lorenz const LinkageSpecDecl *DeclContext::getExternCContext() const {
1209560ae565SAlex Lorenz   const DeclContext *DC = this;
1210560ae565SAlex Lorenz   while (DC->getDeclKind() != Decl::TranslationUnit) {
1211560ae565SAlex Lorenz     if (DC->getDeclKind() == Decl::LinkageSpec &&
12120d00c899SEugene Zelenko         cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecDecl::lang_c)
1213560ae565SAlex Lorenz       return cast<LinkageSpecDecl>(DC);
1214560ae565SAlex Lorenz     DC = DC->getLexicalParent();
1215560ae565SAlex Lorenz   }
1216560ae565SAlex Lorenz   return nullptr;
1217560ae565SAlex Lorenz }
1218560ae565SAlex Lorenz 
isExternCXXContext() const12193cb80228SSerge Pavlov bool DeclContext::isExternCXXContext() const {
12200d00c899SEugene Zelenko   return isLinkageSpecContext(this, LinkageSpecDecl::lang_cxx);
12213cb80228SSerge Pavlov }
12223cb80228SSerge Pavlov 
Encloses(const DeclContext * DC) const122350c68258SSebastian Redl bool DeclContext::Encloses(const DeclContext *DC) const {
1224e985a3b7SDouglas Gregor   if (getPrimaryContext() != this)
1225e985a3b7SDouglas Gregor     return getPrimaryContext()->Encloses(DC);
1226e985a3b7SDouglas Gregor 
1227e985a3b7SDouglas Gregor   for (; DC; DC = DC->getParent())
122886c5b870SChuanqi Xu     if (!isa<LinkageSpecDecl>(DC) && !isa<ExportDecl>(DC) &&
122986c5b870SChuanqi Xu         DC->getPrimaryContext() == this)
1230e985a3b7SDouglas Gregor       return true;
1231e985a3b7SDouglas Gregor   return false;
1232e985a3b7SDouglas Gregor }
1233e985a3b7SDouglas Gregor 
getNonTransparentContext()123448f73ee6SAaron Ballman DeclContext *DeclContext::getNonTransparentContext() {
123548f73ee6SAaron Ballman   DeclContext *DC = this;
123665bcdeaaSAaron Ballman   while (DC->isTransparentContext()) {
123748f73ee6SAaron Ballman     DC = DC->getParent();
123865bcdeaaSAaron Ballman     assert(DC && "All transparent contexts should have a parent!");
123965bcdeaaSAaron Ballman   }
124048f73ee6SAaron Ballman   return DC;
124148f73ee6SAaron Ballman }
124248f73ee6SAaron Ballman 
getPrimaryContext()124335c62ae6SSteve Naroff DeclContext *DeclContext::getPrimaryContext() {
1244f92f31c6SErich Keane   switch (getDeclKind()) {
1245f19e1279SRichard Smith   case Decl::ExternCContext:
124607665a69SDouglas Gregor   case Decl::LinkageSpec:
12478df390f9SRichard Smith   case Decl::Export:
124807665a69SDouglas Gregor   case Decl::Block:
12496dfa25a1STareq A. Siraj   case Decl::Captured:
125094a4f0cbSAlexey Bataev   case Decl::OMPDeclareReduction:
1251251e1488SMichael Kruse   case Decl::OMPDeclareMapper:
1252a0f50d73SSaar Raz   case Decl::RequiresExprBody:
125391f84216SDouglas Gregor     // There is only one DeclContext for these entities.
125491f84216SDouglas Gregor     return this;
125591f84216SDouglas Gregor 
125611b47c10SVassil Vassilev   case Decl::TranslationUnit:
125711b47c10SVassil Vassilev     return static_cast<TranslationUnitDecl *>(this)->getFirstDecl();
125891f84216SDouglas Gregor   case Decl::Namespace:
125991f84216SDouglas Gregor     // The original namespace is our primary context.
126091f84216SDouglas Gregor     return static_cast<NamespaceDecl *>(this)->getOriginalNamespace();
126191f84216SDouglas Gregor 
126291f84216SDouglas Gregor   case Decl::ObjCMethod:
126391f84216SDouglas Gregor     return this;
126491f84216SDouglas Gregor 
126591f84216SDouglas Gregor   case Decl::ObjCInterface:
1266f170dff3SDon Hinton     if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))
1267f170dff3SDon Hinton       if (auto *Def = OID->getDefinition())
126866b310c6SDouglas Gregor         return Def;
126966b310c6SDouglas Gregor     return this;
127066b310c6SDouglas Gregor 
127135c62ae6SSteve Naroff   case Decl::ObjCProtocol:
1272f170dff3SDon Hinton     if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))
1273f170dff3SDon Hinton       if (auto *Def = OPD->getDefinition())
1274a715bfffSDouglas Gregor         return Def;
1275a715bfffSDouglas Gregor     return this;
127666b310c6SDouglas Gregor 
127735c62ae6SSteve Naroff   case Decl::ObjCCategory:
127891f84216SDouglas Gregor     return this;
127991f84216SDouglas Gregor 
128035c62ae6SSteve Naroff   case Decl::ObjCImplementation:
128135c62ae6SSteve Naroff   case Decl::ObjCCategoryImpl:
128235c62ae6SSteve Naroff     return this;
128335c62ae6SSteve Naroff 
128491f84216SDouglas Gregor   default:
1285f92f31c6SErich Keane     if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
128667a65640SDouglas Gregor       // If this is a tag type that has a definition or is currently
128767a65640SDouglas Gregor       // being defined, that definition is our primary context.
12882a1ba94fSEugene Zelenko       auto *Tag = cast<TagDecl>(this);
1289e78aac41SJohn McCall 
1290e78aac41SJohn McCall       if (TagDecl *Def = Tag->getDefinition())
1291e78aac41SJohn McCall         return Def;
1292e78aac41SJohn McCall 
12932a1ba94fSEugene Zelenko       if (const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
12945b21db89SRichard Smith         // Note, TagType::getDecl returns the (partial) definition one exists.
12955b21db89SRichard Smith         TagDecl *PossiblePartialDef = TagTy->getDecl();
12965b21db89SRichard Smith         if (PossiblePartialDef->isBeingDefined())
12975b21db89SRichard Smith           return PossiblePartialDef;
12985b21db89SRichard Smith       } else {
12995b21db89SRichard Smith         assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1300e78aac41SJohn McCall       }
1301e78aac41SJohn McCall 
1302e78aac41SJohn McCall       return Tag;
130367a65640SDouglas Gregor     }
130467a65640SDouglas Gregor 
1305f92f31c6SErich Keane     assert(getDeclKind() >= Decl::firstFunction &&
1306f92f31c6SErich Keane            getDeclKind() <= Decl::lastFunction &&
130791f84216SDouglas Gregor           "Unknown DeclContext kind");
130891f84216SDouglas Gregor     return this;
130991f84216SDouglas Gregor   }
131091f84216SDouglas Gregor }
131191f84216SDouglas Gregor 
131211b47c10SVassil Vassilev template <typename T>
collectAllContextsImpl(T * Self,SmallVectorImpl<DeclContext * > & Contexts)131311b47c10SVassil Vassilev void collectAllContextsImpl(T *Self, SmallVectorImpl<DeclContext *> &Contexts) {
131411b47c10SVassil Vassilev   for (T *D = Self->getMostRecentDecl(); D; D = D->getPreviousDecl())
131511b47c10SVassil Vassilev     Contexts.push_back(D);
13165922f234SVassil Vassilev 
13175922f234SVassil Vassilev   std::reverse(Contexts.begin(), Contexts.end());
13186775fc6fSVassil Vassilev }
13196775fc6fSVassil Vassilev 
collectAllContexts(SmallVectorImpl<DeclContext * > & Contexts)132011b47c10SVassil Vassilev void DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts) {
132111b47c10SVassil Vassilev   Contexts.clear();
132211b47c10SVassil Vassilev 
132311b47c10SVassil Vassilev   Decl::Kind Kind = getDeclKind();
132411b47c10SVassil Vassilev 
132511b47c10SVassil Vassilev   if (Kind == Decl::TranslationUnit)
132611b47c10SVassil Vassilev     collectAllContextsImpl(static_cast<TranslationUnitDecl *>(this), Contexts);
132711b47c10SVassil Vassilev   else if (Kind == Decl::Namespace)
132811b47c10SVassil Vassilev     collectAllContextsImpl(static_cast<NamespaceDecl *>(this), Contexts);
132911b47c10SVassil Vassilev   else
133011b47c10SVassil Vassilev     Contexts.push_back(this);
133111b47c10SVassil Vassilev }
133211b47c10SVassil Vassilev 
13330e88a565SArgyrios Kyrtzidis std::pair<Decl *, Decl *>
BuildDeclChain(ArrayRef<Decl * > Decls,bool FieldsAlreadyLoaded)13348eb771d4SBill Wendling DeclContext::BuildDeclChain(ArrayRef<Decl *> Decls,
1335094da739SArgyrios Kyrtzidis                             bool FieldsAlreadyLoaded) {
1336781f713dSDouglas Gregor   // Build up a chain of declarations via the Decl::NextInContextAndBits field.
133736250ad6SCraig Topper   Decl *FirstNewDecl = nullptr;
133836250ad6SCraig Topper   Decl *PrevDecl = nullptr;
13392a1ba94fSEugene Zelenko   for (auto *D : Decls) {
13402a1ba94fSEugene Zelenko     if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1341094da739SArgyrios Kyrtzidis       continue;
1342094da739SArgyrios Kyrtzidis 
13430e88a565SArgyrios Kyrtzidis     if (PrevDecl)
1344781f713dSDouglas Gregor       PrevDecl->NextInContextAndBits.setPointer(D);
13450e88a565SArgyrios Kyrtzidis     else
13460e88a565SArgyrios Kyrtzidis       FirstNewDecl = D;
13470e88a565SArgyrios Kyrtzidis 
13480e88a565SArgyrios Kyrtzidis     PrevDecl = D;
13490e88a565SArgyrios Kyrtzidis   }
13500e88a565SArgyrios Kyrtzidis 
13510e88a565SArgyrios Kyrtzidis   return std::make_pair(FirstNewDecl, PrevDecl);
13520e88a565SArgyrios Kyrtzidis }
13530e88a565SArgyrios Kyrtzidis 
13549fc8faf9SAdrian Prantl /// We have just acquired external visible storage, and we already have
1355645d755dSRichard Smith /// built a lookup map. For every name in the map, pull in the new names from
1356645d755dSRichard Smith /// the external storage.
reconcileExternalVisibleStorage() const1357a8b74591SRichard Smith void DeclContext::reconcileExternalVisibleStorage() const {
1358f92f31c6SErich Keane   assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1359f92f31c6SErich Keane   setNeedToReconcileExternalVisibleStorage(false);
1360645d755dSRichard Smith 
13619e2341d0SRichard Smith   for (auto &Lookup : *LookupPtr)
1362a8b74591SRichard Smith     Lookup.second.setHasExternalDecls();
1363645d755dSRichard Smith }
1364645d755dSRichard Smith 
13659fc8faf9SAdrian Prantl /// Load the declarations within this lexical storage from an
1366ef84c4b4SDouglas Gregor /// external source.
136718b380b1SRichard Smith /// \return \c true if any declarations were added.
136818b380b1SRichard Smith bool
LoadLexicalDeclsFromExternalStorage() const1369cfbfe78eSArgyrios Kyrtzidis DeclContext::LoadLexicalDeclsFromExternalStorage() const {
1370cfbfe78eSArgyrios Kyrtzidis   ExternalASTSource *Source = getParentASTContext().getExternalSource();
1371ef84c4b4SDouglas Gregor   assert(hasExternalLexicalStorage() && Source && "No external storage?");
1372ef84c4b4SDouglas Gregor 
137398d045ebSArgyrios Kyrtzidis   // Notify that we have a DeclContext that is initializing.
137498d045ebSArgyrios Kyrtzidis   ExternalASTSource::Deserializing ADeclContext(Source);
137598d045ebSArgyrios Kyrtzidis 
13763d0adb32SDouglas Gregor   // Load the external declarations, if any.
13770e62c1ccSChris Lattner   SmallVector<Decl*, 64> Decls;
1378f92f31c6SErich Keane   setHasExternalLexicalStorage(false);
13793cb15729SRichard Smith   Source->FindExternalLexicalDecls(this, Decls);
1380ef84c4b4SDouglas Gregor 
1381ef84c4b4SDouglas Gregor   if (Decls.empty())
138218b380b1SRichard Smith     return false;
13839e2341d0SRichard Smith 
1384094da739SArgyrios Kyrtzidis   // We may have already loaded just the fields of this record, in which case
1385094da739SArgyrios Kyrtzidis   // we need to ignore them.
1386094da739SArgyrios Kyrtzidis   bool FieldsAlreadyLoaded = false;
13872a1ba94fSEugene Zelenko   if (const auto *RD = dyn_cast<RecordDecl>(this))
1388f92f31c6SErich Keane     FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1389094da739SArgyrios Kyrtzidis 
1390ef84c4b4SDouglas Gregor   // Splice the newly-read declarations into the beginning of the list
1391ef84c4b4SDouglas Gregor   // of declarations.
13920e88a565SArgyrios Kyrtzidis   Decl *ExternalFirst, *ExternalLast;
1393867ea1d4SBenjamin Kramer   std::tie(ExternalFirst, ExternalLast) =
1394867ea1d4SBenjamin Kramer       BuildDeclChain(Decls, FieldsAlreadyLoaded);
1395781f713dSDouglas Gregor   ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
13960e88a565SArgyrios Kyrtzidis   FirstDecl = ExternalFirst;
1397ef84c4b4SDouglas Gregor   if (!LastDecl)
13980e88a565SArgyrios Kyrtzidis     LastDecl = ExternalLast;
139918b380b1SRichard Smith   return true;
1400ef84c4b4SDouglas Gregor }
1401ef84c4b4SDouglas Gregor 
140275b960e5SJohn McCall DeclContext::lookup_result
SetNoExternalVisibleDeclsForName(const DeclContext * DC,DeclarationName Name)140375b960e5SJohn McCall ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
140475b960e5SJohn McCall                                                     DeclarationName Name) {
140575b960e5SJohn McCall   ASTContext &Context = DC->getParentASTContext();
140675b960e5SJohn McCall   StoredDeclsMap *Map;
14079e2341d0SRichard Smith   if (!(Map = DC->LookupPtr))
140875b960e5SJohn McCall     Map = DC->CreateStoredDeclsMap(Context);
1409f92f31c6SErich Keane   if (DC->hasNeedToReconcileExternalVisibleStorage())
1410a8b74591SRichard Smith     DC->reconcileExternalVisibleStorage();
1411ef84c4b4SDouglas Gregor 
14124abe0a8dSRichard Smith   (*Map)[Name].removeExternalDecls();
1413ef84c4b4SDouglas Gregor 
141475b960e5SJohn McCall   return DeclContext::lookup_result();
141575b960e5SJohn McCall }
1416ef84c4b4SDouglas Gregor 
141775b960e5SJohn McCall DeclContext::lookup_result
SetExternalVisibleDeclsForName(const DeclContext * DC,DeclarationName Name,ArrayRef<NamedDecl * > Decls)141875b960e5SJohn McCall ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
141975b960e5SJohn McCall                                                   DeclarationName Name,
142094d3f9dcSArgyrios Kyrtzidis                                                   ArrayRef<NamedDecl*> Decls) {
142176bb5cabSDmitri Gribenko   ASTContext &Context = DC->getParentASTContext();
142275b960e5SJohn McCall   StoredDeclsMap *Map;
14239e2341d0SRichard Smith   if (!(Map = DC->LookupPtr))
142475b960e5SJohn McCall     Map = DC->CreateStoredDeclsMap(Context);
1425f92f31c6SErich Keane   if (DC->hasNeedToReconcileExternalVisibleStorage())
1426a8b74591SRichard Smith     DC->reconcileExternalVisibleStorage();
142775b960e5SJohn McCall 
142875b960e5SJohn McCall   StoredDeclsList &List = (*Map)[Name];
14290cb7e7caSVassil Vassilev   List.replaceExternalDecls(Decls);
1430ba88bfabSArgyrios Kyrtzidis   return List.getLookupResult();
143175b960e5SJohn McCall }
143275b960e5SJohn McCall 
decls_begin() const1433da634f1dSAaron Ballman DeclContext::decl_iterator DeclContext::decls_begin() const {
1434da634f1dSAaron Ballman   if (hasExternalLexicalStorage())
1435da634f1dSAaron Ballman     LoadLexicalDeclsFromExternalStorage();
1436da634f1dSAaron Ballman   return decl_iterator(FirstDecl);
1437da634f1dSAaron Ballman }
1438da634f1dSAaron Ballman 
decls_empty() const1439cfbfe78eSArgyrios Kyrtzidis bool DeclContext::decls_empty() const {
14401e9bf3baSDouglas Gregor   if (hasExternalLexicalStorage())
1441cfbfe78eSArgyrios Kyrtzidis     LoadLexicalDeclsFromExternalStorage();
14421e9bf3baSDouglas Gregor 
14431e9bf3baSDouglas Gregor   return !FirstDecl;
14441e9bf3baSDouglas Gregor }
14451e9bf3baSDouglas Gregor 
containsDecl(Decl * D) const14460325fb85SSean Callanan bool DeclContext::containsDecl(Decl *D) const {
14470325fb85SSean Callanan   return (D->getLexicalDeclContext() == this &&
14480325fb85SSean Callanan           (D->NextInContextAndBits.getPointer() || D == LastDecl));
14490325fb85SSean Callanan }
14500325fb85SSean Callanan 
containsDeclAndLoad(Decl * D) const14515254e64aSGabor Marton bool DeclContext::containsDeclAndLoad(Decl *D) const {
14525254e64aSGabor Marton   if (hasExternalLexicalStorage())
14535254e64aSGabor Marton     LoadLexicalDeclsFromExternalStorage();
14545254e64aSGabor Marton   return containsDecl(D);
14555254e64aSGabor Marton }
14565254e64aSGabor Marton 
145761d862a9SGabor Marton /// shouldBeHidden - Determine whether a declaration which was declared
145861d862a9SGabor Marton /// within its semantic context should be invisible to qualified name lookup.
shouldBeHidden(NamedDecl * D)145961d862a9SGabor Marton static bool shouldBeHidden(NamedDecl *D) {
146061d862a9SGabor Marton   // Skip unnamed declarations.
146161d862a9SGabor Marton   if (!D->getDeclName())
146261d862a9SGabor Marton     return true;
146361d862a9SGabor Marton 
146461d862a9SGabor Marton   // Skip entities that can't be found by name lookup into a particular
146561d862a9SGabor Marton   // context.
146661d862a9SGabor Marton   if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
146761d862a9SGabor Marton       D->isTemplateParameter())
146861d862a9SGabor Marton     return true;
146961d862a9SGabor Marton 
14708ce732b4SRichard Smith   // Skip friends and local extern declarations unless they're the first
14718ce732b4SRichard Smith   // declaration of the entity.
14728ce732b4SRichard Smith   if ((D->isLocalExternDecl() || D->getFriendObjectKind()) &&
14738ce732b4SRichard Smith       D != D->getCanonicalDecl())
14748ce732b4SRichard Smith     return true;
14758ce732b4SRichard Smith 
147661d862a9SGabor Marton   // Skip template specializations.
147761d862a9SGabor Marton   // FIXME: This feels like a hack. Should DeclarationName support
147861d862a9SGabor Marton   // template-ids, or is there a better way to keep specializations
147961d862a9SGabor Marton   // from being visible?
148061d862a9SGabor Marton   if (isa<ClassTemplateSpecializationDecl>(D))
148161d862a9SGabor Marton     return true;
148261d862a9SGabor Marton   if (auto *FD = dyn_cast<FunctionDecl>(D))
148361d862a9SGabor Marton     if (FD->isFunctionTemplateSpecialization())
148461d862a9SGabor Marton       return true;
148561d862a9SGabor Marton 
1486eed0af61SAdam Czachorowski   // Hide destructors that are invalid. There should always be one destructor,
1487eed0af61SAdam Czachorowski   // but if it is an invalid decl, another one is created. We need to hide the
1488eed0af61SAdam Czachorowski   // invalid one from places that expect exactly one destructor, like the
1489eed0af61SAdam Czachorowski   // serialization code.
1490eed0af61SAdam Czachorowski   if (isa<CXXDestructorDecl>(D) && D->isInvalidDecl())
1491eed0af61SAdam Czachorowski     return true;
1492eed0af61SAdam Czachorowski 
149361d862a9SGabor Marton   return false;
149461d862a9SGabor Marton }
149561d862a9SGabor Marton 
removeDecl(Decl * D)149684d8767cSJohn McCall void DeclContext::removeDecl(Decl *D) {
149784d8767cSJohn McCall   assert(D->getLexicalDeclContext() == this &&
149884d8767cSJohn McCall          "decl being removed from non-lexical context");
1499781f713dSDouglas Gregor   assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
150084d8767cSJohn McCall          "decl is not in decls list");
150184d8767cSJohn McCall 
150284d8767cSJohn McCall   // Remove D from the decl chain.  This is O(n) but hopefully rare.
150384d8767cSJohn McCall   if (D == FirstDecl) {
150484d8767cSJohn McCall     if (D == LastDecl)
150536250ad6SCraig Topper       FirstDecl = LastDecl = nullptr;
150684d8767cSJohn McCall     else
1507781f713dSDouglas Gregor       FirstDecl = D->NextInContextAndBits.getPointer();
150884d8767cSJohn McCall   } else {
1509781f713dSDouglas Gregor     for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {
151084d8767cSJohn McCall       assert(I && "decl not found in linked list");
1511781f713dSDouglas Gregor       if (I->NextInContextAndBits.getPointer() == D) {
1512781f713dSDouglas Gregor         I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
151384d8767cSJohn McCall         if (D == LastDecl) LastDecl = I;
151484d8767cSJohn McCall         break;
151584d8767cSJohn McCall       }
151684d8767cSJohn McCall     }
151784d8767cSJohn McCall   }
151884d8767cSJohn McCall 
151984d8767cSJohn McCall   // Mark that D is no longer in the decl chain.
152036250ad6SCraig Topper   D->NextInContextAndBits.setPointer(nullptr);
152184d8767cSJohn McCall 
152284d8767cSJohn McCall   // Remove D from the lookup table if necessary.
152384d8767cSJohn McCall   if (isa<NamedDecl>(D)) {
15242a1ba94fSEugene Zelenko     auto *ND = cast<NamedDecl>(D);
152584d8767cSJohn McCall 
152661d862a9SGabor Marton     // Do not try to remove the declaration if that is invisible to qualified
152761d862a9SGabor Marton     // lookup.  E.g. template specializations are skipped.
152861d862a9SGabor Marton     if (shouldBeHidden(ND))
152961d862a9SGabor Marton       return;
153061d862a9SGabor Marton 
1531cb2c52f7SAxel Naumann     // Remove only decls that have a name
153261d862a9SGabor Marton     if (!ND->getDeclName())
153361d862a9SGabor Marton       return;
1534cb2c52f7SAxel Naumann 
15352e415980SVassil Vassilev     auto *DC = D->getDeclContext();
153626210db6SRichard Smith     do {
153726210db6SRichard Smith       StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr;
153826210db6SRichard Smith       if (Map) {
153984d8767cSJohn McCall         StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
154084d8767cSJohn McCall         assert(Pos != Map->end() && "no lookup entry for decl");
15418c0eb32dSVassil Vassilev         StoredDeclsList &List = Pos->second;
15428c0eb32dSVassil Vassilev         List.remove(ND);
15438c0eb32dSVassil Vassilev         // Clean up the entry if there are no more decls.
15448c0eb32dSVassil Vassilev         if (List.isNull())
15458c0eb32dSVassil Vassilev           Map->erase(Pos);
154684d8767cSJohn McCall       }
154726210db6SRichard Smith     } while (DC->isTransparentContext() && (DC = DC->getParent()));
154826210db6SRichard Smith   }
154984d8767cSJohn McCall }
155084d8767cSJohn McCall 
addHiddenDecl(Decl * D)1551d1e9d835SJohn McCall void DeclContext::addHiddenDecl(Decl *D) {
155233f219d1SChris Lattner   assert(D->getLexicalDeclContext() == this &&
155333f219d1SChris Lattner          "Decl inserted into wrong lexical context");
1554fcd33a68SChris Lattner   assert(!D->getNextDeclInContext() && D != LastDecl &&
1555020713e3SDouglas Gregor          "Decl already inserted into a DeclContext");
1556020713e3SDouglas Gregor 
1557020713e3SDouglas Gregor   if (FirstDecl) {
1558781f713dSDouglas Gregor     LastDecl->NextInContextAndBits.setPointer(D);
1559020713e3SDouglas Gregor     LastDecl = D;
1560020713e3SDouglas Gregor   } else {
1561020713e3SDouglas Gregor     FirstDecl = LastDecl = D;
1562020713e3SDouglas Gregor   }
1563d30e79f8SDouglas Gregor 
1564a1ce1f80SDouglas Gregor   // Notify a C++ record declaration that we've added a member, so it can
15654b81fc87SNick Lewycky   // update its class-specific state.
15662a1ba94fSEugene Zelenko   if (auto *Record = dyn_cast<CXXRecordDecl>(this))
1567a1ce1f80SDouglas Gregor     Record->addedMember(D);
15680f2a3607SDouglas Gregor 
15690f2a3607SDouglas Gregor   // If this is a newly-created (not de-serialized) import declaration, wire
15700f2a3607SDouglas Gregor   // it in to the list of local import declarations.
15710f2a3607SDouglas Gregor   if (!D->isFromASTFile()) {
15722a1ba94fSEugene Zelenko     if (auto *Import = dyn_cast<ImportDecl>(D))
15730f2a3607SDouglas Gregor       D->getASTContext().addedLocalImportDecl(Import);
15740f2a3607SDouglas Gregor   }
1575d1e9d835SJohn McCall }
1576d1e9d835SJohn McCall 
addDecl(Decl * D)1577d1e9d835SJohn McCall void DeclContext::addDecl(Decl *D) {
1578d1e9d835SJohn McCall   addHiddenDecl(D);
15796e6ad602SDouglas Gregor 
15802a1ba94fSEugene Zelenko   if (auto *ND = dyn_cast<NamedDecl>(D))
1581f634c900SRichard Smith     ND->getDeclContext()->getPrimaryContext()->
1582f634c900SRichard Smith         makeDeclVisibleInContextWithFlags(ND, false, true);
158391f84216SDouglas Gregor }
158491f84216SDouglas Gregor 
addDeclInternal(Decl * D)158595e74be1SSean Callanan void DeclContext::addDeclInternal(Decl *D) {
158695e74be1SSean Callanan   addHiddenDecl(D);
158795e74be1SSean Callanan 
15882a1ba94fSEugene Zelenko   if (auto *ND = dyn_cast<NamedDecl>(D))
1589f634c900SRichard Smith     ND->getDeclContext()->getPrimaryContext()->
1590f634c900SRichard Smith         makeDeclVisibleInContextWithFlags(ND, true, true);
1591f634c900SRichard Smith }
1592f634c900SRichard Smith 
1593f634c900SRichard Smith /// buildLookup - Build the lookup data structure with all of the
1594f634c900SRichard Smith /// declarations in this DeclContext (and any other contexts linked
1595f634c900SRichard Smith /// to it or transparent contexts nested within it) and return it.
1596a8b74591SRichard Smith ///
1597a8b74591SRichard Smith /// Note that the produced map may miss out declarations from an
1598a8b74591SRichard Smith /// external source. If it does, those entries will be marked with
1599a8b74591SRichard Smith /// the 'hasExternalDecls' flag.
buildLookup()1600f634c900SRichard Smith StoredDeclsMap *DeclContext::buildLookup() {
1601f634c900SRichard Smith   assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
1602f634c900SRichard Smith 
1603f92f31c6SErich Keane   if (!hasLazyLocalLexicalLookups() &&
1604f92f31c6SErich Keane       !hasLazyExternalLexicalLookups())
16059e2341d0SRichard Smith     return LookupPtr;
16069e2341d0SRichard Smith 
1607f857950dSDmitri Gribenko   SmallVector<DeclContext *, 2> Contexts;
1608f634c900SRichard Smith   collectAllContexts(Contexts);
160918b380b1SRichard Smith 
1610f92f31c6SErich Keane   if (hasLazyExternalLexicalLookups()) {
1611f92f31c6SErich Keane     setHasLazyExternalLexicalLookups(false);
161218b380b1SRichard Smith     for (auto *DC : Contexts) {
1613f92f31c6SErich Keane       if (DC->hasExternalLexicalStorage()) {
1614f92f31c6SErich Keane         bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1615f92f31c6SErich Keane         setHasLazyLocalLexicalLookups(
1616f92f31c6SErich Keane             hasLazyLocalLexicalLookups() | LoadedDecls );
1617f92f31c6SErich Keane       }
161818b380b1SRichard Smith     }
161918b380b1SRichard Smith 
1620f92f31c6SErich Keane     if (!hasLazyLocalLexicalLookups())
162118b380b1SRichard Smith       return LookupPtr;
162218b380b1SRichard Smith   }
162318b380b1SRichard Smith 
162418b380b1SRichard Smith   for (auto *DC : Contexts)
162518b380b1SRichard Smith     buildLookupImpl(DC, hasExternalVisibleStorage());
1626f634c900SRichard Smith 
1627f634c900SRichard Smith   // We no longer have any lazy decls.
1628f92f31c6SErich Keane   setHasLazyLocalLexicalLookups(false);
16299e2341d0SRichard Smith   return LookupPtr;
1630f634c900SRichard Smith }
1631f634c900SRichard Smith 
1632f634c900SRichard Smith /// buildLookupImpl - Build part of the lookup data structure for the
1633f634c900SRichard Smith /// declarations contained within DCtx, which will either be this
1634f634c900SRichard Smith /// DeclContext, a DeclContext linked to it, or a transparent context
1635f634c900SRichard Smith /// nested within it.
buildLookupImpl(DeclContext * DCtx,bool Internal)1636a3271c13SRichard Smith void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) {
16372a1ba94fSEugene Zelenko   for (auto *D : DCtx->noload_decls()) {
1638f634c900SRichard Smith     // Insert this declaration into the lookup structure, but only if
1639f634c900SRichard Smith     // it's semantically within its decl context. Any other decls which
1640f634c900SRichard Smith     // should be found in this context are added eagerly.
1641cf4ab520SRichard Smith     //
1642cf4ab520SRichard Smith     // If it's from an AST file, don't add it now. It'll get handled by
1643cf4ab520SRichard Smith     // FindExternalVisibleDeclsByName if needed. Exception: if we're not
1644cf4ab520SRichard Smith     // in C++, we do not track external visible decls for the TU, so in
1645cf4ab520SRichard Smith     // that case we need to collect them all here.
16462a1ba94fSEugene Zelenko     if (auto *ND = dyn_cast<NamedDecl>(D))
1647cf4ab520SRichard Smith       if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&
1648cf4ab520SRichard Smith           (!ND->isFromASTFile() ||
1649cf4ab520SRichard Smith            (isTranslationUnit() &&
1650cf4ab520SRichard Smith             !getParentASTContext().getLangOpts().CPlusPlus)))
1651a3271c13SRichard Smith         makeDeclVisibleInContextImpl(ND, Internal);
1652f634c900SRichard Smith 
1653f634c900SRichard Smith     // If this declaration is itself a transparent declaration context
1654f634c900SRichard Smith     // or inline namespace, add the members of this declaration of that
1655f634c900SRichard Smith     // context (recursively).
16562a1ba94fSEugene Zelenko     if (auto *InnerCtx = dyn_cast<DeclContext>(D))
1657f634c900SRichard Smith       if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
16589e2341d0SRichard Smith         buildLookupImpl(InnerCtx, Internal);
1659f634c900SRichard Smith   }
166095e74be1SSean Callanan }
166195e74be1SSean Callanan 
166291f84216SDouglas Gregor DeclContext::lookup_result
lookup(DeclarationName Name) const166340c78064SRichard Smith DeclContext::lookup(DeclarationName Name) const {
1664d9d63fc1SChuanqi Xu   // For transparent DeclContext, we should lookup in their enclosing context.
1665d9d63fc1SChuanqi Xu   if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
1666d9d63fc1SChuanqi Xu     return getParent()->lookup(Name);
16672bd636f5SNick Lewycky 
16687d2f5c4aSManman Ren   const DeclContext *PrimaryContext = getPrimaryContext();
16697d2f5c4aSManman Ren   if (PrimaryContext != this)
16707d2f5c4aSManman Ren     return PrimaryContext->lookup(Name);
16717d2f5c4aSManman Ren 
16728cebe37fSRichard Smith   // If we have an external source, ensure that any later redeclarations of this
16738cebe37fSRichard Smith   // context have been loaded, since they may add names to the result of this
16748cebe37fSRichard Smith   // lookup (or add external visible storage).
16758cebe37fSRichard Smith   ExternalASTSource *Source = getParentASTContext().getExternalSource();
16768cebe37fSRichard Smith   if (Source)
16778cebe37fSRichard Smith     (void)cast<Decl>(this)->getMostRecentDecl();
1678bb853c79SRichard Smith 
1679f634c900SRichard Smith   if (hasExternalVisibleStorage()) {
16808cebe37fSRichard Smith     assert(Source && "external visible storage but no external source?");
16818cebe37fSRichard Smith 
1682f92f31c6SErich Keane     if (hasNeedToReconcileExternalVisibleStorage())
1683a8b74591SRichard Smith       reconcileExternalVisibleStorage();
1684a8b74591SRichard Smith 
16859e2341d0SRichard Smith     StoredDeclsMap *Map = LookupPtr;
1686a8b74591SRichard Smith 
1687f92f31c6SErich Keane     if (hasLazyLocalLexicalLookups() ||
1688f92f31c6SErich Keane         hasLazyExternalLexicalLookups())
168940c78064SRichard Smith       // FIXME: Make buildLookup const?
169040c78064SRichard Smith       Map = const_cast<DeclContext*>(this)->buildLookup();
1691645d755dSRichard Smith 
169275fc3bf5SRichard Smith     if (!Map)
169375fc3bf5SRichard Smith       Map = CreateStoredDeclsMap(getParentASTContext());
169475fc3bf5SRichard Smith 
16954abe0a8dSRichard Smith     // If we have a lookup result with no external decls, we are done.
169675fc3bf5SRichard Smith     std::pair<StoredDeclsMap::iterator, bool> R =
169775fc3bf5SRichard Smith         Map->insert(std::make_pair(Name, StoredDeclsList()));
16984abe0a8dSRichard Smith     if (!R.second && !R.first->second.hasExternalDecls())
169975fc3bf5SRichard Smith       return R.first->second.getLookupResult();
1700f634c900SRichard Smith 
1701309271b0SRichard Smith     if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
17029e2341d0SRichard Smith       if (StoredDeclsMap *Map = LookupPtr) {
17039ce12e36SRichard Smith         StoredDeclsMap::iterator I = Map->find(Name);
17049ce12e36SRichard Smith         if (I != Map->end())
17059ce12e36SRichard Smith           return I->second.getLookupResult();
17069ce12e36SRichard Smith       }
17079ce12e36SRichard Smith     }
17089ce12e36SRichard Smith 
17092a1ba94fSEugene Zelenko     return {};
171075b960e5SJohn McCall   }
1711ef84c4b4SDouglas Gregor 
17129e2341d0SRichard Smith   StoredDeclsMap *Map = LookupPtr;
1713f92f31c6SErich Keane   if (hasLazyLocalLexicalLookups() ||
1714f92f31c6SErich Keane       hasLazyExternalLexicalLookups())
171540c78064SRichard Smith     Map = const_cast<DeclContext*>(this)->buildLookup();
1716f634c900SRichard Smith 
1717f634c900SRichard Smith   if (!Map)
17182a1ba94fSEugene Zelenko     return {};
1719f634c900SRichard Smith 
1720f634c900SRichard Smith   StoredDeclsMap::iterator I = Map->find(Name);
1721f634c900SRichard Smith   if (I == Map->end())
17222a1ba94fSEugene Zelenko     return {};
1723f634c900SRichard Smith 
1724f634c900SRichard Smith   return I->second.getLookupResult();
17259615ec20SDouglas Gregor }
17269615ec20SDouglas Gregor 
172795d99308SRichard Smith DeclContext::lookup_result
noload_lookup(DeclarationName Name)172895d99308SRichard Smith DeclContext::noload_lookup(DeclarationName Name) {
1729f92f31c6SErich Keane   assert(getDeclKind() != Decl::LinkageSpec &&
1730f92f31c6SErich Keane          getDeclKind() != Decl::Export &&
17318df390f9SRichard Smith          "should not perform lookups into transparent contexts");
173295d99308SRichard Smith 
173395d99308SRichard Smith   DeclContext *PrimaryContext = getPrimaryContext();
173495d99308SRichard Smith   if (PrimaryContext != this)
173595d99308SRichard Smith     return PrimaryContext->noload_lookup(Name);
173695d99308SRichard Smith 
1737091b1efaSSam McCall   loadLazyLocalLexicalLookups();
17389e2341d0SRichard Smith   StoredDeclsMap *Map = LookupPtr;
173995d99308SRichard Smith   if (!Map)
17402a1ba94fSEugene Zelenko     return {};
174195d99308SRichard Smith 
174295d99308SRichard Smith   StoredDeclsMap::iterator I = Map->find(Name);
174336250ad6SCraig Topper   return I != Map->end() ? I->second.getLookupResult()
174440c78064SRichard Smith                          : lookup_result();
174595d99308SRichard Smith }
174695d99308SRichard Smith 
1747091b1efaSSam McCall // If we have any lazy lexical declarations not in our lookup map, add them
1748091b1efaSSam McCall // now. Don't import any external declarations, not even if we know we have
1749091b1efaSSam McCall // some missing from the external visible lookups.
loadLazyLocalLexicalLookups()1750091b1efaSSam McCall void DeclContext::loadLazyLocalLexicalLookups() {
1751f92f31c6SErich Keane   if (hasLazyLocalLexicalLookups()) {
1752091b1efaSSam McCall     SmallVector<DeclContext *, 2> Contexts;
1753091b1efaSSam McCall     collectAllContexts(Contexts);
17542a1ba94fSEugene Zelenko     for (auto *Context : Contexts)
17552a1ba94fSEugene Zelenko       buildLookupImpl(Context, hasExternalVisibleStorage());
1756f92f31c6SErich Keane     setHasLazyLocalLexicalLookups(false);
1757091b1efaSSam McCall   }
1758091b1efaSSam McCall }
1759091b1efaSSam McCall 
localUncachedLookup(DeclarationName Name,SmallVectorImpl<NamedDecl * > & Results)17609e0a5b39SDouglas Gregor void DeclContext::localUncachedLookup(DeclarationName Name,
1761f857950dSDmitri Gribenko                                       SmallVectorImpl<NamedDecl *> &Results) {
17629e0a5b39SDouglas Gregor   Results.clear();
17639e0a5b39SDouglas Gregor 
17649e0a5b39SDouglas Gregor   // If there's no external storage, just perform a normal lookup and copy
17659e0a5b39SDouglas Gregor   // the results.
1766dd6006f3SDouglas Gregor   if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
17679e0a5b39SDouglas Gregor     lookup_result LookupResults = lookup(Name);
1768ff7d47a3SDavid Blaikie     Results.insert(Results.end(), LookupResults.begin(), LookupResults.end());
17699e0a5b39SDouglas Gregor     return;
17709e0a5b39SDouglas Gregor   }
17719e0a5b39SDouglas Gregor 
17729e0a5b39SDouglas Gregor   // If we have a lookup table, check there first. Maybe we'll get lucky.
17739e2341d0SRichard Smith   // FIXME: Should we be checking these flags on the primary context?
1774f92f31c6SErich Keane   if (Name && !hasLazyLocalLexicalLookups() &&
1775f92f31c6SErich Keane       !hasLazyExternalLexicalLookups()) {
17769e2341d0SRichard Smith     if (StoredDeclsMap *Map = LookupPtr) {
1777f634c900SRichard Smith       StoredDeclsMap::iterator Pos = Map->find(Name);
1778f634c900SRichard Smith       if (Pos != Map->end()) {
17799e0a5b39SDouglas Gregor         Results.insert(Results.end(),
1780ff7d47a3SDavid Blaikie                        Pos->second.getLookupResult().begin(),
1781ff7d47a3SDavid Blaikie                        Pos->second.getLookupResult().end());
17829e0a5b39SDouglas Gregor         return;
17839e0a5b39SDouglas Gregor       }
17849e0a5b39SDouglas Gregor     }
1785dd6006f3SDouglas Gregor   }
17869e0a5b39SDouglas Gregor 
17879e0a5b39SDouglas Gregor   // Slow case: grovel through the declarations in our chain looking for
17889e0a5b39SDouglas Gregor   // matches.
17899e2341d0SRichard Smith   // FIXME: If we have lazy external declarations, this will not find them!
17909e2341d0SRichard Smith   // FIXME: Should we CollectAllContexts and walk them all here?
17919e0a5b39SDouglas Gregor   for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {
17922a1ba94fSEugene Zelenko     if (auto *ND = dyn_cast<NamedDecl>(D))
17939e0a5b39SDouglas Gregor       if (ND->getDeclName() == Name)
17949e0a5b39SDouglas Gregor         Results.push_back(ND);
17959e0a5b39SDouglas Gregor   }
17969e0a5b39SDouglas Gregor }
17979e0a5b39SDouglas Gregor 
getRedeclContext()179850c68258SSebastian Redl DeclContext *DeclContext::getRedeclContext() {
179917a1bfa9SChris Lattner   DeclContext *Ctx = this;
18005e7b1eaeSAaron Ballman 
18015e7b1eaeSAaron Ballman   // In C, a record type is the redeclaration context for its fields only. If
18025e7b1eaeSAaron Ballman   // we arrive at a record context after skipping anything else, we should skip
18035e7b1eaeSAaron Ballman   // the record as well. Currently, this means skipping enumerations because
18045e7b1eaeSAaron Ballman   // they're the only transparent context that can exist within a struct or
18055e7b1eaeSAaron Ballman   // union.
18065e7b1eaeSAaron Ballman   bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
18075e7b1eaeSAaron Ballman                      !getParentASTContext().getLangOpts().CPlusPlus;
18085e7b1eaeSAaron Ballman 
18095e7b1eaeSAaron Ballman   // Skip through contexts to get to the redeclaration context. Transparent
18105e7b1eaeSAaron Ballman   // contexts are always skipped.
18115e7b1eaeSAaron Ballman   while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())
18126ad0ef50SDouglas Gregor     Ctx = Ctx->getParent();
18136ad0ef50SDouglas Gregor   return Ctx;
18146ad0ef50SDouglas Gregor }
18156ad0ef50SDouglas Gregor 
getEnclosingNamespaceContext()1816f47b911fSDouglas Gregor DeclContext *DeclContext::getEnclosingNamespaceContext() {
1817f47b911fSDouglas Gregor   DeclContext *Ctx = this;
1818f47b911fSDouglas Gregor   // Skip through non-namespace, non-translation-unit contexts.
18194f08c96aSSebastian Redl   while (!Ctx->isFileContext())
1820f47b911fSDouglas Gregor     Ctx = Ctx->getParent();
1821f47b911fSDouglas Gregor   return Ctx->getPrimaryContext();
1822f47b911fSDouglas Gregor }
1823f47b911fSDouglas Gregor 
getOuterLexicalRecordContext()1824d60b82f9SReid Kleckner RecordDecl *DeclContext::getOuterLexicalRecordContext() {
1825d60b82f9SReid Kleckner   // Loop until we find a non-record context.
1826d60b82f9SReid Kleckner   RecordDecl *OutermostRD = nullptr;
1827d60b82f9SReid Kleckner   DeclContext *DC = this;
1828d60b82f9SReid Kleckner   while (DC->isRecord()) {
1829d60b82f9SReid Kleckner     OutermostRD = cast<RecordDecl>(DC);
1830d60b82f9SReid Kleckner     DC = DC->getLexicalParent();
1831d60b82f9SReid Kleckner   }
1832d60b82f9SReid Kleckner   return OutermostRD;
1833d60b82f9SReid Kleckner }
1834d60b82f9SReid Kleckner 
InEnclosingNamespaceSetOf(const DeclContext * O) const183550c68258SSebastian Redl bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const {
183650c68258SSebastian Redl   // For non-file contexts, this is equivalent to Equals.
183750c68258SSebastian Redl   if (!isFileContext())
183850c68258SSebastian Redl     return O->Equals(this);
183950c68258SSebastian Redl 
184050c68258SSebastian Redl   do {
184150c68258SSebastian Redl     if (O->Equals(this))
184250c68258SSebastian Redl       return true;
184350c68258SSebastian Redl 
18442a1ba94fSEugene Zelenko     const auto *NS = dyn_cast<NamespaceDecl>(O);
184550c68258SSebastian Redl     if (!NS || !NS->isInline())
184650c68258SSebastian Redl       break;
184750c68258SSebastian Redl     O = NS->getParent();
184850c68258SSebastian Redl   } while (O);
184950c68258SSebastian Redl 
185050c68258SSebastian Redl   return false;
185150c68258SSebastian Redl }
185250c68258SSebastian Redl 
makeDeclVisibleInContext(NamedDecl * D)1853f634c900SRichard Smith void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
1854f634c900SRichard Smith   DeclContext *PrimaryDC = this->getPrimaryContext();
1855f634c900SRichard Smith   DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();
1856f634c900SRichard Smith   // If the decl is being added outside of its semantic decl context, we
1857f634c900SRichard Smith   // need to ensure that we eagerly build the lookup information for it.
1858f634c900SRichard Smith   PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);
185995e74be1SSean Callanan }
186095e74be1SSean Callanan 
makeDeclVisibleInContextWithFlags(NamedDecl * D,bool Internal,bool Recoverable)1861f634c900SRichard Smith void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
1862f634c900SRichard Smith                                                     bool Recoverable) {
1863f634c900SRichard Smith   assert(this == getPrimaryContext() && "expected a primary DC");
186495e74be1SSean Callanan 
186571eafdedSVassil Vassilev   if (!isLookupContext()) {
186671eafdedSVassil Vassilev     if (isTransparentContext())
186771eafdedSVassil Vassilev       getParent()->getPrimaryContext()
186871eafdedSVassil Vassilev         ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
186905afe5e0SRichard Smith     return;
187071eafdedSVassil Vassilev   }
187105afe5e0SRichard Smith 
1872f634c900SRichard Smith   // Skip declarations which should be invisible to name lookup.
1873f634c900SRichard Smith   if (shouldBeHidden(D))
1874f634c900SRichard Smith     return;
1875f634c900SRichard Smith 
1876f634c900SRichard Smith   // If we already have a lookup data structure, perform the insertion into
1877f634c900SRichard Smith   // it. If we might have externally-stored decls with this name, look them
1878f634c900SRichard Smith   // up and perform the insertion. If this decl was declared outside its
1879f634c900SRichard Smith   // semantic context, buildLookup won't add it, so add it now.
1880f634c900SRichard Smith   //
1881f634c900SRichard Smith   // FIXME: As a performance hack, don't add such decls into the translation
1882f634c900SRichard Smith   // unit unless we're in C++, since qualified lookup into the TU is never
1883f634c900SRichard Smith   // performed.
18849e2341d0SRichard Smith   if (LookupPtr || hasExternalVisibleStorage() ||
1885f634c900SRichard Smith       ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&
1886f634c900SRichard Smith        (getParentASTContext().getLangOpts().CPlusPlus ||
1887f634c900SRichard Smith         !isTranslationUnit()))) {
1888f634c900SRichard Smith     // If we have lazily omitted any decls, they might have the same name as
1889f634c900SRichard Smith     // the decl which we are adding, so build a full lookup table before adding
1890f634c900SRichard Smith     // this decl.
1891f634c900SRichard Smith     buildLookup();
1892f634c900SRichard Smith     makeDeclVisibleInContextImpl(D, Internal);
1893f634c900SRichard Smith   } else {
1894f92f31c6SErich Keane     setHasLazyLocalLexicalLookups(true);
1895f634c900SRichard Smith   }
1896f634c900SRichard Smith 
1897f634c900SRichard Smith   // If we are a transparent context or inline namespace, insert into our
1898f634c900SRichard Smith   // parent context, too. This operation is recursive.
1899f634c900SRichard Smith   if (isTransparentContext() || isInlineNamespace())
1900f634c900SRichard Smith     getParent()->getPrimaryContext()->
1901f634c900SRichard Smith         makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1902f634c900SRichard Smith 
19032a1ba94fSEugene Zelenko   auto *DCAsDecl = cast<Decl>(this);
1904f634c900SRichard Smith   // Notify that a decl was made visible unless we are a Tag being defined.
1905f634c900SRichard Smith   if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1906f634c900SRichard Smith     if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())
1907f634c900SRichard Smith       L->AddedVisibleDecl(this, D);
1908f634c900SRichard Smith }
1909f634c900SRichard Smith 
makeDeclVisibleInContextImpl(NamedDecl * D,bool Internal)1910f634c900SRichard Smith void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
1911f634c900SRichard Smith   // Find or create the stored declaration map.
19129e2341d0SRichard Smith   StoredDeclsMap *Map = LookupPtr;
1913f634c900SRichard Smith   if (!Map) {
1914f634c900SRichard Smith     ASTContext *C = &getParentASTContext();
1915f634c900SRichard Smith     Map = CreateStoredDeclsMap(*C);
1916e51e554aSArgyrios Kyrtzidis   }
1917e51e554aSArgyrios Kyrtzidis 
1918ba88bfabSArgyrios Kyrtzidis   // If there is an external AST source, load any declarations it knows about
1919ba88bfabSArgyrios Kyrtzidis   // with this declaration's name.
1920ba88bfabSArgyrios Kyrtzidis   // If the lookup table contains an entry about this name it means that we
1921ba88bfabSArgyrios Kyrtzidis   // have already checked the external source.
192295e74be1SSean Callanan   if (!Internal)
1923ba88bfabSArgyrios Kyrtzidis     if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
1924ba88bfabSArgyrios Kyrtzidis       if (hasExternalVisibleStorage() &&
1925f634c900SRichard Smith           Map->find(D->getDeclName()) == Map->end())
1926ba88bfabSArgyrios Kyrtzidis         Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
1927ba88bfabSArgyrios Kyrtzidis 
192891f84216SDouglas Gregor   // Insert this declaration into the map.
1929f634c900SRichard Smith   StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];
19304abe0a8dSRichard Smith 
19314abe0a8dSRichard Smith   if (Internal) {
19324abe0a8dSRichard Smith     // If this is being added as part of loading an external declaration,
19334abe0a8dSRichard Smith     // this may not be the only external declaration with this name.
19344abe0a8dSRichard Smith     // In this case, we never try to replace an existing declaration; we'll
19354abe0a8dSRichard Smith     // handle that when we finalize the list of declarations for this name.
19364abe0a8dSRichard Smith     DeclNameEntries.setHasExternalDecls();
19370cb7e7caSVassil Vassilev     DeclNameEntries.prependDeclNoReplace(D);
19384abe0a8dSRichard Smith     return;
19394abe0a8dSRichard Smith   }
19404abe0a8dSRichard Smith 
19410cb7e7caSVassil Vassilev   DeclNameEntries.addOrReplaceDecl(D);
194205afe5e0SRichard Smith }
194305afe5e0SRichard Smith 
operator *() const194440c78064SRichard Smith UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const {
194540c78064SRichard Smith   return cast<UsingDirectiveDecl>(*I);
194640c78064SRichard Smith }
194740c78064SRichard Smith 
1948889ceb75SDouglas Gregor /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
1949889ceb75SDouglas Gregor /// this context.
using_directives() const1950804a7fb7SAaron Ballman DeclContext::udir_range DeclContext::using_directives() const {
195105afe5e0SRichard Smith   // FIXME: Use something more efficient than normal lookup for using
195205afe5e0SRichard Smith   // directives. In C++, using directives are looked up more than anything else.
1953cf4bdde3SRichard Smith   lookup_result Result = lookup(UsingDirectiveDecl::getName());
195440c78064SRichard Smith   return udir_range(Result.begin(), Result.end());
1955889ceb75SDouglas Gregor }
1956ef84c4b4SDouglas Gregor 
1957da4e0d35STed Kremenek //===----------------------------------------------------------------------===//
1958da4e0d35STed Kremenek // Creation and Destruction of StoredDeclsMaps.                               //
1959da4e0d35STed Kremenek //===----------------------------------------------------------------------===//
1960da4e0d35STed Kremenek 
CreateStoredDeclsMap(ASTContext & C) const1961c62bb64cSJohn McCall StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {
19629e2341d0SRichard Smith   assert(!LookupPtr && "context already has a decls map");
1963c62bb64cSJohn McCall   assert(getPrimaryContext() == this &&
1964c62bb64cSJohn McCall          "creating decls map on non-primary context");
1965c62bb64cSJohn McCall 
1966c62bb64cSJohn McCall   StoredDeclsMap *M;
1967c62bb64cSJohn McCall   bool Dependent = isDependentContext();
1968c62bb64cSJohn McCall   if (Dependent)
1969c62bb64cSJohn McCall     M = new DependentStoredDeclsMap();
1970c62bb64cSJohn McCall   else
1971c62bb64cSJohn McCall     M = new StoredDeclsMap();
1972c62bb64cSJohn McCall   M->Previous = C.LastSDM;
1973c62bb64cSJohn McCall   C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
19749e2341d0SRichard Smith   LookupPtr = M;
1975da4e0d35STed Kremenek   return M;
1976da4e0d35STed Kremenek }
1977da4e0d35STed Kremenek 
ReleaseDeclContextMaps()1978da4e0d35STed Kremenek void ASTContext::ReleaseDeclContextMaps() {
1979c62bb64cSJohn McCall   // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap
1980c62bb64cSJohn McCall   // pointer because the subclass doesn't add anything that needs to
1981c62bb64cSJohn McCall   // be deleted.
1982c62bb64cSJohn McCall   StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());
1983d0a5f61cSArthur Eubanks   LastSDM.setPointer(nullptr);
1984c62bb64cSJohn McCall }
1985c62bb64cSJohn McCall 
DestroyAll(StoredDeclsMap * Map,bool Dependent)1986c62bb64cSJohn McCall void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {
1987c62bb64cSJohn McCall   while (Map) {
1988c62bb64cSJohn McCall     // Advance the iteration before we invalidate memory.
1989c62bb64cSJohn McCall     llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1990c62bb64cSJohn McCall 
1991c62bb64cSJohn McCall     if (Dependent)
1992c62bb64cSJohn McCall       delete static_cast<DependentStoredDeclsMap*>(Map);
1993c62bb64cSJohn McCall     else
1994c62bb64cSJohn McCall       delete Map;
1995c62bb64cSJohn McCall 
1996c62bb64cSJohn McCall     Map = Next.getPointer();
1997c62bb64cSJohn McCall     Dependent = Next.getInt();
1998c62bb64cSJohn McCall   }
1999c62bb64cSJohn McCall }
2000c62bb64cSJohn McCall 
Create(ASTContext & C,DeclContext * Parent,const PartialDiagnostic & PDiag)2001c62bb64cSJohn McCall DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
2002c62bb64cSJohn McCall                                                  DeclContext *Parent,
2003c62bb64cSJohn McCall                                            const PartialDiagnostic &PDiag) {
2004c62bb64cSJohn McCall   assert(Parent->isDependentContext()
2005c62bb64cSJohn McCall          && "cannot iterate dependent diagnostics of non-dependent context");
2006c62bb64cSJohn McCall   Parent = Parent->getPrimaryContext();
20079e2341d0SRichard Smith   if (!Parent->LookupPtr)
2008c62bb64cSJohn McCall     Parent->CreateStoredDeclsMap(C);
2009c62bb64cSJohn McCall 
20102a1ba94fSEugene Zelenko   auto *Map = static_cast<DependentStoredDeclsMap *>(Parent->LookupPtr);
2011c62bb64cSJohn McCall 
2012a55530e5SDouglas Gregor   // Allocate the copy of the PartialDiagnostic via the ASTContext's
20138933623bSDouglas Gregor   // BumpPtrAllocator, rather than the ASTContext itself.
20147e561b62SYaxun (Sam) Liu   DiagnosticStorage *DiagStorage = nullptr;
2015a55530e5SDouglas Gregor   if (PDiag.hasStorage())
20167e561b62SYaxun (Sam) Liu     DiagStorage = new (C) DiagnosticStorage;
2017a55530e5SDouglas Gregor 
20182a1ba94fSEugene Zelenko   auto *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);
2019c62bb64cSJohn McCall 
2020c62bb64cSJohn McCall   // TODO: Maybe we shouldn't reverse the order during insertion.
2021c62bb64cSJohn McCall   DD->NextDiagnostic = Map->FirstDiagnostic;
2022c62bb64cSJohn McCall   Map->FirstDiagnostic = DD;
2023c62bb64cSJohn McCall 
2024c62bb64cSJohn McCall   return DD;
2025da4e0d35STed Kremenek }
2026