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 
637dab26b8SDouglas 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 
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 
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 
114c147b0bcSDouglas Gregor Module *Decl::getOwningModuleSlow() const {
115c147b0bcSDouglas Gregor   assert(isFromASTFile() && "Not from AST file?");
116c147b0bcSDouglas Gregor   return getASTContext().getExternalSource()->getModule(getOwningModuleID());
117c147b0bcSDouglas Gregor }
118c147b0bcSDouglas Gregor 
11987bb5698SRichard Smith bool Decl::hasLocalOwningModuleStorage() const {
12026342f91SRichard Smith   return getASTContext().getLangOpts().trackLocalOwningModule();
12187bb5698SRichard Smith }
12287bb5698SRichard Smith 
1236301884dSArgyrios 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 
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 
1555faaef76SSteve 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;
16562905578SDaniel Dunbar void Decl::EnableStatistics() {
16662905578SDaniel Dunbar   StatisticsEnabled = true;
1676301884dSArgyrios Kyrtzidis }
1686301884dSArgyrios Kyrtzidis 
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 
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 
201aa73b913SAnders 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 
2113c6bd2adSDouglas 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 
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 
226990d5712SCaitlin Sadowski bool Decl::isTemplateDecl() const {
227990d5712SCaitlin Sadowski   return isa<TemplateDecl>(this);
228990d5712SCaitlin Sadowski }
229990d5712SCaitlin Sadowski 
2307dcc97e7SSerge Pavlov TemplateDecl *Decl::getDescribedTemplate() const {
2317dcc97e7SSerge Pavlov   if (auto *FD = dyn_cast<FunctionDecl>(this))
2327dcc97e7SSerge Pavlov     return FD->getDescribedFunctionTemplate();
2337dcc97e7SSerge Pavlov   else if (auto *RD = dyn_cast<CXXRecordDecl>(this))
2347dcc97e7SSerge Pavlov     return RD->getDescribedClassTemplate();
2357dcc97e7SSerge Pavlov   else if (auto *VD = dyn_cast<VarDecl>(this))
2367dcc97e7SSerge Pavlov     return VD->getDescribedVarTemplate();
23732b615c2SRichard Smith   else if (auto *AD = dyn_cast<TypeAliasDecl>(this))
23832b615c2SRichard Smith     return AD->getDescribedAliasTemplate();
2397dcc97e7SSerge Pavlov 
2407dcc97e7SSerge Pavlov   return nullptr;
2417dcc97e7SSerge Pavlov }
2427dcc97e7SSerge Pavlov 
24332b615c2SRichard Smith bool Decl::isTemplated() const {
24432b615c2SRichard Smith   // A declaration is dependent if it is a template or a template pattern, or
24532b615c2SRichard Smith   // is within (lexcially for a friend, semantically otherwise) a dependent
24632b615c2SRichard Smith   // context.
24732b615c2SRichard Smith   // FIXME: Should local extern declarations be treated like friends?
24832b615c2SRichard Smith   if (auto *AsDC = dyn_cast<DeclContext>(this))
24932b615c2SRichard Smith     return AsDC->isDependentContext();
25032b615c2SRichard Smith   auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
25132b615c2SRichard Smith   return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate();
25232b615c2SRichard Smith }
25332b615c2SRichard Smith 
2540ce4c9abSArgyrios Kyrtzidis const DeclContext *Decl::getParentFunctionOrMethod() const {
255f5974fa0SDouglas Gregor   for (const DeclContext *DC = getDeclContext();
2560ce4c9abSArgyrios Kyrtzidis        DC && !DC->isTranslationUnit() && !DC->isNamespace();
257f5974fa0SDouglas Gregor        DC = DC->getParent())
258f5974fa0SDouglas Gregor     if (DC->isFunctionOrMethod())
2590ce4c9abSArgyrios Kyrtzidis       return DC;
260f5974fa0SDouglas Gregor 
26136250ad6SCraig Topper   return nullptr;
262f5974fa0SDouglas Gregor }
263f5974fa0SDouglas Gregor 
2646301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
265eae6cb61SChris Lattner // PrettyStackTraceDecl Implementation
266eae6cb61SChris Lattner //===----------------------------------------------------------------------===//
267eae6cb61SChris Lattner 
2680e62c1ccSChris Lattner void PrettyStackTraceDecl::print(raw_ostream &OS) const {
269eae6cb61SChris Lattner   SourceLocation TheLoc = Loc;
270eae6cb61SChris Lattner   if (TheLoc.isInvalid() && TheDecl)
271eae6cb61SChris Lattner     TheLoc = TheDecl->getLocation();
272eae6cb61SChris Lattner 
273eae6cb61SChris Lattner   if (TheLoc.isValid()) {
274eae6cb61SChris Lattner     TheLoc.print(OS, SM);
275eae6cb61SChris Lattner     OS << ": ";
276eae6cb61SChris Lattner   }
277eae6cb61SChris Lattner 
278eae6cb61SChris Lattner   OS << Message;
279eae6cb61SChris Lattner 
2802a1ba94fSEugene Zelenko   if (const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
28124ebf7c9SBenjamin Kramer     OS << " '";
28224ebf7c9SBenjamin Kramer     DN->printQualifiedName(OS);
28324ebf7c9SBenjamin Kramer     OS << '\'';
28424ebf7c9SBenjamin Kramer   }
285eae6cb61SChris Lattner   OS << '\n';
286eae6cb61SChris Lattner }
287eae6cb61SChris Lattner 
288eae6cb61SChris Lattner //===----------------------------------------------------------------------===//
2896301884dSArgyrios Kyrtzidis // Decl Implementation
2906301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
2916301884dSArgyrios Kyrtzidis 
292b11aad8cSDouglas Gregor // Out-of-line virtual method providing a home for Decl.
2930d00c899SEugene Zelenko Decl::~Decl() = default;
294a43942a4SDouglas Gregor 
2956e6ad602SDouglas Gregor void Decl::setDeclContext(DeclContext *DC) {
296b81eb052SChris Lattner   DeclCtx = DC;
2976e6ad602SDouglas Gregor }
2986e6ad602SDouglas Gregor 
2996e6ad602SDouglas Gregor void Decl::setLexicalDeclContext(DeclContext *DC) {
3006e6ad602SDouglas Gregor   if (DC == getLexicalDeclContext())
3016e6ad602SDouglas Gregor     return;
3026e6ad602SDouglas Gregor 
3036e6ad602SDouglas Gregor   if (isInSemaDC()) {
3046f40eb7eSArgyrios Kyrtzidis     setDeclContextsImpl(getDeclContext(), DC, getASTContext());
3056e6ad602SDouglas Gregor   } else {
3066e6ad602SDouglas Gregor     getMultipleDC()->LexicalDC = DC;
3076e6ad602SDouglas Gregor   }
308ae50c56dSRichard Smith 
309ae50c56dSRichard Smith   // FIXME: We shouldn't be changing the lexical context of declarations
310ae50c56dSRichard Smith   // imported from AST files.
311ae50c56dSRichard Smith   if (!isFromASTFile()) {
31290dc5254SRichard Smith     setModuleOwnershipKind(getModuleOwnershipKindForChildOf(DC));
31390dc5254SRichard Smith     if (hasOwningModule())
31426342f91SRichard Smith       setLocalOwningModule(cast<Decl>(DC)->getOwningModule());
3156e6ad602SDouglas Gregor   }
3166e6ad602SDouglas Gregor 
317d19389a3SRichard Smith   assert(
318d19389a3SRichard Smith       (getModuleOwnershipKind() != ModuleOwnershipKind::VisibleWhenImported ||
319d19389a3SRichard Smith        getOwningModule()) &&
320ae50c56dSRichard Smith       "hidden declaration has no owning module");
321ae50c56dSRichard Smith }
322ae50c56dSRichard Smith 
3236f40eb7eSArgyrios Kyrtzidis void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
3246f40eb7eSArgyrios Kyrtzidis                                ASTContext &Ctx) {
3256f40eb7eSArgyrios Kyrtzidis   if (SemaDC == LexicalDC) {
3266f40eb7eSArgyrios Kyrtzidis     DeclCtx = SemaDC;
3276f40eb7eSArgyrios Kyrtzidis   } else {
3282a1ba94fSEugene Zelenko     auto *MDC = new (Ctx) Decl::MultipleDC();
3296f40eb7eSArgyrios Kyrtzidis     MDC->SemanticDC = SemaDC;
3306f40eb7eSArgyrios Kyrtzidis     MDC->LexicalDC = LexicalDC;
3316f40eb7eSArgyrios Kyrtzidis     DeclCtx = MDC;
3326f40eb7eSArgyrios Kyrtzidis   }
3336f40eb7eSArgyrios Kyrtzidis }
3346f40eb7eSArgyrios Kyrtzidis 
33573c6a244SSerge Pavlov bool Decl::isLexicallyWithinFunctionOrMethod() const {
33673c6a244SSerge Pavlov   const DeclContext *LDC = getLexicalDeclContext();
337b24a7111SSerge Pavlov   while (true) {
33873c6a244SSerge Pavlov     if (LDC->isFunctionOrMethod())
33973c6a244SSerge Pavlov       return true;
34073c6a244SSerge Pavlov     if (!isa<TagDecl>(LDC))
34173c6a244SSerge Pavlov       return false;
342b24a7111SSerge Pavlov     LDC = LDC->getLexicalParent();
343b24a7111SSerge Pavlov   }
34473c6a244SSerge Pavlov   return false;
34573c6a244SSerge Pavlov }
34673c6a244SSerge Pavlov 
3474fa53427SJohn McCall bool Decl::isInAnonymousNamespace() const {
348becb92deSRichard Smith   for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {
3492a1ba94fSEugene Zelenko     if (const auto *ND = dyn_cast<NamespaceDecl>(DC))
3504fa53427SJohn McCall       if (ND->isAnonymousNamespace())
3514fa53427SJohn McCall         return true;
352becb92deSRichard Smith   }
3534fa53427SJohn McCall 
3544fa53427SJohn McCall   return false;
3554fa53427SJohn McCall }
3564fa53427SJohn McCall 
357c771d5d7SRichard Trieu bool Decl::isInStdNamespace() const {
358b641b914SDmitri Gribenko   const DeclContext *DC = getDeclContext();
359b641b914SDmitri Gribenko   return DC && DC->isStdNamespace();
360c771d5d7SRichard Trieu }
361c771d5d7SRichard Trieu 
362743e7db7SArgyrios Kyrtzidis TranslationUnitDecl *Decl::getTranslationUnitDecl() {
3632a1ba94fSEugene Zelenko   if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
3644e1a72b3SArgyrios Kyrtzidis     return TUD;
3654e1a72b3SArgyrios Kyrtzidis 
366743e7db7SArgyrios Kyrtzidis   DeclContext *DC = getDeclContext();
367743e7db7SArgyrios Kyrtzidis   assert(DC && "This decl is not contained in a translation unit!");
368743e7db7SArgyrios Kyrtzidis 
369743e7db7SArgyrios Kyrtzidis   while (!DC->isTranslationUnit()) {
370743e7db7SArgyrios Kyrtzidis     DC = DC->getParent();
371743e7db7SArgyrios Kyrtzidis     assert(DC && "This decl is not contained in a translation unit!");
372743e7db7SArgyrios Kyrtzidis   }
373743e7db7SArgyrios Kyrtzidis 
374743e7db7SArgyrios Kyrtzidis   return cast<TranslationUnitDecl>(DC);
375743e7db7SArgyrios Kyrtzidis }
376743e7db7SArgyrios Kyrtzidis 
377743e7db7SArgyrios Kyrtzidis ASTContext &Decl::getASTContext() const {
378743e7db7SArgyrios Kyrtzidis   return getTranslationUnitDecl()->getASTContext();
379743e7db7SArgyrios Kyrtzidis }
380743e7db7SArgyrios Kyrtzidis 
381*b36c19bcSReid Kleckner /// Helper to get the language options from the ASTContext.
382*b36c19bcSReid Kleckner /// Defined out of line to avoid depending on ASTContext.h.
383*b36c19bcSReid Kleckner const LangOptions &Decl::getLangOpts() const {
384*b36c19bcSReid Kleckner   return getASTContext().getLangOpts();
385*b36c19bcSReid Kleckner }
386*b36c19bcSReid Kleckner 
38765ad5691SArgyrios Kyrtzidis ASTMutationListener *Decl::getASTMutationListener() const {
38865ad5691SArgyrios Kyrtzidis   return getASTContext().getASTMutationListener();
38965ad5691SArgyrios Kyrtzidis }
39065ad5691SArgyrios Kyrtzidis 
391ea70eb30SBenjamin Kramer unsigned Decl::getMaxAlignment() const {
392ea70eb30SBenjamin Kramer   if (!hasAttrs())
393ea70eb30SBenjamin Kramer     return 0;
394ea70eb30SBenjamin Kramer 
395ea70eb30SBenjamin Kramer   unsigned Align = 0;
396ea70eb30SBenjamin Kramer   const AttrVec &V = getAttrs();
397ea70eb30SBenjamin Kramer   ASTContext &Ctx = getASTContext();
398ea70eb30SBenjamin Kramer   specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());
399ea70eb30SBenjamin Kramer   for (; I != E; ++I)
400ea70eb30SBenjamin Kramer     Align = std::max(Align, I->getAlignment(Ctx));
401ea70eb30SBenjamin Kramer   return Align;
402ea70eb30SBenjamin Kramer }
403ea70eb30SBenjamin Kramer 
404ebada077SDouglas Gregor bool Decl::isUsed(bool CheckUsedAttr) const {
405928c8254SVassil Vassilev   const Decl *CanonD = getCanonicalDecl();
406928c8254SVassil Vassilev   if (CanonD->Used)
4078aefcbedSTanya Lattner     return true;
4088aefcbedSTanya Lattner 
4098aefcbedSTanya Lattner   // Check for used attribute.
410928c8254SVassil Vassilev   // Ask the most recent decl, since attributes accumulate in the redecl chain.
411928c8254SVassil Vassilev   if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>())
4128aefcbedSTanya Lattner     return true;
4138aefcbedSTanya Lattner 
414928c8254SVassil Vassilev   // The information may have not been deserialized yet. Force deserialization
415928c8254SVassil Vassilev   // to complete the needed information.
416928c8254SVassil Vassilev   return getMostRecentDecl()->getCanonicalDecl()->Used;
4178aefcbedSTanya Lattner }
4188aefcbedSTanya Lattner 
419276dd188SEli Friedman void Decl::markUsed(ASTContext &C) {
420928c8254SVassil Vassilev   if (isUsed(false))
421276dd188SEli Friedman     return;
422276dd188SEli Friedman 
423276dd188SEli Friedman   if (C.getASTMutationListener())
424276dd188SEli Friedman     C.getASTMutationListener()->DeclarationMarkedUsed(this);
425276dd188SEli Friedman 
426928c8254SVassil Vassilev   setIsUsed();
427276dd188SEli Friedman }
428276dd188SEli Friedman 
42916180230SArgyrios Kyrtzidis bool Decl::isReferenced() const {
43016180230SArgyrios Kyrtzidis   if (Referenced)
43116180230SArgyrios Kyrtzidis     return true;
43216180230SArgyrios Kyrtzidis 
43316180230SArgyrios Kyrtzidis   // Check redeclarations.
4342a1ba94fSEugene Zelenko   for (const auto *I : redecls())
43516180230SArgyrios Kyrtzidis     if (I->Referenced)
43616180230SArgyrios Kyrtzidis       return true;
43716180230SArgyrios Kyrtzidis 
43816180230SArgyrios Kyrtzidis   return false;
43916180230SArgyrios Kyrtzidis }
44016180230SArgyrios Kyrtzidis 
44111d70483SArgyrios Kyrtzidis ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
44211d70483SArgyrios Kyrtzidis   const Decl *Definition = nullptr;
4432a1ba94fSEugene Zelenko   if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
44411d70483SArgyrios Kyrtzidis     Definition = ID->getDefinition();
4452a1ba94fSEugene Zelenko   } else if (auto *PD = dyn_cast<ObjCProtocolDecl>(this)) {
44611d70483SArgyrios Kyrtzidis     Definition = PD->getDefinition();
4472a1ba94fSEugene Zelenko   } else if (auto *TD = dyn_cast<TagDecl>(this)) {
44811d70483SArgyrios Kyrtzidis     Definition = TD->getDefinition();
44911d70483SArgyrios Kyrtzidis   }
45011d70483SArgyrios Kyrtzidis   if (!Definition)
45111d70483SArgyrios Kyrtzidis     Definition = this;
45211d70483SArgyrios Kyrtzidis 
45311d70483SArgyrios Kyrtzidis   if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())
45411d70483SArgyrios Kyrtzidis     return attr;
45511d70483SArgyrios Kyrtzidis   if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {
45611d70483SArgyrios Kyrtzidis     return dcd->getAttr<ExternalSourceSymbolAttr>();
45711d70483SArgyrios Kyrtzidis   }
45811d70483SArgyrios Kyrtzidis 
45911d70483SArgyrios Kyrtzidis   return nullptr;
46011d70483SArgyrios Kyrtzidis }
46111d70483SArgyrios Kyrtzidis 
46285eda12dSDmitry Polukhin bool Decl::hasDefiningAttr() const {
463c45eaeabSJon Chesterfield   return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
464c45eaeabSJon Chesterfield          hasAttr<LoaderUninitializedAttr>();
46585eda12dSDmitry Polukhin }
46685eda12dSDmitry Polukhin 
46785eda12dSDmitry Polukhin const Attr *Decl::getDefiningAttr() const {
4682a1ba94fSEugene Zelenko   if (auto *AA = getAttr<AliasAttr>())
46985eda12dSDmitry Polukhin     return AA;
4702a1ba94fSEugene Zelenko   if (auto *IFA = getAttr<IFuncAttr>())
47185eda12dSDmitry Polukhin     return IFA;
472c45eaeabSJon Chesterfield   if (auto *NZA = getAttr<LoaderUninitializedAttr>())
473c45eaeabSJon Chesterfield     return NZA;
47485eda12dSDmitry Polukhin   return nullptr;
47585eda12dSDmitry Polukhin }
47685eda12dSDmitry Polukhin 
477674d5792SBenjamin Kramer static StringRef getRealizedPlatform(const AvailabilityAttr *A,
478a8a372d8SAlex Lorenz                                      const ASTContext &Context) {
479a8a372d8SAlex Lorenz   // Check if this is an App Extension "platform", and if so chop off
480a8a372d8SAlex Lorenz   // the suffix for matching with the actual platform.
481a8a372d8SAlex Lorenz   StringRef RealizedPlatform = A->getPlatform()->getName();
482a8a372d8SAlex Lorenz   if (!Context.getLangOpts().AppExt)
483a8a372d8SAlex Lorenz     return RealizedPlatform;
484a8a372d8SAlex Lorenz   size_t suffix = RealizedPlatform.rfind("_app_extension");
485a8a372d8SAlex Lorenz   if (suffix != StringRef::npos)
486a8a372d8SAlex Lorenz     return RealizedPlatform.slice(0, suffix);
487a8a372d8SAlex Lorenz   return RealizedPlatform;
488a8a372d8SAlex Lorenz }
489a8a372d8SAlex Lorenz 
4909fc8faf9SAdrian Prantl /// Determine the availability of the given declaration based on
49120b2ebd7SDouglas Gregor /// the target platform.
49220b2ebd7SDouglas Gregor ///
49320b2ebd7SDouglas Gregor /// When it returns an availability result other than \c AR_Available,
49420b2ebd7SDouglas Gregor /// if the \p Message parameter is non-NULL, it will be set to a
49520b2ebd7SDouglas Gregor /// string describing why the entity is unavailable.
49620b2ebd7SDouglas Gregor ///
49720b2ebd7SDouglas Gregor /// FIXME: Make these strings localizable, since they end up in
49820b2ebd7SDouglas Gregor /// diagnostics.
49920b2ebd7SDouglas Gregor static AvailabilityResult CheckAvailability(ASTContext &Context,
50020b2ebd7SDouglas Gregor                                             const AvailabilityAttr *A,
50148c7cc9bSErik Pilkington                                             std::string *Message,
50248c7cc9bSErik Pilkington                                             VersionTuple EnclosingVersion) {
50348c7cc9bSErik Pilkington   if (EnclosingVersion.empty())
50448c7cc9bSErik Pilkington     EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();
50520b2ebd7SDouglas Gregor 
50648c7cc9bSErik Pilkington   if (EnclosingVersion.empty())
50720b2ebd7SDouglas Gregor     return AR_Available;
50820b2ebd7SDouglas Gregor 
509b111ec94SBob Wilson   StringRef ActualPlatform = A->getPlatform()->getName();
510b111ec94SBob Wilson   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
511b111ec94SBob Wilson 
51220b2ebd7SDouglas Gregor   // Match the platform name.
513a8a372d8SAlex Lorenz   if (getRealizedPlatform(A, Context) != TargetPlatform)
51420b2ebd7SDouglas Gregor     return AR_Available;
51520b2ebd7SDouglas Gregor 
516b111ec94SBob Wilson   StringRef PrettyPlatformName
517b111ec94SBob Wilson     = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
518b111ec94SBob Wilson 
519b111ec94SBob Wilson   if (PrettyPlatformName.empty())
520b111ec94SBob Wilson     PrettyPlatformName = ActualPlatform;
521b111ec94SBob Wilson 
52288d510daSFariborz Jahanian   std::string HintMessage;
52388d510daSFariborz Jahanian   if (!A->getMessage().empty()) {
52488d510daSFariborz Jahanian     HintMessage = " - ";
52588d510daSFariborz Jahanian     HintMessage += A->getMessage();
52688d510daSFariborz Jahanian   }
52788d510daSFariborz Jahanian 
5287ab142b5SDouglas Gregor   // Make sure that this declaration has not been marked 'unavailable'.
5297ab142b5SDouglas Gregor   if (A->getUnavailable()) {
5307ab142b5SDouglas Gregor     if (Message) {
5317ab142b5SDouglas Gregor       Message->clear();
5327ab142b5SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
53388d510daSFariborz Jahanian       Out << "not available on " << PrettyPlatformName
53488d510daSFariborz Jahanian           << HintMessage;
5357ab142b5SDouglas Gregor     }
5367ab142b5SDouglas Gregor 
5377ab142b5SDouglas Gregor     return AR_Unavailable;
5387ab142b5SDouglas Gregor   }
5397ab142b5SDouglas Gregor 
54020b2ebd7SDouglas Gregor   // Make sure that this declaration has already been introduced.
54120b2ebd7SDouglas Gregor   if (!A->getIntroduced().empty() &&
54248c7cc9bSErik Pilkington       EnclosingVersion < A->getIntroduced()) {
54320b2ebd7SDouglas Gregor     if (Message) {
54420b2ebd7SDouglas Gregor       Message->clear();
54520b2ebd7SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
5462618dbafSFariborz Jahanian       VersionTuple VTI(A->getIntroduced());
54720b2ebd7SDouglas Gregor       Out << "introduced in " << PrettyPlatformName << ' '
5482618dbafSFariborz Jahanian           << VTI << HintMessage;
54920b2ebd7SDouglas Gregor     }
55020b2ebd7SDouglas Gregor 
5515d6790c7SDuncan P. N. Exon Smith     return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced;
55220b2ebd7SDouglas Gregor   }
55320b2ebd7SDouglas Gregor 
55420b2ebd7SDouglas Gregor   // Make sure that this declaration hasn't been obsoleted.
55548c7cc9bSErik Pilkington   if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
55620b2ebd7SDouglas Gregor     if (Message) {
55720b2ebd7SDouglas Gregor       Message->clear();
55820b2ebd7SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
5592618dbafSFariborz Jahanian       VersionTuple VTO(A->getObsoleted());
56020b2ebd7SDouglas Gregor       Out << "obsoleted in " << PrettyPlatformName << ' '
5612618dbafSFariborz Jahanian           << VTO << HintMessage;
56220b2ebd7SDouglas Gregor     }
56320b2ebd7SDouglas Gregor 
56420b2ebd7SDouglas Gregor     return AR_Unavailable;
56520b2ebd7SDouglas Gregor   }
56620b2ebd7SDouglas Gregor 
56720b2ebd7SDouglas Gregor   // Make sure that this declaration hasn't been deprecated.
56848c7cc9bSErik Pilkington   if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
56920b2ebd7SDouglas Gregor     if (Message) {
57020b2ebd7SDouglas Gregor       Message->clear();
57120b2ebd7SDouglas Gregor       llvm::raw_string_ostream Out(*Message);
5722618dbafSFariborz Jahanian       VersionTuple VTD(A->getDeprecated());
57320b2ebd7SDouglas Gregor       Out << "first deprecated in " << PrettyPlatformName << ' '
5742618dbafSFariborz Jahanian           << VTD << HintMessage;
57520b2ebd7SDouglas Gregor     }
57620b2ebd7SDouglas Gregor 
57720b2ebd7SDouglas Gregor     return AR_Deprecated;
57820b2ebd7SDouglas Gregor   }
57920b2ebd7SDouglas Gregor 
58020b2ebd7SDouglas Gregor   return AR_Available;
58120b2ebd7SDouglas Gregor }
58220b2ebd7SDouglas Gregor 
58348c7cc9bSErik Pilkington AvailabilityResult Decl::getAvailability(std::string *Message,
584f4d4cfbeSAlex Lorenz                                          VersionTuple EnclosingVersion,
585f4d4cfbeSAlex Lorenz                                          StringRef *RealizedPlatform) const {
586ec599a90SDuncan P. N. Exon Smith   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
587f4d4cfbeSAlex Lorenz     return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
588f4d4cfbeSAlex Lorenz                                                     RealizedPlatform);
589ec599a90SDuncan P. N. Exon Smith 
59020b2ebd7SDouglas Gregor   AvailabilityResult Result = AR_Available;
59120b2ebd7SDouglas Gregor   std::string ResultMessage;
59220b2ebd7SDouglas Gregor 
593b97112e4SAaron Ballman   for (const auto *A : attrs()) {
594b97112e4SAaron Ballman     if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
59520b2ebd7SDouglas Gregor       if (Result >= AR_Deprecated)
59620b2ebd7SDouglas Gregor         continue;
59720b2ebd7SDouglas Gregor 
59820b2ebd7SDouglas Gregor       if (Message)
599adcd0268SBenjamin Kramer         ResultMessage = std::string(Deprecated->getMessage());
60020b2ebd7SDouglas Gregor 
60120b2ebd7SDouglas Gregor       Result = AR_Deprecated;
60220b2ebd7SDouglas Gregor       continue;
60320b2ebd7SDouglas Gregor     }
60420b2ebd7SDouglas Gregor 
605b97112e4SAaron Ballman     if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
60620b2ebd7SDouglas Gregor       if (Message)
607adcd0268SBenjamin Kramer         *Message = std::string(Unavailable->getMessage());
60820b2ebd7SDouglas Gregor       return AR_Unavailable;
60920b2ebd7SDouglas Gregor     }
61020b2ebd7SDouglas Gregor 
611b97112e4SAaron Ballman     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
61220b2ebd7SDouglas Gregor       AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
61348c7cc9bSErik Pilkington                                                 Message, EnclosingVersion);
61420b2ebd7SDouglas Gregor 
615f4d4cfbeSAlex Lorenz       if (AR == AR_Unavailable) {
616f4d4cfbeSAlex Lorenz         if (RealizedPlatform)
617f4d4cfbeSAlex Lorenz           *RealizedPlatform = Availability->getPlatform()->getName();
61820b2ebd7SDouglas Gregor         return AR_Unavailable;
619f4d4cfbeSAlex Lorenz       }
62020b2ebd7SDouglas Gregor 
62120b2ebd7SDouglas Gregor       if (AR > Result) {
62220b2ebd7SDouglas Gregor         Result = AR;
62320b2ebd7SDouglas Gregor         if (Message)
62420b2ebd7SDouglas Gregor           ResultMessage.swap(*Message);
62520b2ebd7SDouglas Gregor       }
62620b2ebd7SDouglas Gregor       continue;
62720b2ebd7SDouglas Gregor     }
62820b2ebd7SDouglas Gregor   }
62920b2ebd7SDouglas Gregor 
63020b2ebd7SDouglas Gregor   if (Message)
63120b2ebd7SDouglas Gregor     Message->swap(ResultMessage);
63220b2ebd7SDouglas Gregor   return Result;
63320b2ebd7SDouglas Gregor }
63420b2ebd7SDouglas Gregor 
635a8a372d8SAlex Lorenz VersionTuple Decl::getVersionIntroduced() const {
636a8a372d8SAlex Lorenz   const ASTContext &Context = getASTContext();
637a8a372d8SAlex Lorenz   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
638a8a372d8SAlex Lorenz   for (const auto *A : attrs()) {
639a8a372d8SAlex Lorenz     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
640a8a372d8SAlex Lorenz       if (getRealizedPlatform(Availability, Context) != TargetPlatform)
641a8a372d8SAlex Lorenz         continue;
642a8a372d8SAlex Lorenz       if (!Availability->getIntroduced().empty())
643a8a372d8SAlex Lorenz         return Availability->getIntroduced();
644a8a372d8SAlex Lorenz     }
645a8a372d8SAlex Lorenz   }
6462a1ba94fSEugene Zelenko   return {};
647a8a372d8SAlex Lorenz }
648a8a372d8SAlex Lorenz 
64920b2ebd7SDouglas Gregor bool Decl::canBeWeakImported(bool &IsDefinition) const {
65020b2ebd7SDouglas Gregor   IsDefinition = false;
6515fb5df9cSJohn McCall 
6525fb5df9cSJohn McCall   // Variables, if they aren't definitions.
6532a1ba94fSEugene Zelenko   if (const auto *Var = dyn_cast<VarDecl>(this)) {
6546ae7e50bSRafael Espindola     if (Var->isThisDeclarationADefinition()) {
65520b2ebd7SDouglas Gregor       IsDefinition = true;
65620b2ebd7SDouglas Gregor       return false;
65720b2ebd7SDouglas Gregor     }
6585fb5df9cSJohn McCall     return true;
6595fb5df9cSJohn McCall 
6605fb5df9cSJohn McCall   // Functions, if they aren't definitions.
6612a1ba94fSEugene Zelenko   } else if (const auto *FD = dyn_cast<FunctionDecl>(this)) {
66220b2ebd7SDouglas Gregor     if (FD->hasBody()) {
66320b2ebd7SDouglas Gregor       IsDefinition = true;
66420b2ebd7SDouglas Gregor       return false;
66520b2ebd7SDouglas Gregor     }
66620b2ebd7SDouglas Gregor     return true;
6675fb5df9cSJohn McCall 
6685fb5df9cSJohn McCall   // Objective-C classes, if this is the non-fragile runtime.
6695fb5df9cSJohn McCall   } else if (isa<ObjCInterfaceDecl>(this) &&
67018ac1632SJohn McCall              getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {
6715fb5df9cSJohn McCall     return true;
6725fb5df9cSJohn McCall 
6735fb5df9cSJohn McCall   // Nothing else.
6745fb5df9cSJohn McCall   } else {
6755fb5df9cSJohn McCall     return false;
6765fb5df9cSJohn McCall   }
67720b2ebd7SDouglas Gregor }
67820b2ebd7SDouglas Gregor 
67920b2ebd7SDouglas Gregor bool Decl::isWeakImported() const {
68020b2ebd7SDouglas Gregor   bool IsDefinition;
68120b2ebd7SDouglas Gregor   if (!canBeWeakImported(IsDefinition))
68220b2ebd7SDouglas Gregor     return false;
68320b2ebd7SDouglas Gregor 
684b97112e4SAaron Ballman   for (const auto *A : attrs()) {
685b97112e4SAaron Ballman     if (isa<WeakImportAttr>(A))
68620b2ebd7SDouglas Gregor       return true;
68720b2ebd7SDouglas Gregor 
688b97112e4SAaron Ballman     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
68948c7cc9bSErik Pilkington       if (CheckAvailability(getASTContext(), Availability, nullptr,
69048c7cc9bSErik Pilkington                             VersionTuple()) == AR_NotYetIntroduced)
69120b2ebd7SDouglas Gregor         return true;
69220b2ebd7SDouglas Gregor     }
69320b2ebd7SDouglas Gregor   }
69420b2ebd7SDouglas Gregor 
69520b2ebd7SDouglas Gregor   return false;
69620b2ebd7SDouglas Gregor }
6978aefcbedSTanya Lattner 
6988e097198SChris Lattner unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
6998e097198SChris Lattner   switch (DeclKind) {
7003f746828SJohn McCall     case Function:
701bc491203SRichard Smith     case CXXDeductionGuide:
7023f746828SJohn McCall     case CXXMethod:
7033f746828SJohn McCall     case CXXConstructor:
7045179eb78SRichard Smith     case ConstructorUsingShadow:
7053f746828SJohn McCall     case CXXDestructor:
7063f746828SJohn McCall     case CXXConversion:
7078e097198SChris Lattner     case EnumConstant:
7088e097198SChris Lattner     case Var:
7098e097198SChris Lattner     case ImplicitParam:
7108e097198SChris Lattner     case ParmVar:
7118e097198SChris Lattner     case ObjCMethod:
71245b2d8abSDaniel Dunbar     case ObjCProperty:
7135e77d76cSJohn McCall     case MSProperty:
71445b2d8abSDaniel Dunbar       return IDNS_Ordinary;
715c8e630e4SChris Lattner     case Label:
716c8e630e4SChris Lattner       return IDNS_Label;
717783dd6ecSFrancois Pichet     case IndirectField:
718783dd6ecSFrancois Pichet       return IDNS_Ordinary | IDNS_Member;
719783dd6ecSFrancois Pichet 
720b8c41908SRichard Smith     case Binding:
7219f951826SRichard Smith     case NonTypeTemplateParm:
722b8c41908SRichard Smith     case VarTemplate:
723d7aae33aSSaar Raz     case Concept:
724b8c41908SRichard Smith       // These (C++-only) declarations are found by redeclaration lookup for
725b8c41908SRichard Smith       // tag types, so we include them in the tag namespace.
7269f951826SRichard Smith       return IDNS_Ordinary | IDNS_Tag;
7279f951826SRichard Smith 
728e87beb25SJohn McCall     case ObjCCompatibleAlias:
729e87beb25SJohn McCall     case ObjCInterface:
730e87beb25SJohn McCall       return IDNS_Ordinary | IDNS_Type;
731e87beb25SJohn McCall 
732e87beb25SJohn McCall     case Typedef:
733dda56e4bSRichard Smith     case TypeAlias:
734e87beb25SJohn McCall     case TemplateTypeParm:
73585f3f951SDouglas Gregor     case ObjCTypeParam:
736e87beb25SJohn McCall       return IDNS_Ordinary | IDNS_Type;
737e87beb25SJohn McCall 
738151c4568SRichard Smith     case UnresolvedUsingTypename:
739151c4568SRichard Smith       return IDNS_Ordinary | IDNS_Type | IDNS_Using;
740151c4568SRichard Smith 
7413f746828SJohn McCall     case UsingShadow:
7423f746828SJohn McCall       return 0; // we'll actually overwrite this later
7433f746828SJohn McCall 
744e61f2ba7SJohn McCall     case UnresolvedUsingValue:
745e61f2ba7SJohn McCall       return IDNS_Ordinary | IDNS_Using;
7463f746828SJohn McCall 
7473f746828SJohn McCall     case Using:
748151c4568SRichard Smith     case UsingPack:
7493f746828SJohn McCall       return IDNS_Using;
7503f746828SJohn McCall 
7518e097198SChris Lattner     case ObjCProtocol:
75279947a24SDouglas Gregor       return IDNS_ObjCProtocol;
75379947a24SDouglas Gregor 
7548e097198SChris Lattner     case Field:
7558e097198SChris Lattner     case ObjCAtDefsField:
7568e097198SChris Lattner     case ObjCIvar:
7578e097198SChris Lattner       return IDNS_Member;
7588e097198SChris Lattner 
7598e097198SChris Lattner     case Record:
7608e097198SChris Lattner     case CXXRecord:
7618e097198SChris Lattner     case Enum:
762e87beb25SJohn McCall       return IDNS_Tag | IDNS_Type;
7638e097198SChris Lattner 
7648e097198SChris Lattner     case Namespace:
765e87beb25SJohn McCall     case NamespaceAlias:
766e87beb25SJohn McCall       return IDNS_Namespace;
767e87beb25SJohn McCall 
7688e097198SChris Lattner     case FunctionTemplate:
769e87beb25SJohn McCall       return IDNS_Ordinary;
770e87beb25SJohn McCall 
7718e097198SChris Lattner     case ClassTemplate:
7728e097198SChris Lattner     case TemplateTemplateParm:
773b8c41908SRichard Smith     case TypeAliasTemplate:
774e87beb25SJohn McCall       return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
7758e097198SChris Lattner 
77694a4f0cbSAlexey Bataev     case OMPDeclareReduction:
77794a4f0cbSAlexey Bataev       return IDNS_OMPReduction;
77894a4f0cbSAlexey Bataev 
779251e1488SMichael Kruse     case OMPDeclareMapper:
780251e1488SMichael Kruse       return IDNS_OMPMapper;
781251e1488SMichael Kruse 
7828e097198SChris Lattner     // Never have names.
783aa74a0c3SJohn McCall     case Friend:
78411083da4SJohn McCall     case FriendTemplate:
785d7340582SAbramo Bagnara     case AccessSpec:
7868e097198SChris Lattner     case LinkageSpec:
7878df390f9SRichard Smith     case Export:
7888e097198SChris Lattner     case FileScopeAsm:
7898e097198SChris Lattner     case StaticAssert:
7908e097198SChris Lattner     case ObjCPropertyImpl:
7916622029dSNico Weber     case PragmaComment:
792cbbaeb13SNico Weber     case PragmaDetectMismatch:
7938e097198SChris Lattner     case Block:
7946dfa25a1STareq A. Siraj     case Captured:
7958e097198SChris Lattner     case TranslationUnit:
796f19e1279SRichard Smith     case ExternCContext:
797bdb84f37SRichard Smith     case Decomposition:
7988e097198SChris Lattner 
7998e097198SChris Lattner     case UsingDirective:
800d9b1a4fbSDavid Majnemer     case BuiltinTemplate:
8018e097198SChris Lattner     case ClassTemplateSpecialization:
8022373c599SDouglas Gregor     case ClassTemplatePartialSpecialization:
80300c7e6ceSFrancois Pichet     case ClassScopeFunctionSpecialization:
80439a1e507SLarisse Voufo     case VarTemplateSpecialization:
80539a1e507SLarisse Voufo     case VarTemplatePartialSpecialization:
806e93525edSDouglas Gregor     case ObjCImplementation:
807e93525edSDouglas Gregor     case ObjCCategory:
808e93525edSDouglas Gregor     case ObjCCategoryImpl:
809ba34552eSDouglas Gregor     case Import:
810a769e072SAlexey Bataev     case OMPThreadPrivate:
81125ed0c07SAlexey Bataev     case OMPAllocate:
8121408f91aSKelvin Li     case OMPRequires:
8134244be25SAlexey Bataev     case OMPCapturedExpr:
81484324357SMichael Han     case Empty:
815b0561b33STyker     case LifetimeExtendedTemporary:
816a0f50d73SSaar Raz     case RequiresExprBody:
817e93525edSDouglas Gregor       // Never looked up by name.
8188e097198SChris Lattner       return 0;
8198e097198SChris Lattner   }
8203f746828SJohn McCall 
821e4d798f0SDavid Blaikie   llvm_unreachable("Invalid DeclKind!");
8226301884dSArgyrios Kyrtzidis }
8236301884dSArgyrios Kyrtzidis 
8246f40eb7eSArgyrios Kyrtzidis void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
82591167171SArgyrios Kyrtzidis   assert(!HasAttrs && "Decl already contains attrs.");
82691167171SArgyrios Kyrtzidis 
8276f40eb7eSArgyrios Kyrtzidis   AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
828dcfba7b3SAlexis Hunt   assert(AttrBlank.empty() && "HasAttrs was wrong?");
82991167171SArgyrios Kyrtzidis 
83091167171SArgyrios Kyrtzidis   AttrBlank = attrs;
83191167171SArgyrios Kyrtzidis   HasAttrs = true;
83291167171SArgyrios Kyrtzidis }
83391167171SArgyrios Kyrtzidis 
834dcfba7b3SAlexis Hunt void Decl::dropAttrs() {
8356301884dSArgyrios Kyrtzidis   if (!HasAttrs) return;
8366301884dSArgyrios Kyrtzidis 
8376301884dSArgyrios Kyrtzidis   HasAttrs = false;
838b4b64ca7SArgyrios Kyrtzidis   getASTContext().eraseDeclAttrs(this);
8396301884dSArgyrios Kyrtzidis }
8406301884dSArgyrios Kyrtzidis 
8414c99f5feSMichael Kruse void Decl::addAttr(Attr *A) {
8424c99f5feSMichael Kruse   if (!hasAttrs()) {
8434c99f5feSMichael Kruse     setAttrs(AttrVec(1, A));
8444c99f5feSMichael Kruse     return;
8454c99f5feSMichael Kruse   }
8464c99f5feSMichael Kruse 
8474c99f5feSMichael Kruse   AttrVec &Attrs = getAttrs();
8484c99f5feSMichael Kruse   if (!A->isInherited()) {
8494c99f5feSMichael Kruse     Attrs.push_back(A);
8504c99f5feSMichael Kruse     return;
8514c99f5feSMichael Kruse   }
8524c99f5feSMichael Kruse 
8534c99f5feSMichael Kruse   // Attribute inheritance is processed after attribute parsing. To keep the
8544c99f5feSMichael Kruse   // order as in the source code, add inherited attributes before non-inherited
8554c99f5feSMichael Kruse   // ones.
8564c99f5feSMichael Kruse   auto I = Attrs.begin(), E = Attrs.end();
8574c99f5feSMichael Kruse   for (; I != E; ++I) {
8584c99f5feSMichael Kruse     if (!(*I)->isInherited())
8594c99f5feSMichael Kruse       break;
8604c99f5feSMichael Kruse   }
8614c99f5feSMichael Kruse   Attrs.insert(I, A);
8624c99f5feSMichael Kruse }
8634c99f5feSMichael Kruse 
864dcfba7b3SAlexis Hunt const AttrVec &Decl::getAttrs() const {
865dcfba7b3SAlexis Hunt   assert(HasAttrs && "No attrs to get!");
866b4b64ca7SArgyrios Kyrtzidis   return getASTContext().getDeclAttrs(this);
8676301884dSArgyrios Kyrtzidis }
8686301884dSArgyrios Kyrtzidis 
8693768ad6dSArgyrios Kyrtzidis Decl *Decl::castFromDeclContext (const DeclContext *D) {
870afe24c88SArgyrios Kyrtzidis   Decl::Kind DK = D->getDeclKind();
871afe24c88SArgyrios Kyrtzidis   switch(DK) {
872ed05325dSAlexis Hunt #define DECL(NAME, BASE)
873ed05325dSAlexis Hunt #define DECL_CONTEXT(NAME) \
874ed05325dSAlexis Hunt     case Decl::NAME:       \
875ed05325dSAlexis Hunt       return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
876ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)
877ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
878afe24c88SArgyrios Kyrtzidis     default:
879ed05325dSAlexis Hunt #define DECL(NAME, BASE)
880ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)                  \
881ed05325dSAlexis Hunt       if (DK >= first##NAME && DK <= last##NAME) \
882ed05325dSAlexis Hunt         return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
883ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
88483d382b1SDavid Blaikie       llvm_unreachable("a decl that inherits DeclContext isn't handled");
885afe24c88SArgyrios Kyrtzidis   }
8863768ad6dSArgyrios Kyrtzidis }
8873768ad6dSArgyrios Kyrtzidis 
8883768ad6dSArgyrios Kyrtzidis DeclContext *Decl::castToDeclContext(const Decl *D) {
889afe24c88SArgyrios Kyrtzidis   Decl::Kind DK = D->getKind();
890afe24c88SArgyrios Kyrtzidis   switch(DK) {
891ed05325dSAlexis Hunt #define DECL(NAME, BASE)
892ed05325dSAlexis Hunt #define DECL_CONTEXT(NAME) \
893ed05325dSAlexis Hunt     case Decl::NAME:       \
894ed05325dSAlexis Hunt       return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
895ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)
896ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
897afe24c88SArgyrios Kyrtzidis     default:
898ed05325dSAlexis Hunt #define DECL(NAME, BASE)
899ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)                                   \
900ed05325dSAlexis Hunt       if (DK >= first##NAME && DK <= last##NAME)                  \
901ed05325dSAlexis Hunt         return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
902ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
90383d382b1SDavid Blaikie       llvm_unreachable("a decl that inherits DeclContext isn't handled");
904afe24c88SArgyrios Kyrtzidis   }
9053768ad6dSArgyrios Kyrtzidis }
9063768ad6dSArgyrios Kyrtzidis 
907ddcd132aSArgyrios Kyrtzidis SourceLocation Decl::getBodyRBrace() const {
90836ea3225SArgyrios Kyrtzidis   // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
90936ea3225SArgyrios Kyrtzidis   // FunctionDecl stores EndRangeLoc for this purpose.
9102a1ba94fSEugene Zelenko   if (const auto *FD = dyn_cast<FunctionDecl>(this)) {
91136ea3225SArgyrios Kyrtzidis     const FunctionDecl *Definition;
91236ea3225SArgyrios Kyrtzidis     if (FD->hasBody(Definition))
91336ea3225SArgyrios Kyrtzidis       return Definition->getSourceRange().getEnd();
9142a1ba94fSEugene Zelenko     return {};
91536ea3225SArgyrios Kyrtzidis   }
91636ea3225SArgyrios Kyrtzidis 
9176fbc8fa5SArgyrios Kyrtzidis   if (Stmt *Body = getBody())
9186fbc8fa5SArgyrios Kyrtzidis     return Body->getSourceRange().getEnd();
9196fbc8fa5SArgyrios Kyrtzidis 
9202a1ba94fSEugene Zelenko   return {};
921a7b98a77SSebastian Redl }
922a7b98a77SSebastian Redl 
923c1086768SAlp Toker bool Decl::AccessDeclContextSanity() const {
9244b00d3b5SDouglas Gregor #ifndef NDEBUG
925401982f5SJohn McCall   // Suppress this check if any of the following hold:
926401982f5SJohn McCall   // 1. this is the translation unit (and thus has no parent)
927401982f5SJohn McCall   // 2. this is a template parameter (and thus doesn't belong to its context)
928e177863aSArgyrios Kyrtzidis   // 3. this is a non-type template parameter
929e177863aSArgyrios Kyrtzidis   // 4. the context is not a record
930e177863aSArgyrios Kyrtzidis   // 5. it's invalid
931e177863aSArgyrios Kyrtzidis   // 6. it's a C++0x static_assert.
932758d7a5aSRichard Trieu   // 7. it's a block literal declaration
933adf36b23SAnders Carlsson   if (isa<TranslationUnitDecl>(this) ||
934a45855fcSArgyrios Kyrtzidis       isa<TemplateTypeParmDecl>(this) ||
935e177863aSArgyrios Kyrtzidis       isa<NonTypeTemplateParmDecl>(this) ||
936dcf17dedSRichard Smith       !getDeclContext() ||
9372b76dd9aSDouglas Gregor       !isa<CXXRecordDecl>(getDeclContext()) ||
938260b4a8eSArgyrios Kyrtzidis       isInvalidDecl() ||
939260b4a8eSArgyrios Kyrtzidis       isa<StaticAssertDecl>(this) ||
940758d7a5aSRichard Trieu       isa<BlockDecl>(this) ||
941260b4a8eSArgyrios Kyrtzidis       // FIXME: a ParmVarDecl can have ClassTemplateSpecialization
942260b4a8eSArgyrios Kyrtzidis       // as DeclContext (?).
943e177863aSArgyrios Kyrtzidis       isa<ParmVarDecl>(this) ||
944e177863aSArgyrios Kyrtzidis       // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have
945e177863aSArgyrios Kyrtzidis       // AS_none as access specifier.
94609af8c36SFrancois Pichet       isa<CXXRecordDecl>(this) ||
94709af8c36SFrancois Pichet       isa<ClassScopeFunctionSpecializationDecl>(this))
948c1086768SAlp Toker     return true;
949adf36b23SAnders Carlsson 
950adf36b23SAnders Carlsson   assert(Access != AS_none &&
951a28908d5SAnders Carlsson          "Access specifier is AS_none inside a record decl");
9524b00d3b5SDouglas Gregor #endif
953c1086768SAlp Toker   return true;
954a28908d5SAnders Carlsson }
955a28908d5SAnders Carlsson 
956dec348f7SJohn McCall static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
957dec348f7SJohn McCall static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
958dec348f7SJohn McCall 
959e3c99427SGeorge Karpenkov int64_t Decl::getID() const {
960057647d8SArtem Dergachev   return getASTContext().getAllocator().identifyKnownAlignedObject<Decl>(this);
961e3c99427SGeorge Karpenkov }
962e3c99427SGeorge Karpenkov 
96312b9f653SAaron Ballman const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
96412b9f653SAaron Ballman   QualType Ty;
9652a1ba94fSEugene Zelenko   if (const auto *D = dyn_cast<ValueDecl>(this))
96612b9f653SAaron Ballman     Ty = D->getType();
9672a1ba94fSEugene Zelenko   else if (const auto *D = dyn_cast<TypedefNameDecl>(this))
96812b9f653SAaron Ballman     Ty = D->getUnderlyingType();
96912b9f653SAaron Ballman   else
97036250ad6SCraig Topper     return nullptr;
97112b9f653SAaron Ballman 
97212b9f653SAaron Ballman   if (Ty->isFunctionPointerType())
97386976c91SSimon Pilgrim     Ty = Ty->castAs<PointerType>()->getPointeeType();
974bf37536aSErich Keane   else if (Ty->isFunctionReferenceType())
97586976c91SSimon Pilgrim     Ty = Ty->castAs<ReferenceType>()->getPointeeType();
97612b9f653SAaron Ballman   else if (BlocksToo && Ty->isBlockPointerType())
97786976c91SSimon Pilgrim     Ty = Ty->castAs<BlockPointerType>()->getPointeeType();
97812b9f653SAaron Ballman 
97912b9f653SAaron Ballman   return Ty->getAs<FunctionType>();
98012b9f653SAaron Ballman }
98112b9f653SAaron Ballman 
982dec348f7SJohn McCall /// Starting at a given context (a Decl or DeclContext), look for a
983dec348f7SJohn McCall /// code context that is not a closure (a lambda, block, etc.).
984dec348f7SJohn McCall template <class T> static Decl *getNonClosureContext(T *D) {
985dec348f7SJohn McCall   if (getKind(D) == Decl::CXXMethod) {
9862a1ba94fSEugene Zelenko     auto *MD = cast<CXXMethodDecl>(D);
98755c0ceecSJohn McCall     if (MD->getOverloadedOperator() == OO_Call &&
98855c0ceecSJohn McCall         MD->getParent()->isLambda())
989dec348f7SJohn McCall       return getNonClosureContext(MD->getParent()->getParent());
990dec348f7SJohn McCall     return MD;
9912a1ba94fSEugene Zelenko   } else if (auto *FD = dyn_cast<FunctionDecl>(D))
992dec348f7SJohn McCall     return FD;
9932a1ba94fSEugene Zelenko   else if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
994dec348f7SJohn McCall     return MD;
9952a1ba94fSEugene Zelenko   else if (auto *BD = dyn_cast<BlockDecl>(D))
996dec348f7SJohn McCall     return getNonClosureContext(BD->getParent());
9972a1ba94fSEugene Zelenko   else if (auto *CD = dyn_cast<CapturedDecl>(D))
998dec348f7SJohn McCall     return getNonClosureContext(CD->getParent());
9992a1ba94fSEugene Zelenko   else
100036250ad6SCraig Topper     return nullptr;
1001dec348f7SJohn McCall }
1002fe96e0b6SJohn McCall 
1003dec348f7SJohn McCall Decl *Decl::getNonClosureContext() {
1004dec348f7SJohn McCall   return ::getNonClosureContext(this);
1005dec348f7SJohn McCall }
1006b67608feSJohn McCall 
1007dec348f7SJohn McCall Decl *DeclContext::getNonClosureAncestor() {
1008dec348f7SJohn McCall   return ::getNonClosureContext(this);
1009b67608feSJohn McCall }
1010a28908d5SAnders Carlsson 
10116301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
10126301884dSArgyrios Kyrtzidis // DeclContext Implementation
10136301884dSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
10146301884dSArgyrios Kyrtzidis 
1015f92f31c6SErich Keane DeclContext::DeclContext(Decl::Kind K) {
1016f92f31c6SErich Keane   DeclContextBits.DeclKind = K;
1017f92f31c6SErich Keane   setHasExternalLexicalStorage(false);
1018f92f31c6SErich Keane   setHasExternalVisibleStorage(false);
1019f92f31c6SErich Keane   setNeedToReconcileExternalVisibleStorage(false);
1020f92f31c6SErich Keane   setHasLazyLocalLexicalLookups(false);
1021f92f31c6SErich Keane   setHasLazyExternalLexicalLookups(false);
1022f92f31c6SErich Keane   setUseQualifiedLookup(false);
1023f92f31c6SErich Keane }
1024f92f31c6SErich Keane 
1025afe24c88SArgyrios Kyrtzidis bool DeclContext::classof(const Decl *D) {
1026afe24c88SArgyrios Kyrtzidis   switch (D->getKind()) {
1027ed05325dSAlexis Hunt #define DECL(NAME, BASE)
1028ed05325dSAlexis Hunt #define DECL_CONTEXT(NAME) case Decl::NAME:
1029ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)
1030ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1031afe24c88SArgyrios Kyrtzidis       return true;
1032afe24c88SArgyrios Kyrtzidis     default:
1033ed05325dSAlexis Hunt #define DECL(NAME, BASE)
1034ed05325dSAlexis Hunt #define DECL_CONTEXT_BASE(NAME)                 \
1035ed05325dSAlexis Hunt       if (D->getKind() >= Decl::first##NAME &&  \
1036ed05325dSAlexis Hunt           D->getKind() <= Decl::last##NAME)     \
1037afe24c88SArgyrios Kyrtzidis         return true;
1038ed05325dSAlexis Hunt #include "clang/AST/DeclNodes.inc"
1039afe24c88SArgyrios Kyrtzidis       return false;
1040afe24c88SArgyrios Kyrtzidis   }
1041afe24c88SArgyrios Kyrtzidis }
1042afe24c88SArgyrios Kyrtzidis 
10430d00c899SEugene Zelenko DeclContext::~DeclContext() = default;
104491f84216SDouglas Gregor 
10459fc8faf9SAdrian Prantl /// Find the parent context of this context that will be
10467f737c00SDouglas Gregor /// used for unqualified name lookup.
10477f737c00SDouglas Gregor ///
10487f737c00SDouglas Gregor /// Generally, the parent lookup context is the semantic context. However, for
10497f737c00SDouglas Gregor /// a friend function the parent lookup context is the lexical context, which
10507f737c00SDouglas Gregor /// is the class in which the friend is declared.
10517f737c00SDouglas Gregor DeclContext *DeclContext::getLookupParent() {
1052cfd22580SBruno Ricci   // FIXME: Find a better way to identify friends.
10537f737c00SDouglas Gregor   if (isa<FunctionDecl>(this))
105450c68258SSebastian Redl     if (getParent()->getRedeclContext()->isFileContext() &&
105550c68258SSebastian Redl         getLexicalParent()->getRedeclContext()->isRecord())
10567f737c00SDouglas Gregor       return getLexicalParent();
10577f737c00SDouglas Gregor 
10587ac42374SRichard Smith   // A lookup within the call operator of a lambda never looks in the lambda
10597ac42374SRichard Smith   // class; instead, skip to the context in which that closure type is
10607ac42374SRichard Smith   // declared.
10617ac42374SRichard Smith   if (isLambdaCallOperator(this))
10627ac42374SRichard Smith     return getParent()->getParent();
10637ac42374SRichard Smith 
10647f737c00SDouglas Gregor   return getParent();
10657f737c00SDouglas Gregor }
10667f737c00SDouglas Gregor 
1067f8268f67SAkira Hatanaka const BlockDecl *DeclContext::getInnermostBlockDecl() const {
1068f8268f67SAkira Hatanaka   const DeclContext *Ctx = this;
1069f8268f67SAkira Hatanaka 
1070f8268f67SAkira Hatanaka   do {
1071f8268f67SAkira Hatanaka     if (Ctx->isClosure())
1072f8268f67SAkira Hatanaka       return cast<BlockDecl>(Ctx);
1073f8268f67SAkira Hatanaka     Ctx = Ctx->getParent();
1074f8268f67SAkira Hatanaka   } while (Ctx);
1075f8268f67SAkira Hatanaka 
1076f8268f67SAkira Hatanaka   return nullptr;
1077f8268f67SAkira Hatanaka }
1078f8268f67SAkira Hatanaka 
1079bd595765SSebastian Redl bool DeclContext::isInlineNamespace() const {
1080bd595765SSebastian Redl   return isNamespace() &&
1081bd595765SSebastian Redl          cast<NamespaceDecl>(this)->isInline();
1082bd595765SSebastian Redl }
1083bd595765SSebastian Redl 
1084c771d5d7SRichard Trieu bool DeclContext::isStdNamespace() const {
1085c771d5d7SRichard Trieu   if (!isNamespace())
1086c771d5d7SRichard Trieu     return false;
1087c771d5d7SRichard Trieu 
10882a1ba94fSEugene Zelenko   const auto *ND = cast<NamespaceDecl>(this);
1089c771d5d7SRichard Trieu   if (ND->isInline()) {
1090c771d5d7SRichard Trieu     return ND->getParent()->isStdNamespace();
1091c771d5d7SRichard Trieu   }
1092c771d5d7SRichard Trieu 
1093c771d5d7SRichard Trieu   if (!getParent()->getRedeclContext()->isTranslationUnit())
1094c771d5d7SRichard Trieu     return false;
1095c771d5d7SRichard Trieu 
1096c771d5d7SRichard Trieu   const IdentifierInfo *II = ND->getIdentifier();
1097c771d5d7SRichard Trieu   return II && II->isStr("std");
1098c771d5d7SRichard Trieu }
1099c771d5d7SRichard Trieu 
11009e927abcSDouglas Gregor bool DeclContext::isDependentContext() const {
11019e927abcSDouglas Gregor   if (isFileContext())
11029e927abcSDouglas Gregor     return false;
11039e927abcSDouglas Gregor 
11042373c599SDouglas Gregor   if (isa<ClassTemplatePartialSpecializationDecl>(this))
11052373c599SDouglas Gregor     return true;
11062373c599SDouglas Gregor 
11072a1ba94fSEugene Zelenko   if (const auto *Record = dyn_cast<CXXRecordDecl>(this)) {
11089e927abcSDouglas Gregor     if (Record->getDescribedClassTemplate())
11099e927abcSDouglas Gregor       return true;
11109e927abcSDouglas Gregor 
1111680e9e01SDouglas Gregor     if (Record->isDependentLambda())
1112680e9e01SDouglas Gregor       return true;
1113680e9e01SDouglas Gregor   }
1114680e9e01SDouglas Gregor 
11152a1ba94fSEugene Zelenko   if (const auto *Function = dyn_cast<FunctionDecl>(this)) {
11169e927abcSDouglas Gregor     if (Function->getDescribedFunctionTemplate())
11179e927abcSDouglas Gregor       return true;
11189e927abcSDouglas Gregor 
1119c62bb64cSJohn McCall     // Friend function declarations are dependent if their *lexical*
1120c62bb64cSJohn McCall     // context is dependent.
1121c62bb64cSJohn McCall     if (cast<Decl>(this)->getFriendObjectKind())
1122c62bb64cSJohn McCall       return getLexicalParent()->isDependentContext();
1123c62bb64cSJohn McCall   }
1124c62bb64cSJohn McCall 
11252b560575SRichard Smith   // FIXME: A variable template is a dependent context, but is not a
11262b560575SRichard Smith   // DeclContext. A context within it (such as a lambda-expression)
11272b560575SRichard Smith   // should be considered dependent.
11282b560575SRichard Smith 
11299e927abcSDouglas Gregor   return getParent() && getParent()->isDependentContext();
11309e927abcSDouglas Gregor }
11319e927abcSDouglas Gregor 
113207665a69SDouglas Gregor bool DeclContext::isTransparentContext() const {
1133f92f31c6SErich Keane   if (getDeclKind() == Decl::Enum)
11340bf31404SDouglas Gregor     return !cast<EnumDecl>(this)->isScoped();
1135f92f31c6SErich Keane   else if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
113607665a69SDouglas Gregor     return true;
113707665a69SDouglas Gregor 
113807665a69SDouglas Gregor   return false;
113907665a69SDouglas Gregor }
114007665a69SDouglas Gregor 
11413cb80228SSerge Pavlov static bool isLinkageSpecContext(const DeclContext *DC,
11423cb80228SSerge Pavlov                                  LinkageSpecDecl::LanguageIDs ID) {
11433cb80228SSerge Pavlov   while (DC->getDeclKind() != Decl::TranslationUnit) {
11443cb80228SSerge Pavlov     if (DC->getDeclKind() == Decl::LinkageSpec)
11453cb80228SSerge Pavlov       return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
1146ac9c9a00SRichard Smith     DC = DC->getLexicalParent();
11473cb80228SSerge Pavlov   }
11483cb80228SSerge Pavlov   return false;
11493cb80228SSerge Pavlov }
11503cb80228SSerge Pavlov 
11513cb80228SSerge Pavlov bool DeclContext::isExternCContext() const {
11520d00c899SEugene Zelenko   return isLinkageSpecContext(this, LinkageSpecDecl::lang_c);
11533cb80228SSerge Pavlov }
11543cb80228SSerge Pavlov 
1155560ae565SAlex Lorenz const LinkageSpecDecl *DeclContext::getExternCContext() const {
1156560ae565SAlex Lorenz   const DeclContext *DC = this;
1157560ae565SAlex Lorenz   while (DC->getDeclKind() != Decl::TranslationUnit) {
1158560ae565SAlex Lorenz     if (DC->getDeclKind() == Decl::LinkageSpec &&
11590d00c899SEugene Zelenko         cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecDecl::lang_c)
1160560ae565SAlex Lorenz       return cast<LinkageSpecDecl>(DC);
1161560ae565SAlex Lorenz     DC = DC->getLexicalParent();
1162560ae565SAlex Lorenz   }
1163560ae565SAlex Lorenz   return nullptr;
1164560ae565SAlex Lorenz }
1165560ae565SAlex Lorenz 
11663cb80228SSerge Pavlov bool DeclContext::isExternCXXContext() const {
11670d00c899SEugene Zelenko   return isLinkageSpecContext(this, LinkageSpecDecl::lang_cxx);
11683cb80228SSerge Pavlov }
11693cb80228SSerge Pavlov 
117050c68258SSebastian Redl bool DeclContext::Encloses(const DeclContext *DC) const {
1171e985a3b7SDouglas Gregor   if (getPrimaryContext() != this)
1172e985a3b7SDouglas Gregor     return getPrimaryContext()->Encloses(DC);
1173e985a3b7SDouglas Gregor 
1174e985a3b7SDouglas Gregor   for (; DC; DC = DC->getParent())
1175e985a3b7SDouglas Gregor     if (DC->getPrimaryContext() == this)
1176e985a3b7SDouglas Gregor       return true;
1177e985a3b7SDouglas Gregor   return false;
1178e985a3b7SDouglas Gregor }
1179e985a3b7SDouglas Gregor 
118035c62ae6SSteve Naroff DeclContext *DeclContext::getPrimaryContext() {
1181f92f31c6SErich Keane   switch (getDeclKind()) {
118291f84216SDouglas Gregor   case Decl::TranslationUnit:
1183f19e1279SRichard Smith   case Decl::ExternCContext:
118407665a69SDouglas Gregor   case Decl::LinkageSpec:
11858df390f9SRichard Smith   case Decl::Export:
118607665a69SDouglas Gregor   case Decl::Block:
11876dfa25a1STareq A. Siraj   case Decl::Captured:
118894a4f0cbSAlexey Bataev   case Decl::OMPDeclareReduction:
1189251e1488SMichael Kruse   case Decl::OMPDeclareMapper:
1190a0f50d73SSaar Raz   case Decl::RequiresExprBody:
119191f84216SDouglas Gregor     // There is only one DeclContext for these entities.
119291f84216SDouglas Gregor     return this;
119391f84216SDouglas Gregor 
119491f84216SDouglas Gregor   case Decl::Namespace:
119591f84216SDouglas Gregor     // The original namespace is our primary context.
119691f84216SDouglas Gregor     return static_cast<NamespaceDecl *>(this)->getOriginalNamespace();
119791f84216SDouglas Gregor 
119891f84216SDouglas Gregor   case Decl::ObjCMethod:
119991f84216SDouglas Gregor     return this;
120091f84216SDouglas Gregor 
120191f84216SDouglas Gregor   case Decl::ObjCInterface:
1202f170dff3SDon Hinton     if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))
1203f170dff3SDon Hinton       if (auto *Def = OID->getDefinition())
120466b310c6SDouglas Gregor         return Def;
120566b310c6SDouglas Gregor     return this;
120666b310c6SDouglas Gregor 
120735c62ae6SSteve Naroff   case Decl::ObjCProtocol:
1208f170dff3SDon Hinton     if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))
1209f170dff3SDon Hinton       if (auto *Def = OPD->getDefinition())
1210a715bfffSDouglas Gregor         return Def;
1211a715bfffSDouglas Gregor     return this;
121266b310c6SDouglas Gregor 
121335c62ae6SSteve Naroff   case Decl::ObjCCategory:
121491f84216SDouglas Gregor     return this;
121591f84216SDouglas Gregor 
121635c62ae6SSteve Naroff   case Decl::ObjCImplementation:
121735c62ae6SSteve Naroff   case Decl::ObjCCategoryImpl:
121835c62ae6SSteve Naroff     return this;
121935c62ae6SSteve Naroff 
122091f84216SDouglas Gregor   default:
1221f92f31c6SErich Keane     if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
122267a65640SDouglas Gregor       // If this is a tag type that has a definition or is currently
122367a65640SDouglas Gregor       // being defined, that definition is our primary context.
12242a1ba94fSEugene Zelenko       auto *Tag = cast<TagDecl>(this);
1225e78aac41SJohn McCall 
1226e78aac41SJohn McCall       if (TagDecl *Def = Tag->getDefinition())
1227e78aac41SJohn McCall         return Def;
1228e78aac41SJohn McCall 
12292a1ba94fSEugene Zelenko       if (const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
12305b21db89SRichard Smith         // Note, TagType::getDecl returns the (partial) definition one exists.
12315b21db89SRichard Smith         TagDecl *PossiblePartialDef = TagTy->getDecl();
12325b21db89SRichard Smith         if (PossiblePartialDef->isBeingDefined())
12335b21db89SRichard Smith           return PossiblePartialDef;
12345b21db89SRichard Smith       } else {
12355b21db89SRichard Smith         assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1236e78aac41SJohn McCall       }
1237e78aac41SJohn McCall 
1238e78aac41SJohn McCall       return Tag;
123967a65640SDouglas Gregor     }
124067a65640SDouglas Gregor 
1241f92f31c6SErich Keane     assert(getDeclKind() >= Decl::firstFunction &&
1242f92f31c6SErich Keane            getDeclKind() <= Decl::lastFunction &&
124391f84216SDouglas Gregor           "Unknown DeclContext kind");
124491f84216SDouglas Gregor     return this;
124591f84216SDouglas Gregor   }
124691f84216SDouglas Gregor }
124791f84216SDouglas Gregor 
1248e57e752bSDouglas Gregor void
1249f857950dSDmitri Gribenko DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts){
1250e57e752bSDouglas Gregor   Contexts.clear();
125191f84216SDouglas Gregor 
1252f92f31c6SErich Keane   if (getDeclKind() != Decl::Namespace) {
1253e57e752bSDouglas Gregor     Contexts.push_back(this);
1254e57e752bSDouglas Gregor     return;
125591f84216SDouglas Gregor   }
1256e57e752bSDouglas Gregor 
12572a1ba94fSEugene Zelenko   auto *Self = static_cast<NamespaceDecl *>(this);
1258ec9fd13cSDouglas Gregor   for (NamespaceDecl *N = Self->getMostRecentDecl(); N;
1259ec9fd13cSDouglas Gregor        N = N->getPreviousDecl())
1260e57e752bSDouglas Gregor     Contexts.push_back(N);
1261e57e752bSDouglas Gregor 
1262e57e752bSDouglas Gregor   std::reverse(Contexts.begin(), Contexts.end());
126391f84216SDouglas Gregor }
126491f84216SDouglas Gregor 
12650e88a565SArgyrios Kyrtzidis std::pair<Decl *, Decl *>
12668eb771d4SBill Wendling DeclContext::BuildDeclChain(ArrayRef<Decl *> Decls,
1267094da739SArgyrios Kyrtzidis                             bool FieldsAlreadyLoaded) {
1268781f713dSDouglas Gregor   // Build up a chain of declarations via the Decl::NextInContextAndBits field.
126936250ad6SCraig Topper   Decl *FirstNewDecl = nullptr;
127036250ad6SCraig Topper   Decl *PrevDecl = nullptr;
12712a1ba94fSEugene Zelenko   for (auto *D : Decls) {
12722a1ba94fSEugene Zelenko     if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1273094da739SArgyrios Kyrtzidis       continue;
1274094da739SArgyrios Kyrtzidis 
12750e88a565SArgyrios Kyrtzidis     if (PrevDecl)
1276781f713dSDouglas Gregor       PrevDecl->NextInContextAndBits.setPointer(D);
12770e88a565SArgyrios Kyrtzidis     else
12780e88a565SArgyrios Kyrtzidis       FirstNewDecl = D;
12790e88a565SArgyrios Kyrtzidis 
12800e88a565SArgyrios Kyrtzidis     PrevDecl = D;
12810e88a565SArgyrios Kyrtzidis   }
12820e88a565SArgyrios Kyrtzidis 
12830e88a565SArgyrios Kyrtzidis   return std::make_pair(FirstNewDecl, PrevDecl);
12840e88a565SArgyrios Kyrtzidis }
12850e88a565SArgyrios Kyrtzidis 
12869fc8faf9SAdrian Prantl /// We have just acquired external visible storage, and we already have
1287645d755dSRichard Smith /// built a lookup map. For every name in the map, pull in the new names from
1288645d755dSRichard Smith /// the external storage.
1289a8b74591SRichard Smith void DeclContext::reconcileExternalVisibleStorage() const {
1290f92f31c6SErich Keane   assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1291f92f31c6SErich Keane   setNeedToReconcileExternalVisibleStorage(false);
1292645d755dSRichard Smith 
12939e2341d0SRichard Smith   for (auto &Lookup : *LookupPtr)
1294a8b74591SRichard Smith     Lookup.second.setHasExternalDecls();
1295645d755dSRichard Smith }
1296645d755dSRichard Smith 
12979fc8faf9SAdrian Prantl /// Load the declarations within this lexical storage from an
1298ef84c4b4SDouglas Gregor /// external source.
129918b380b1SRichard Smith /// \return \c true if any declarations were added.
130018b380b1SRichard Smith bool
1301cfbfe78eSArgyrios Kyrtzidis DeclContext::LoadLexicalDeclsFromExternalStorage() const {
1302cfbfe78eSArgyrios Kyrtzidis   ExternalASTSource *Source = getParentASTContext().getExternalSource();
1303ef84c4b4SDouglas Gregor   assert(hasExternalLexicalStorage() && Source && "No external storage?");
1304ef84c4b4SDouglas Gregor 
130598d045ebSArgyrios Kyrtzidis   // Notify that we have a DeclContext that is initializing.
130698d045ebSArgyrios Kyrtzidis   ExternalASTSource::Deserializing ADeclContext(Source);
130798d045ebSArgyrios Kyrtzidis 
13083d0adb32SDouglas Gregor   // Load the external declarations, if any.
13090e62c1ccSChris Lattner   SmallVector<Decl*, 64> Decls;
1310f92f31c6SErich Keane   setHasExternalLexicalStorage(false);
13113cb15729SRichard Smith   Source->FindExternalLexicalDecls(this, Decls);
1312ef84c4b4SDouglas Gregor 
1313ef84c4b4SDouglas Gregor   if (Decls.empty())
131418b380b1SRichard Smith     return false;
13159e2341d0SRichard Smith 
1316094da739SArgyrios Kyrtzidis   // We may have already loaded just the fields of this record, in which case
1317094da739SArgyrios Kyrtzidis   // we need to ignore them.
1318094da739SArgyrios Kyrtzidis   bool FieldsAlreadyLoaded = false;
13192a1ba94fSEugene Zelenko   if (const auto *RD = dyn_cast<RecordDecl>(this))
1320f92f31c6SErich Keane     FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1321094da739SArgyrios Kyrtzidis 
1322ef84c4b4SDouglas Gregor   // Splice the newly-read declarations into the beginning of the list
1323ef84c4b4SDouglas Gregor   // of declarations.
13240e88a565SArgyrios Kyrtzidis   Decl *ExternalFirst, *ExternalLast;
1325867ea1d4SBenjamin Kramer   std::tie(ExternalFirst, ExternalLast) =
1326867ea1d4SBenjamin Kramer       BuildDeclChain(Decls, FieldsAlreadyLoaded);
1327781f713dSDouglas Gregor   ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
13280e88a565SArgyrios Kyrtzidis   FirstDecl = ExternalFirst;
1329ef84c4b4SDouglas Gregor   if (!LastDecl)
13300e88a565SArgyrios Kyrtzidis     LastDecl = ExternalLast;
133118b380b1SRichard Smith   return true;
1332ef84c4b4SDouglas Gregor }
1333ef84c4b4SDouglas Gregor 
133475b960e5SJohn McCall DeclContext::lookup_result
133575b960e5SJohn McCall ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
133675b960e5SJohn McCall                                                     DeclarationName Name) {
133775b960e5SJohn McCall   ASTContext &Context = DC->getParentASTContext();
133875b960e5SJohn McCall   StoredDeclsMap *Map;
13399e2341d0SRichard Smith   if (!(Map = DC->LookupPtr))
134075b960e5SJohn McCall     Map = DC->CreateStoredDeclsMap(Context);
1341f92f31c6SErich Keane   if (DC->hasNeedToReconcileExternalVisibleStorage())
1342a8b74591SRichard Smith     DC->reconcileExternalVisibleStorage();
1343ef84c4b4SDouglas Gregor 
13444abe0a8dSRichard Smith   (*Map)[Name].removeExternalDecls();
1345ef84c4b4SDouglas Gregor 
134675b960e5SJohn McCall   return DeclContext::lookup_result();
134775b960e5SJohn McCall }
1348ef84c4b4SDouglas Gregor 
134975b960e5SJohn McCall DeclContext::lookup_result
135075b960e5SJohn McCall ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
135175b960e5SJohn McCall                                                   DeclarationName Name,
135294d3f9dcSArgyrios Kyrtzidis                                                   ArrayRef<NamedDecl*> Decls) {
135376bb5cabSDmitri Gribenko   ASTContext &Context = DC->getParentASTContext();
135475b960e5SJohn McCall   StoredDeclsMap *Map;
13559e2341d0SRichard Smith   if (!(Map = DC->LookupPtr))
135675b960e5SJohn McCall     Map = DC->CreateStoredDeclsMap(Context);
1357f92f31c6SErich Keane   if (DC->hasNeedToReconcileExternalVisibleStorage())
1358a8b74591SRichard Smith     DC->reconcileExternalVisibleStorage();
135975b960e5SJohn McCall 
136075b960e5SJohn McCall   StoredDeclsList &List = (*Map)[Name];
136151445cd3SRichard Smith 
136251445cd3SRichard Smith   // Clear out any old external visible declarations, to avoid quadratic
136351445cd3SRichard Smith   // performance in the redeclaration checks below.
136451445cd3SRichard Smith   List.removeExternalDecls();
136551445cd3SRichard Smith 
136651445cd3SRichard Smith   if (!List.isNull()) {
136751445cd3SRichard Smith     // We have both existing declarations and new declarations for this name.
136851445cd3SRichard Smith     // Some of the declarations may simply replace existing ones. Handle those
136951445cd3SRichard Smith     // first.
137051445cd3SRichard Smith     llvm::SmallVector<unsigned, 8> Skip;
137151445cd3SRichard Smith     for (unsigned I = 0, N = Decls.size(); I != N; ++I)
1372e8292b10SRichard Smith       if (List.HandleRedeclaration(Decls[I], /*IsKnownNewer*/false))
137351445cd3SRichard Smith         Skip.push_back(I);
137451445cd3SRichard Smith     Skip.push_back(Decls.size());
137551445cd3SRichard Smith 
137651445cd3SRichard Smith     // Add in any new declarations.
137751445cd3SRichard Smith     unsigned SkipPos = 0;
137851445cd3SRichard Smith     for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
137951445cd3SRichard Smith       if (I == Skip[SkipPos])
138051445cd3SRichard Smith         ++SkipPos;
138151445cd3SRichard Smith       else
138251445cd3SRichard Smith         List.AddSubsequentDecl(Decls[I]);
138351445cd3SRichard Smith     }
138451445cd3SRichard Smith   } else {
138551445cd3SRichard Smith     // Convert the array to a StoredDeclsList.
13862a1ba94fSEugene Zelenko     for (auto *D : Decls) {
138775b960e5SJohn McCall       if (List.isNull())
13882a1ba94fSEugene Zelenko         List.setOnlyValue(D);
138975b960e5SJohn McCall       else
13902a1ba94fSEugene Zelenko         List.AddSubsequentDecl(D);
139175b960e5SJohn McCall     }
139251445cd3SRichard Smith   }
139375b960e5SJohn McCall 
1394ba88bfabSArgyrios Kyrtzidis   return List.getLookupResult();
139575b960e5SJohn McCall }
139675b960e5SJohn McCall 
1397da634f1dSAaron Ballman DeclContext::decl_iterator DeclContext::decls_begin() const {
1398da634f1dSAaron Ballman   if (hasExternalLexicalStorage())
1399da634f1dSAaron Ballman     LoadLexicalDeclsFromExternalStorage();
1400da634f1dSAaron Ballman   return decl_iterator(FirstDecl);
1401da634f1dSAaron Ballman }
1402da634f1dSAaron Ballman 
1403cfbfe78eSArgyrios Kyrtzidis bool DeclContext::decls_empty() const {
14041e9bf3baSDouglas Gregor   if (hasExternalLexicalStorage())
1405cfbfe78eSArgyrios Kyrtzidis     LoadLexicalDeclsFromExternalStorage();
14061e9bf3baSDouglas Gregor 
14071e9bf3baSDouglas Gregor   return !FirstDecl;
14081e9bf3baSDouglas Gregor }
14091e9bf3baSDouglas Gregor 
14100325fb85SSean Callanan bool DeclContext::containsDecl(Decl *D) const {
14110325fb85SSean Callanan   return (D->getLexicalDeclContext() == this &&
14120325fb85SSean Callanan           (D->NextInContextAndBits.getPointer() || D == LastDecl));
14130325fb85SSean Callanan }
14140325fb85SSean Callanan 
14155254e64aSGabor Marton bool DeclContext::containsDeclAndLoad(Decl *D) const {
14165254e64aSGabor Marton   if (hasExternalLexicalStorage())
14175254e64aSGabor Marton     LoadLexicalDeclsFromExternalStorage();
14185254e64aSGabor Marton   return containsDecl(D);
14195254e64aSGabor Marton }
14205254e64aSGabor Marton 
142161d862a9SGabor Marton /// shouldBeHidden - Determine whether a declaration which was declared
142261d862a9SGabor Marton /// within its semantic context should be invisible to qualified name lookup.
142361d862a9SGabor Marton static bool shouldBeHidden(NamedDecl *D) {
142461d862a9SGabor Marton   // Skip unnamed declarations.
142561d862a9SGabor Marton   if (!D->getDeclName())
142661d862a9SGabor Marton     return true;
142761d862a9SGabor Marton 
142861d862a9SGabor Marton   // Skip entities that can't be found by name lookup into a particular
142961d862a9SGabor Marton   // context.
143061d862a9SGabor Marton   if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
143161d862a9SGabor Marton       D->isTemplateParameter())
143261d862a9SGabor Marton     return true;
143361d862a9SGabor Marton 
14348ce732b4SRichard Smith   // Skip friends and local extern declarations unless they're the first
14358ce732b4SRichard Smith   // declaration of the entity.
14368ce732b4SRichard Smith   if ((D->isLocalExternDecl() || D->getFriendObjectKind()) &&
14378ce732b4SRichard Smith       D != D->getCanonicalDecl())
14388ce732b4SRichard Smith     return true;
14398ce732b4SRichard Smith 
144061d862a9SGabor Marton   // Skip template specializations.
144161d862a9SGabor Marton   // FIXME: This feels like a hack. Should DeclarationName support
144261d862a9SGabor Marton   // template-ids, or is there a better way to keep specializations
144361d862a9SGabor Marton   // from being visible?
144461d862a9SGabor Marton   if (isa<ClassTemplateSpecializationDecl>(D))
144561d862a9SGabor Marton     return true;
144661d862a9SGabor Marton   if (auto *FD = dyn_cast<FunctionDecl>(D))
144761d862a9SGabor Marton     if (FD->isFunctionTemplateSpecialization())
144861d862a9SGabor Marton       return true;
144961d862a9SGabor Marton 
145061d862a9SGabor Marton   return false;
145161d862a9SGabor Marton }
145261d862a9SGabor Marton 
145384d8767cSJohn McCall void DeclContext::removeDecl(Decl *D) {
145484d8767cSJohn McCall   assert(D->getLexicalDeclContext() == this &&
145584d8767cSJohn McCall          "decl being removed from non-lexical context");
1456781f713dSDouglas Gregor   assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
145784d8767cSJohn McCall          "decl is not in decls list");
145884d8767cSJohn McCall 
145984d8767cSJohn McCall   // Remove D from the decl chain.  This is O(n) but hopefully rare.
146084d8767cSJohn McCall   if (D == FirstDecl) {
146184d8767cSJohn McCall     if (D == LastDecl)
146236250ad6SCraig Topper       FirstDecl = LastDecl = nullptr;
146384d8767cSJohn McCall     else
1464781f713dSDouglas Gregor       FirstDecl = D->NextInContextAndBits.getPointer();
146584d8767cSJohn McCall   } else {
1466781f713dSDouglas Gregor     for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {
146784d8767cSJohn McCall       assert(I && "decl not found in linked list");
1468781f713dSDouglas Gregor       if (I->NextInContextAndBits.getPointer() == D) {
1469781f713dSDouglas Gregor         I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
147084d8767cSJohn McCall         if (D == LastDecl) LastDecl = I;
147184d8767cSJohn McCall         break;
147284d8767cSJohn McCall       }
147384d8767cSJohn McCall     }
147484d8767cSJohn McCall   }
147584d8767cSJohn McCall 
147684d8767cSJohn McCall   // Mark that D is no longer in the decl chain.
147736250ad6SCraig Topper   D->NextInContextAndBits.setPointer(nullptr);
147884d8767cSJohn McCall 
147984d8767cSJohn McCall   // Remove D from the lookup table if necessary.
148084d8767cSJohn McCall   if (isa<NamedDecl>(D)) {
14812a1ba94fSEugene Zelenko     auto *ND = cast<NamedDecl>(D);
148284d8767cSJohn McCall 
148361d862a9SGabor Marton     // Do not try to remove the declaration if that is invisible to qualified
148461d862a9SGabor Marton     // lookup.  E.g. template specializations are skipped.
148561d862a9SGabor Marton     if (shouldBeHidden(ND))
148661d862a9SGabor Marton       return;
148761d862a9SGabor Marton 
1488cb2c52f7SAxel Naumann     // Remove only decls that have a name
148961d862a9SGabor Marton     if (!ND->getDeclName())
149061d862a9SGabor Marton       return;
1491cb2c52f7SAxel Naumann 
14922e415980SVassil Vassilev     auto *DC = D->getDeclContext();
149326210db6SRichard Smith     do {
149426210db6SRichard Smith       StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr;
149526210db6SRichard Smith       if (Map) {
149684d8767cSJohn McCall         StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
149784d8767cSJohn McCall         assert(Pos != Map->end() && "no lookup entry for decl");
14987df342a4SGabor Marton         // Remove the decl only if it is contained.
14997df342a4SGabor Marton         StoredDeclsList::DeclsTy *Vec = Pos->second.getAsVector();
15007df342a4SGabor Marton         if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND)
150184d8767cSJohn McCall           Pos->second.remove(ND);
150284d8767cSJohn McCall       }
150326210db6SRichard Smith     } while (DC->isTransparentContext() && (DC = DC->getParent()));
150426210db6SRichard Smith   }
150584d8767cSJohn McCall }
150684d8767cSJohn McCall 
1507d1e9d835SJohn McCall void DeclContext::addHiddenDecl(Decl *D) {
150833f219d1SChris Lattner   assert(D->getLexicalDeclContext() == this &&
150933f219d1SChris Lattner          "Decl inserted into wrong lexical context");
1510fcd33a68SChris Lattner   assert(!D->getNextDeclInContext() && D != LastDecl &&
1511020713e3SDouglas Gregor          "Decl already inserted into a DeclContext");
1512020713e3SDouglas Gregor 
1513020713e3SDouglas Gregor   if (FirstDecl) {
1514781f713dSDouglas Gregor     LastDecl->NextInContextAndBits.setPointer(D);
1515020713e3SDouglas Gregor     LastDecl = D;
1516020713e3SDouglas Gregor   } else {
1517020713e3SDouglas Gregor     FirstDecl = LastDecl = D;
1518020713e3SDouglas Gregor   }
1519d30e79f8SDouglas Gregor 
1520a1ce1f80SDouglas Gregor   // Notify a C++ record declaration that we've added a member, so it can
15214b81fc87SNick Lewycky   // update its class-specific state.
15222a1ba94fSEugene Zelenko   if (auto *Record = dyn_cast<CXXRecordDecl>(this))
1523a1ce1f80SDouglas Gregor     Record->addedMember(D);
15240f2a3607SDouglas Gregor 
15250f2a3607SDouglas Gregor   // If this is a newly-created (not de-serialized) import declaration, wire
15260f2a3607SDouglas Gregor   // it in to the list of local import declarations.
15270f2a3607SDouglas Gregor   if (!D->isFromASTFile()) {
15282a1ba94fSEugene Zelenko     if (auto *Import = dyn_cast<ImportDecl>(D))
15290f2a3607SDouglas Gregor       D->getASTContext().addedLocalImportDecl(Import);
15300f2a3607SDouglas Gregor   }
1531d1e9d835SJohn McCall }
1532d1e9d835SJohn McCall 
1533d1e9d835SJohn McCall void DeclContext::addDecl(Decl *D) {
1534d1e9d835SJohn McCall   addHiddenDecl(D);
15356e6ad602SDouglas Gregor 
15362a1ba94fSEugene Zelenko   if (auto *ND = dyn_cast<NamedDecl>(D))
1537f634c900SRichard Smith     ND->getDeclContext()->getPrimaryContext()->
1538f634c900SRichard Smith         makeDeclVisibleInContextWithFlags(ND, false, true);
153991f84216SDouglas Gregor }
154091f84216SDouglas Gregor 
154195e74be1SSean Callanan void DeclContext::addDeclInternal(Decl *D) {
154295e74be1SSean Callanan   addHiddenDecl(D);
154395e74be1SSean Callanan 
15442a1ba94fSEugene Zelenko   if (auto *ND = dyn_cast<NamedDecl>(D))
1545f634c900SRichard Smith     ND->getDeclContext()->getPrimaryContext()->
1546f634c900SRichard Smith         makeDeclVisibleInContextWithFlags(ND, true, true);
1547f634c900SRichard Smith }
1548f634c900SRichard Smith 
1549f634c900SRichard Smith /// buildLookup - Build the lookup data structure with all of the
1550f634c900SRichard Smith /// declarations in this DeclContext (and any other contexts linked
1551f634c900SRichard Smith /// to it or transparent contexts nested within it) and return it.
1552a8b74591SRichard Smith ///
1553a8b74591SRichard Smith /// Note that the produced map may miss out declarations from an
1554a8b74591SRichard Smith /// external source. If it does, those entries will be marked with
1555a8b74591SRichard Smith /// the 'hasExternalDecls' flag.
1556f634c900SRichard Smith StoredDeclsMap *DeclContext::buildLookup() {
1557f634c900SRichard Smith   assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
1558f634c900SRichard Smith 
1559f92f31c6SErich Keane   if (!hasLazyLocalLexicalLookups() &&
1560f92f31c6SErich Keane       !hasLazyExternalLexicalLookups())
15619e2341d0SRichard Smith     return LookupPtr;
15629e2341d0SRichard Smith 
1563f857950dSDmitri Gribenko   SmallVector<DeclContext *, 2> Contexts;
1564f634c900SRichard Smith   collectAllContexts(Contexts);
156518b380b1SRichard Smith 
1566f92f31c6SErich Keane   if (hasLazyExternalLexicalLookups()) {
1567f92f31c6SErich Keane     setHasLazyExternalLexicalLookups(false);
156818b380b1SRichard Smith     for (auto *DC : Contexts) {
1569f92f31c6SErich Keane       if (DC->hasExternalLexicalStorage()) {
1570f92f31c6SErich Keane         bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1571f92f31c6SErich Keane         setHasLazyLocalLexicalLookups(
1572f92f31c6SErich Keane             hasLazyLocalLexicalLookups() | LoadedDecls );
1573f92f31c6SErich Keane       }
157418b380b1SRichard Smith     }
157518b380b1SRichard Smith 
1576f92f31c6SErich Keane     if (!hasLazyLocalLexicalLookups())
157718b380b1SRichard Smith       return LookupPtr;
157818b380b1SRichard Smith   }
157918b380b1SRichard Smith 
158018b380b1SRichard Smith   for (auto *DC : Contexts)
158118b380b1SRichard Smith     buildLookupImpl(DC, hasExternalVisibleStorage());
1582f634c900SRichard Smith 
1583f634c900SRichard Smith   // We no longer have any lazy decls.
1584f92f31c6SErich Keane   setHasLazyLocalLexicalLookups(false);
15859e2341d0SRichard Smith   return LookupPtr;
1586f634c900SRichard Smith }
1587f634c900SRichard Smith 
1588f634c900SRichard Smith /// buildLookupImpl - Build part of the lookup data structure for the
1589f634c900SRichard Smith /// declarations contained within DCtx, which will either be this
1590f634c900SRichard Smith /// DeclContext, a DeclContext linked to it, or a transparent context
1591f634c900SRichard Smith /// nested within it.
1592a3271c13SRichard Smith void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) {
15932a1ba94fSEugene Zelenko   for (auto *D : DCtx->noload_decls()) {
1594f634c900SRichard Smith     // Insert this declaration into the lookup structure, but only if
1595f634c900SRichard Smith     // it's semantically within its decl context. Any other decls which
1596f634c900SRichard Smith     // should be found in this context are added eagerly.
1597cf4ab520SRichard Smith     //
1598cf4ab520SRichard Smith     // If it's from an AST file, don't add it now. It'll get handled by
1599cf4ab520SRichard Smith     // FindExternalVisibleDeclsByName if needed. Exception: if we're not
1600cf4ab520SRichard Smith     // in C++, we do not track external visible decls for the TU, so in
1601cf4ab520SRichard Smith     // that case we need to collect them all here.
16022a1ba94fSEugene Zelenko     if (auto *ND = dyn_cast<NamedDecl>(D))
1603cf4ab520SRichard Smith       if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&
1604cf4ab520SRichard Smith           (!ND->isFromASTFile() ||
1605cf4ab520SRichard Smith            (isTranslationUnit() &&
1606cf4ab520SRichard Smith             !getParentASTContext().getLangOpts().CPlusPlus)))
1607a3271c13SRichard Smith         makeDeclVisibleInContextImpl(ND, Internal);
1608f634c900SRichard Smith 
1609f634c900SRichard Smith     // If this declaration is itself a transparent declaration context
1610f634c900SRichard Smith     // or inline namespace, add the members of this declaration of that
1611f634c900SRichard Smith     // context (recursively).
16122a1ba94fSEugene Zelenko     if (auto *InnerCtx = dyn_cast<DeclContext>(D))
1613f634c900SRichard Smith       if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
16149e2341d0SRichard Smith         buildLookupImpl(InnerCtx, Internal);
1615f634c900SRichard Smith   }
161695e74be1SSean Callanan }
161795e74be1SSean Callanan 
161840c78064SRichard Smith NamedDecl *const DeclContextLookupResult::SingleElementDummyList = nullptr;
161940c78064SRichard Smith 
162091f84216SDouglas Gregor DeclContext::lookup_result
162140c78064SRichard Smith DeclContext::lookup(DeclarationName Name) const {
1622f92f31c6SErich Keane   assert(getDeclKind() != Decl::LinkageSpec &&
1623f92f31c6SErich Keane          getDeclKind() != Decl::Export &&
16248df390f9SRichard Smith          "should not perform lookups into transparent contexts");
16252bd636f5SNick Lewycky 
16267d2f5c4aSManman Ren   const DeclContext *PrimaryContext = getPrimaryContext();
16277d2f5c4aSManman Ren   if (PrimaryContext != this)
16287d2f5c4aSManman Ren     return PrimaryContext->lookup(Name);
16297d2f5c4aSManman Ren 
16308cebe37fSRichard Smith   // If we have an external source, ensure that any later redeclarations of this
16318cebe37fSRichard Smith   // context have been loaded, since they may add names to the result of this
16328cebe37fSRichard Smith   // lookup (or add external visible storage).
16338cebe37fSRichard Smith   ExternalASTSource *Source = getParentASTContext().getExternalSource();
16348cebe37fSRichard Smith   if (Source)
16358cebe37fSRichard Smith     (void)cast<Decl>(this)->getMostRecentDecl();
1636bb853c79SRichard Smith 
1637f634c900SRichard Smith   if (hasExternalVisibleStorage()) {
16388cebe37fSRichard Smith     assert(Source && "external visible storage but no external source?");
16398cebe37fSRichard Smith 
1640f92f31c6SErich Keane     if (hasNeedToReconcileExternalVisibleStorage())
1641a8b74591SRichard Smith       reconcileExternalVisibleStorage();
1642a8b74591SRichard Smith 
16439e2341d0SRichard Smith     StoredDeclsMap *Map = LookupPtr;
1644a8b74591SRichard Smith 
1645f92f31c6SErich Keane     if (hasLazyLocalLexicalLookups() ||
1646f92f31c6SErich Keane         hasLazyExternalLexicalLookups())
164740c78064SRichard Smith       // FIXME: Make buildLookup const?
164840c78064SRichard Smith       Map = const_cast<DeclContext*>(this)->buildLookup();
1649645d755dSRichard Smith 
165075fc3bf5SRichard Smith     if (!Map)
165175fc3bf5SRichard Smith       Map = CreateStoredDeclsMap(getParentASTContext());
165275fc3bf5SRichard Smith 
16534abe0a8dSRichard Smith     // If we have a lookup result with no external decls, we are done.
165475fc3bf5SRichard Smith     std::pair<StoredDeclsMap::iterator, bool> R =
165575fc3bf5SRichard Smith         Map->insert(std::make_pair(Name, StoredDeclsList()));
16564abe0a8dSRichard Smith     if (!R.second && !R.first->second.hasExternalDecls())
165775fc3bf5SRichard Smith       return R.first->second.getLookupResult();
1658f634c900SRichard Smith 
1659309271b0SRichard Smith     if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
16609e2341d0SRichard Smith       if (StoredDeclsMap *Map = LookupPtr) {
16619ce12e36SRichard Smith         StoredDeclsMap::iterator I = Map->find(Name);
16629ce12e36SRichard Smith         if (I != Map->end())
16639ce12e36SRichard Smith           return I->second.getLookupResult();
16649ce12e36SRichard Smith       }
16659ce12e36SRichard Smith     }
16669ce12e36SRichard Smith 
16672a1ba94fSEugene Zelenko     return {};
166875b960e5SJohn McCall   }
1669ef84c4b4SDouglas Gregor 
16709e2341d0SRichard Smith   StoredDeclsMap *Map = LookupPtr;
1671f92f31c6SErich Keane   if (hasLazyLocalLexicalLookups() ||
1672f92f31c6SErich Keane       hasLazyExternalLexicalLookups())
167340c78064SRichard Smith     Map = const_cast<DeclContext*>(this)->buildLookup();
1674f634c900SRichard Smith 
1675f634c900SRichard Smith   if (!Map)
16762a1ba94fSEugene Zelenko     return {};
1677f634c900SRichard Smith 
1678f634c900SRichard Smith   StoredDeclsMap::iterator I = Map->find(Name);
1679f634c900SRichard Smith   if (I == Map->end())
16802a1ba94fSEugene Zelenko     return {};
1681f634c900SRichard Smith 
1682f634c900SRichard Smith   return I->second.getLookupResult();
16839615ec20SDouglas Gregor }
16849615ec20SDouglas Gregor 
168595d99308SRichard Smith DeclContext::lookup_result
168695d99308SRichard Smith DeclContext::noload_lookup(DeclarationName Name) {
1687f92f31c6SErich Keane   assert(getDeclKind() != Decl::LinkageSpec &&
1688f92f31c6SErich Keane          getDeclKind() != Decl::Export &&
16898df390f9SRichard Smith          "should not perform lookups into transparent contexts");
169095d99308SRichard Smith 
169195d99308SRichard Smith   DeclContext *PrimaryContext = getPrimaryContext();
169295d99308SRichard Smith   if (PrimaryContext != this)
169395d99308SRichard Smith     return PrimaryContext->noload_lookup(Name);
169495d99308SRichard Smith 
1695091b1efaSSam McCall   loadLazyLocalLexicalLookups();
16969e2341d0SRichard Smith   StoredDeclsMap *Map = LookupPtr;
169795d99308SRichard Smith   if (!Map)
16982a1ba94fSEugene Zelenko     return {};
169995d99308SRichard Smith 
170095d99308SRichard Smith   StoredDeclsMap::iterator I = Map->find(Name);
170136250ad6SCraig Topper   return I != Map->end() ? I->second.getLookupResult()
170240c78064SRichard Smith                          : lookup_result();
170395d99308SRichard Smith }
170495d99308SRichard Smith 
1705091b1efaSSam McCall // If we have any lazy lexical declarations not in our lookup map, add them
1706091b1efaSSam McCall // now. Don't import any external declarations, not even if we know we have
1707091b1efaSSam McCall // some missing from the external visible lookups.
1708091b1efaSSam McCall void DeclContext::loadLazyLocalLexicalLookups() {
1709f92f31c6SErich Keane   if (hasLazyLocalLexicalLookups()) {
1710091b1efaSSam McCall     SmallVector<DeclContext *, 2> Contexts;
1711091b1efaSSam McCall     collectAllContexts(Contexts);
17122a1ba94fSEugene Zelenko     for (auto *Context : Contexts)
17132a1ba94fSEugene Zelenko       buildLookupImpl(Context, hasExternalVisibleStorage());
1714f92f31c6SErich Keane     setHasLazyLocalLexicalLookups(false);
1715091b1efaSSam McCall   }
1716091b1efaSSam McCall }
1717091b1efaSSam McCall 
17189e0a5b39SDouglas Gregor void DeclContext::localUncachedLookup(DeclarationName Name,
1719f857950dSDmitri Gribenko                                       SmallVectorImpl<NamedDecl *> &Results) {
17209e0a5b39SDouglas Gregor   Results.clear();
17219e0a5b39SDouglas Gregor 
17229e0a5b39SDouglas Gregor   // If there's no external storage, just perform a normal lookup and copy
17239e0a5b39SDouglas Gregor   // the results.
1724dd6006f3SDouglas Gregor   if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
17259e0a5b39SDouglas Gregor     lookup_result LookupResults = lookup(Name);
1726ff7d47a3SDavid Blaikie     Results.insert(Results.end(), LookupResults.begin(), LookupResults.end());
17279e0a5b39SDouglas Gregor     return;
17289e0a5b39SDouglas Gregor   }
17299e0a5b39SDouglas Gregor 
17309e0a5b39SDouglas Gregor   // If we have a lookup table, check there first. Maybe we'll get lucky.
17319e2341d0SRichard Smith   // FIXME: Should we be checking these flags on the primary context?
1732f92f31c6SErich Keane   if (Name && !hasLazyLocalLexicalLookups() &&
1733f92f31c6SErich Keane       !hasLazyExternalLexicalLookups()) {
17349e2341d0SRichard Smith     if (StoredDeclsMap *Map = LookupPtr) {
1735f634c900SRichard Smith       StoredDeclsMap::iterator Pos = Map->find(Name);
1736f634c900SRichard Smith       if (Pos != Map->end()) {
17379e0a5b39SDouglas Gregor         Results.insert(Results.end(),
1738ff7d47a3SDavid Blaikie                        Pos->second.getLookupResult().begin(),
1739ff7d47a3SDavid Blaikie                        Pos->second.getLookupResult().end());
17409e0a5b39SDouglas Gregor         return;
17419e0a5b39SDouglas Gregor       }
17429e0a5b39SDouglas Gregor     }
1743dd6006f3SDouglas Gregor   }
17449e0a5b39SDouglas Gregor 
17459e0a5b39SDouglas Gregor   // Slow case: grovel through the declarations in our chain looking for
17469e0a5b39SDouglas Gregor   // matches.
17479e2341d0SRichard Smith   // FIXME: If we have lazy external declarations, this will not find them!
17489e2341d0SRichard Smith   // FIXME: Should we CollectAllContexts and walk them all here?
17499e0a5b39SDouglas Gregor   for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {
17502a1ba94fSEugene Zelenko     if (auto *ND = dyn_cast<NamedDecl>(D))
17519e0a5b39SDouglas Gregor       if (ND->getDeclName() == Name)
17529e0a5b39SDouglas Gregor         Results.push_back(ND);
17539e0a5b39SDouglas Gregor   }
17549e0a5b39SDouglas Gregor }
17559e0a5b39SDouglas Gregor 
175650c68258SSebastian Redl DeclContext *DeclContext::getRedeclContext() {
175717a1bfa9SChris Lattner   DeclContext *Ctx = this;
17585e7b1eaeSAaron Ballman 
17595e7b1eaeSAaron Ballman   // In C, a record type is the redeclaration context for its fields only. If
17605e7b1eaeSAaron Ballman   // we arrive at a record context after skipping anything else, we should skip
17615e7b1eaeSAaron Ballman   // the record as well. Currently, this means skipping enumerations because
17625e7b1eaeSAaron Ballman   // they're the only transparent context that can exist within a struct or
17635e7b1eaeSAaron Ballman   // union.
17645e7b1eaeSAaron Ballman   bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
17655e7b1eaeSAaron Ballman                      !getParentASTContext().getLangOpts().CPlusPlus;
17665e7b1eaeSAaron Ballman 
17675e7b1eaeSAaron Ballman   // Skip through contexts to get to the redeclaration context. Transparent
17685e7b1eaeSAaron Ballman   // contexts are always skipped.
17695e7b1eaeSAaron Ballman   while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())
17706ad0ef50SDouglas Gregor     Ctx = Ctx->getParent();
17716ad0ef50SDouglas Gregor   return Ctx;
17726ad0ef50SDouglas Gregor }
17736ad0ef50SDouglas Gregor 
1774f47b911fSDouglas Gregor DeclContext *DeclContext::getEnclosingNamespaceContext() {
1775f47b911fSDouglas Gregor   DeclContext *Ctx = this;
1776f47b911fSDouglas Gregor   // Skip through non-namespace, non-translation-unit contexts.
17774f08c96aSSebastian Redl   while (!Ctx->isFileContext())
1778f47b911fSDouglas Gregor     Ctx = Ctx->getParent();
1779f47b911fSDouglas Gregor   return Ctx->getPrimaryContext();
1780f47b911fSDouglas Gregor }
1781f47b911fSDouglas Gregor 
1782d60b82f9SReid Kleckner RecordDecl *DeclContext::getOuterLexicalRecordContext() {
1783d60b82f9SReid Kleckner   // Loop until we find a non-record context.
1784d60b82f9SReid Kleckner   RecordDecl *OutermostRD = nullptr;
1785d60b82f9SReid Kleckner   DeclContext *DC = this;
1786d60b82f9SReid Kleckner   while (DC->isRecord()) {
1787d60b82f9SReid Kleckner     OutermostRD = cast<RecordDecl>(DC);
1788d60b82f9SReid Kleckner     DC = DC->getLexicalParent();
1789d60b82f9SReid Kleckner   }
1790d60b82f9SReid Kleckner   return OutermostRD;
1791d60b82f9SReid Kleckner }
1792d60b82f9SReid Kleckner 
179350c68258SSebastian Redl bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const {
179450c68258SSebastian Redl   // For non-file contexts, this is equivalent to Equals.
179550c68258SSebastian Redl   if (!isFileContext())
179650c68258SSebastian Redl     return O->Equals(this);
179750c68258SSebastian Redl 
179850c68258SSebastian Redl   do {
179950c68258SSebastian Redl     if (O->Equals(this))
180050c68258SSebastian Redl       return true;
180150c68258SSebastian Redl 
18022a1ba94fSEugene Zelenko     const auto *NS = dyn_cast<NamespaceDecl>(O);
180350c68258SSebastian Redl     if (!NS || !NS->isInline())
180450c68258SSebastian Redl       break;
180550c68258SSebastian Redl     O = NS->getParent();
180650c68258SSebastian Redl   } while (O);
180750c68258SSebastian Redl 
180850c68258SSebastian Redl   return false;
180950c68258SSebastian Redl }
181050c68258SSebastian Redl 
1811f634c900SRichard Smith void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
1812f634c900SRichard Smith   DeclContext *PrimaryDC = this->getPrimaryContext();
1813f634c900SRichard Smith   DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();
1814f634c900SRichard Smith   // If the decl is being added outside of its semantic decl context, we
1815f634c900SRichard Smith   // need to ensure that we eagerly build the lookup information for it.
1816f634c900SRichard Smith   PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);
181795e74be1SSean Callanan }
181895e74be1SSean Callanan 
1819f634c900SRichard Smith void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
1820f634c900SRichard Smith                                                     bool Recoverable) {
1821f634c900SRichard Smith   assert(this == getPrimaryContext() && "expected a primary DC");
182295e74be1SSean Callanan 
182371eafdedSVassil Vassilev   if (!isLookupContext()) {
182471eafdedSVassil Vassilev     if (isTransparentContext())
182571eafdedSVassil Vassilev       getParent()->getPrimaryContext()
182671eafdedSVassil Vassilev         ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
182705afe5e0SRichard Smith     return;
182871eafdedSVassil Vassilev   }
182905afe5e0SRichard Smith 
1830f634c900SRichard Smith   // Skip declarations which should be invisible to name lookup.
1831f634c900SRichard Smith   if (shouldBeHidden(D))
1832f634c900SRichard Smith     return;
1833f634c900SRichard Smith 
1834f634c900SRichard Smith   // If we already have a lookup data structure, perform the insertion into
1835f634c900SRichard Smith   // it. If we might have externally-stored decls with this name, look them
1836f634c900SRichard Smith   // up and perform the insertion. If this decl was declared outside its
1837f634c900SRichard Smith   // semantic context, buildLookup won't add it, so add it now.
1838f634c900SRichard Smith   //
1839f634c900SRichard Smith   // FIXME: As a performance hack, don't add such decls into the translation
1840f634c900SRichard Smith   // unit unless we're in C++, since qualified lookup into the TU is never
1841f634c900SRichard Smith   // performed.
18429e2341d0SRichard Smith   if (LookupPtr || hasExternalVisibleStorage() ||
1843f634c900SRichard Smith       ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&
1844f634c900SRichard Smith        (getParentASTContext().getLangOpts().CPlusPlus ||
1845f634c900SRichard Smith         !isTranslationUnit()))) {
1846f634c900SRichard Smith     // If we have lazily omitted any decls, they might have the same name as
1847f634c900SRichard Smith     // the decl which we are adding, so build a full lookup table before adding
1848f634c900SRichard Smith     // this decl.
1849f634c900SRichard Smith     buildLookup();
1850f634c900SRichard Smith     makeDeclVisibleInContextImpl(D, Internal);
1851f634c900SRichard Smith   } else {
1852f92f31c6SErich Keane     setHasLazyLocalLexicalLookups(true);
1853f634c900SRichard Smith   }
1854f634c900SRichard Smith 
1855f634c900SRichard Smith   // If we are a transparent context or inline namespace, insert into our
1856f634c900SRichard Smith   // parent context, too. This operation is recursive.
1857f634c900SRichard Smith   if (isTransparentContext() || isInlineNamespace())
1858f634c900SRichard Smith     getParent()->getPrimaryContext()->
1859f634c900SRichard Smith         makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1860f634c900SRichard Smith 
18612a1ba94fSEugene Zelenko   auto *DCAsDecl = cast<Decl>(this);
1862f634c900SRichard Smith   // Notify that a decl was made visible unless we are a Tag being defined.
1863f634c900SRichard Smith   if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1864f634c900SRichard Smith     if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())
1865f634c900SRichard Smith       L->AddedVisibleDecl(this, D);
1866f634c900SRichard Smith }
1867f634c900SRichard Smith 
1868f634c900SRichard Smith void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
1869f634c900SRichard Smith   // Find or create the stored declaration map.
18709e2341d0SRichard Smith   StoredDeclsMap *Map = LookupPtr;
1871f634c900SRichard Smith   if (!Map) {
1872f634c900SRichard Smith     ASTContext *C = &getParentASTContext();
1873f634c900SRichard Smith     Map = CreateStoredDeclsMap(*C);
1874e51e554aSArgyrios Kyrtzidis   }
1875e51e554aSArgyrios Kyrtzidis 
1876ba88bfabSArgyrios Kyrtzidis   // If there is an external AST source, load any declarations it knows about
1877ba88bfabSArgyrios Kyrtzidis   // with this declaration's name.
1878ba88bfabSArgyrios Kyrtzidis   // If the lookup table contains an entry about this name it means that we
1879ba88bfabSArgyrios Kyrtzidis   // have already checked the external source.
188095e74be1SSean Callanan   if (!Internal)
1881ba88bfabSArgyrios Kyrtzidis     if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
1882ba88bfabSArgyrios Kyrtzidis       if (hasExternalVisibleStorage() &&
1883f634c900SRichard Smith           Map->find(D->getDeclName()) == Map->end())
1884ba88bfabSArgyrios Kyrtzidis         Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
1885ba88bfabSArgyrios Kyrtzidis 
188691f84216SDouglas Gregor   // Insert this declaration into the map.
1887f634c900SRichard Smith   StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];
18884abe0a8dSRichard Smith 
18894abe0a8dSRichard Smith   if (Internal) {
18904abe0a8dSRichard Smith     // If this is being added as part of loading an external declaration,
18914abe0a8dSRichard Smith     // this may not be the only external declaration with this name.
18924abe0a8dSRichard Smith     // In this case, we never try to replace an existing declaration; we'll
18934abe0a8dSRichard Smith     // handle that when we finalize the list of declarations for this name.
18944abe0a8dSRichard Smith     DeclNameEntries.setHasExternalDecls();
18954abe0a8dSRichard Smith     DeclNameEntries.AddSubsequentDecl(D);
18964abe0a8dSRichard Smith     return;
18974abe0a8dSRichard Smith   }
18984abe0a8dSRichard Smith 
1899a3271c13SRichard Smith   if (DeclNameEntries.isNull()) {
1900caae7168SChris Lattner     DeclNameEntries.setOnlyValue(D);
1901f634c900SRichard Smith     return;
190291f84216SDouglas Gregor   }
1903889ceb75SDouglas Gregor 
1904e8292b10SRichard Smith   if (DeclNameEntries.HandleRedeclaration(D, /*IsKnownNewer*/!Internal)) {
1905f634c900SRichard Smith     // This declaration has replaced an existing one for which
1906f634c900SRichard Smith     // declarationReplaces returns true.
1907f634c900SRichard Smith     return;
1908f634c900SRichard Smith   }
190905afe5e0SRichard Smith 
1910f634c900SRichard Smith   // Put this declaration into the appropriate slot.
1911f634c900SRichard Smith   DeclNameEntries.AddSubsequentDecl(D);
191205afe5e0SRichard Smith }
191305afe5e0SRichard Smith 
191440c78064SRichard Smith UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const {
191540c78064SRichard Smith   return cast<UsingDirectiveDecl>(*I);
191640c78064SRichard Smith }
191740c78064SRichard Smith 
1918889ceb75SDouglas Gregor /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
1919889ceb75SDouglas Gregor /// this context.
1920804a7fb7SAaron Ballman DeclContext::udir_range DeclContext::using_directives() const {
192105afe5e0SRichard Smith   // FIXME: Use something more efficient than normal lookup for using
192205afe5e0SRichard Smith   // directives. In C++, using directives are looked up more than anything else.
1923cf4bdde3SRichard Smith   lookup_result Result = lookup(UsingDirectiveDecl::getName());
192440c78064SRichard Smith   return udir_range(Result.begin(), Result.end());
1925889ceb75SDouglas Gregor }
1926ef84c4b4SDouglas Gregor 
1927da4e0d35STed Kremenek //===----------------------------------------------------------------------===//
1928da4e0d35STed Kremenek // Creation and Destruction of StoredDeclsMaps.                               //
1929da4e0d35STed Kremenek //===----------------------------------------------------------------------===//
1930da4e0d35STed Kremenek 
1931c62bb64cSJohn McCall StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {
19329e2341d0SRichard Smith   assert(!LookupPtr && "context already has a decls map");
1933c62bb64cSJohn McCall   assert(getPrimaryContext() == this &&
1934c62bb64cSJohn McCall          "creating decls map on non-primary context");
1935c62bb64cSJohn McCall 
1936c62bb64cSJohn McCall   StoredDeclsMap *M;
1937c62bb64cSJohn McCall   bool Dependent = isDependentContext();
1938c62bb64cSJohn McCall   if (Dependent)
1939c62bb64cSJohn McCall     M = new DependentStoredDeclsMap();
1940c62bb64cSJohn McCall   else
1941c62bb64cSJohn McCall     M = new StoredDeclsMap();
1942c62bb64cSJohn McCall   M->Previous = C.LastSDM;
1943c62bb64cSJohn McCall   C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
19449e2341d0SRichard Smith   LookupPtr = M;
1945da4e0d35STed Kremenek   return M;
1946da4e0d35STed Kremenek }
1947da4e0d35STed Kremenek 
1948da4e0d35STed Kremenek void ASTContext::ReleaseDeclContextMaps() {
1949c62bb64cSJohn McCall   // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap
1950c62bb64cSJohn McCall   // pointer because the subclass doesn't add anything that needs to
1951c62bb64cSJohn McCall   // be deleted.
1952c62bb64cSJohn McCall   StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());
1953c62bb64cSJohn McCall }
1954c62bb64cSJohn McCall 
1955c62bb64cSJohn McCall void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {
1956c62bb64cSJohn McCall   while (Map) {
1957c62bb64cSJohn McCall     // Advance the iteration before we invalidate memory.
1958c62bb64cSJohn McCall     llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1959c62bb64cSJohn McCall 
1960c62bb64cSJohn McCall     if (Dependent)
1961c62bb64cSJohn McCall       delete static_cast<DependentStoredDeclsMap*>(Map);
1962c62bb64cSJohn McCall     else
1963c62bb64cSJohn McCall       delete Map;
1964c62bb64cSJohn McCall 
1965c62bb64cSJohn McCall     Map = Next.getPointer();
1966c62bb64cSJohn McCall     Dependent = Next.getInt();
1967c62bb64cSJohn McCall   }
1968c62bb64cSJohn McCall }
1969c62bb64cSJohn McCall 
1970c62bb64cSJohn McCall DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
1971c62bb64cSJohn McCall                                                  DeclContext *Parent,
1972c62bb64cSJohn McCall                                            const PartialDiagnostic &PDiag) {
1973c62bb64cSJohn McCall   assert(Parent->isDependentContext()
1974c62bb64cSJohn McCall          && "cannot iterate dependent diagnostics of non-dependent context");
1975c62bb64cSJohn McCall   Parent = Parent->getPrimaryContext();
19769e2341d0SRichard Smith   if (!Parent->LookupPtr)
1977c62bb64cSJohn McCall     Parent->CreateStoredDeclsMap(C);
1978c62bb64cSJohn McCall 
19792a1ba94fSEugene Zelenko   auto *Map = static_cast<DependentStoredDeclsMap *>(Parent->LookupPtr);
1980c62bb64cSJohn McCall 
1981a55530e5SDouglas Gregor   // Allocate the copy of the PartialDiagnostic via the ASTContext's
19828933623bSDouglas Gregor   // BumpPtrAllocator, rather than the ASTContext itself.
198336250ad6SCraig Topper   PartialDiagnostic::Storage *DiagStorage = nullptr;
1984a55530e5SDouglas Gregor   if (PDiag.hasStorage())
1985a55530e5SDouglas Gregor     DiagStorage = new (C) PartialDiagnostic::Storage;
1986a55530e5SDouglas Gregor 
19872a1ba94fSEugene Zelenko   auto *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);
1988c62bb64cSJohn McCall 
1989c62bb64cSJohn McCall   // TODO: Maybe we shouldn't reverse the order during insertion.
1990c62bb64cSJohn McCall   DD->NextDiagnostic = Map->FirstDiagnostic;
1991c62bb64cSJohn McCall   Map->FirstDiagnostic = DD;
1992c62bb64cSJohn McCall 
1993c62bb64cSJohn McCall   return DD;
1994da4e0d35STed Kremenek }
1995