xref: /openbsd-src/gnu/llvm/clang/lib/AST/DeclBase.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements the Decl and DeclContext classes.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "clang/AST/DeclBase.h"
14e5dd7070Spatrick #include "clang/AST/ASTContext.h"
15e5dd7070Spatrick #include "clang/AST/ASTLambda.h"
16e5dd7070Spatrick #include "clang/AST/ASTMutationListener.h"
17e5dd7070Spatrick #include "clang/AST/Attr.h"
18e5dd7070Spatrick #include "clang/AST/AttrIterator.h"
19e5dd7070Spatrick #include "clang/AST/Decl.h"
20e5dd7070Spatrick #include "clang/AST/DeclCXX.h"
21e5dd7070Spatrick #include "clang/AST/DeclContextInternals.h"
22e5dd7070Spatrick #include "clang/AST/DeclFriend.h"
23e5dd7070Spatrick #include "clang/AST/DeclObjC.h"
24e5dd7070Spatrick #include "clang/AST/DeclOpenMP.h"
25e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
26e5dd7070Spatrick #include "clang/AST/DependentDiagnostic.h"
27e5dd7070Spatrick #include "clang/AST/ExternalASTSource.h"
28e5dd7070Spatrick #include "clang/AST/Stmt.h"
29e5dd7070Spatrick #include "clang/AST/Type.h"
30e5dd7070Spatrick #include "clang/Basic/IdentifierTable.h"
31e5dd7070Spatrick #include "clang/Basic/LLVM.h"
32e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
33e5dd7070Spatrick #include "clang/Basic/ObjCRuntime.h"
34e5dd7070Spatrick #include "clang/Basic/PartialDiagnostic.h"
35e5dd7070Spatrick #include "clang/Basic/SourceLocation.h"
36e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
37e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
38e5dd7070Spatrick #include "llvm/ADT/PointerIntPair.h"
39e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
40e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
41e5dd7070Spatrick #include "llvm/Support/Casting.h"
42e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
43e5dd7070Spatrick #include "llvm/Support/MathExtras.h"
44e5dd7070Spatrick #include "llvm/Support/VersionTuple.h"
45e5dd7070Spatrick #include "llvm/Support/raw_ostream.h"
46e5dd7070Spatrick #include <algorithm>
47e5dd7070Spatrick #include <cassert>
48e5dd7070Spatrick #include <cstddef>
49e5dd7070Spatrick #include <string>
50e5dd7070Spatrick #include <tuple>
51e5dd7070Spatrick #include <utility>
52e5dd7070Spatrick 
53e5dd7070Spatrick using namespace clang;
54e5dd7070Spatrick 
55e5dd7070Spatrick //===----------------------------------------------------------------------===//
56e5dd7070Spatrick //  Statistics
57e5dd7070Spatrick //===----------------------------------------------------------------------===//
58e5dd7070Spatrick 
59e5dd7070Spatrick #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
60e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
61e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
62e5dd7070Spatrick 
updateOutOfDate(IdentifierInfo & II) const63e5dd7070Spatrick void Decl::updateOutOfDate(IdentifierInfo &II) const {
64e5dd7070Spatrick   getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
65e5dd7070Spatrick }
66e5dd7070Spatrick 
67e5dd7070Spatrick #define DECL(DERIVED, BASE)                                                    \
68e5dd7070Spatrick   static_assert(alignof(Decl) >= alignof(DERIVED##Decl),                       \
69e5dd7070Spatrick                 "Alignment sufficient after objects prepended to " #DERIVED);
70e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
71e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
72e5dd7070Spatrick 
operator new(std::size_t Size,const ASTContext & Context,unsigned ID,std::size_t Extra)73e5dd7070Spatrick void *Decl::operator new(std::size_t Size, const ASTContext &Context,
74e5dd7070Spatrick                          unsigned ID, std::size_t Extra) {
75e5dd7070Spatrick   // Allocate an extra 8 bytes worth of storage, which ensures that the
76e5dd7070Spatrick   // resulting pointer will still be 8-byte aligned.
77e5dd7070Spatrick   static_assert(sizeof(unsigned) * 2 >= alignof(Decl),
78e5dd7070Spatrick                 "Decl won't be misaligned");
79e5dd7070Spatrick   void *Start = Context.Allocate(Size + Extra + 8);
80e5dd7070Spatrick   void *Result = (char*)Start + 8;
81e5dd7070Spatrick 
82e5dd7070Spatrick   unsigned *PrefixPtr = (unsigned *)Result - 2;
83e5dd7070Spatrick 
84e5dd7070Spatrick   // Zero out the first 4 bytes; this is used to store the owning module ID.
85e5dd7070Spatrick   PrefixPtr[0] = 0;
86e5dd7070Spatrick 
87e5dd7070Spatrick   // Store the global declaration ID in the second 4 bytes.
88e5dd7070Spatrick   PrefixPtr[1] = ID;
89e5dd7070Spatrick 
90e5dd7070Spatrick   return Result;
91e5dd7070Spatrick }
92e5dd7070Spatrick 
operator new(std::size_t Size,const ASTContext & Ctx,DeclContext * Parent,std::size_t Extra)93e5dd7070Spatrick void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
94e5dd7070Spatrick                          DeclContext *Parent, std::size_t Extra) {
95e5dd7070Spatrick   assert(!Parent || &Parent->getParentASTContext() == &Ctx);
96e5dd7070Spatrick   // With local visibility enabled, we track the owning module even for local
97e5dd7070Spatrick   // declarations. We create the TU decl early and may not yet know what the
98e5dd7070Spatrick   // LangOpts are, so conservatively allocate the storage.
99e5dd7070Spatrick   if (Ctx.getLangOpts().trackLocalOwningModule() || !Parent) {
100e5dd7070Spatrick     // Ensure required alignment of the resulting object by adding extra
101e5dd7070Spatrick     // padding at the start if required.
102e5dd7070Spatrick     size_t ExtraAlign =
103e5dd7070Spatrick         llvm::offsetToAlignment(sizeof(Module *), llvm::Align(alignof(Decl)));
104e5dd7070Spatrick     auto *Buffer = reinterpret_cast<char *>(
105e5dd7070Spatrick         ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));
106e5dd7070Spatrick     Buffer += ExtraAlign;
107e5dd7070Spatrick     auto *ParentModule =
108e5dd7070Spatrick         Parent ? cast<Decl>(Parent)->getOwningModule() : nullptr;
109e5dd7070Spatrick     return new (Buffer) Module*(ParentModule) + 1;
110e5dd7070Spatrick   }
111e5dd7070Spatrick   return ::operator new(Size + Extra, Ctx);
112e5dd7070Spatrick }
113e5dd7070Spatrick 
getOwningModuleSlow() const114e5dd7070Spatrick Module *Decl::getOwningModuleSlow() const {
115e5dd7070Spatrick   assert(isFromASTFile() && "Not from AST file?");
116e5dd7070Spatrick   return getASTContext().getExternalSource()->getModule(getOwningModuleID());
117e5dd7070Spatrick }
118e5dd7070Spatrick 
hasLocalOwningModuleStorage() const119e5dd7070Spatrick bool Decl::hasLocalOwningModuleStorage() const {
120e5dd7070Spatrick   return getASTContext().getLangOpts().trackLocalOwningModule();
121e5dd7070Spatrick }
122e5dd7070Spatrick 
getDeclKindName() const123e5dd7070Spatrick const char *Decl::getDeclKindName() const {
124e5dd7070Spatrick   switch (DeclKind) {
125e5dd7070Spatrick   default: llvm_unreachable("Declaration not in DeclNodes.inc!");
126e5dd7070Spatrick #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
127e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
128e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
129e5dd7070Spatrick   }
130e5dd7070Spatrick }
131e5dd7070Spatrick 
setInvalidDecl(bool Invalid)132e5dd7070Spatrick void Decl::setInvalidDecl(bool Invalid) {
133e5dd7070Spatrick   InvalidDecl = Invalid;
134e5dd7070Spatrick   assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
135e5dd7070Spatrick   if (!Invalid) {
136e5dd7070Spatrick     return;
137e5dd7070Spatrick   }
138e5dd7070Spatrick 
139e5dd7070Spatrick   if (!isa<ParmVarDecl>(this)) {
140e5dd7070Spatrick     // Defensive maneuver for ill-formed code: we're likely not to make it to
141e5dd7070Spatrick     // a point where we set the access specifier, so default it to "public"
142e5dd7070Spatrick     // to avoid triggering asserts elsewhere in the front end.
143e5dd7070Spatrick     setAccess(AS_public);
144e5dd7070Spatrick   }
145e5dd7070Spatrick 
146e5dd7070Spatrick   // Marking a DecompositionDecl as invalid implies all the child BindingDecl's
147e5dd7070Spatrick   // are invalid too.
148e5dd7070Spatrick   if (auto *DD = dyn_cast<DecompositionDecl>(this)) {
149e5dd7070Spatrick     for (auto *Binding : DD->bindings()) {
150e5dd7070Spatrick       Binding->setInvalidDecl();
151e5dd7070Spatrick     }
152e5dd7070Spatrick   }
153e5dd7070Spatrick }
154e5dd7070Spatrick 
hasValidDeclKind() const155*12c85518Srobert bool DeclContext::hasValidDeclKind() const {
156*12c85518Srobert   switch (getDeclKind()) {
157*12c85518Srobert #define DECL(DERIVED, BASE) case Decl::DERIVED: return true;
158*12c85518Srobert #define ABSTRACT_DECL(DECL)
159*12c85518Srobert #include "clang/AST/DeclNodes.inc"
160*12c85518Srobert   }
161*12c85518Srobert   return false;
162*12c85518Srobert }
163*12c85518Srobert 
getDeclKindName() const164e5dd7070Spatrick const char *DeclContext::getDeclKindName() const {
165e5dd7070Spatrick   switch (getDeclKind()) {
166e5dd7070Spatrick #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
167e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
168e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
169e5dd7070Spatrick   }
170e5dd7070Spatrick   llvm_unreachable("Declaration context not in DeclNodes.inc!");
171e5dd7070Spatrick }
172e5dd7070Spatrick 
173e5dd7070Spatrick bool Decl::StatisticsEnabled = false;
EnableStatistics()174e5dd7070Spatrick void Decl::EnableStatistics() {
175e5dd7070Spatrick   StatisticsEnabled = true;
176e5dd7070Spatrick }
177e5dd7070Spatrick 
PrintStats()178e5dd7070Spatrick void Decl::PrintStats() {
179e5dd7070Spatrick   llvm::errs() << "\n*** Decl Stats:\n";
180e5dd7070Spatrick 
181e5dd7070Spatrick   int totalDecls = 0;
182e5dd7070Spatrick #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
183e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
184e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
185e5dd7070Spatrick   llvm::errs() << "  " << totalDecls << " decls total.\n";
186e5dd7070Spatrick 
187e5dd7070Spatrick   int totalBytes = 0;
188e5dd7070Spatrick #define DECL(DERIVED, BASE)                                             \
189e5dd7070Spatrick   if (n##DERIVED##s > 0) {                                              \
190e5dd7070Spatrick     totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl));         \
191e5dd7070Spatrick     llvm::errs() << "    " << n##DERIVED##s << " " #DERIVED " decls, "  \
192e5dd7070Spatrick                  << sizeof(DERIVED##Decl) << " each ("                  \
193e5dd7070Spatrick                  << n##DERIVED##s * sizeof(DERIVED##Decl)               \
194e5dd7070Spatrick                  << " bytes)\n";                                        \
195e5dd7070Spatrick   }
196e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
197e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
198e5dd7070Spatrick 
199e5dd7070Spatrick   llvm::errs() << "Total bytes = " << totalBytes << "\n";
200e5dd7070Spatrick }
201e5dd7070Spatrick 
add(Kind k)202e5dd7070Spatrick void Decl::add(Kind k) {
203e5dd7070Spatrick   switch (k) {
204e5dd7070Spatrick #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
205e5dd7070Spatrick #define ABSTRACT_DECL(DECL)
206e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
207e5dd7070Spatrick   }
208e5dd7070Spatrick }
209e5dd7070Spatrick 
isTemplateParameterPack() const210e5dd7070Spatrick bool Decl::isTemplateParameterPack() const {
211e5dd7070Spatrick   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(this))
212e5dd7070Spatrick     return TTP->isParameterPack();
213e5dd7070Spatrick   if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(this))
214e5dd7070Spatrick     return NTTP->isParameterPack();
215e5dd7070Spatrick   if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(this))
216e5dd7070Spatrick     return TTP->isParameterPack();
217e5dd7070Spatrick   return false;
218e5dd7070Spatrick }
219e5dd7070Spatrick 
isParameterPack() const220e5dd7070Spatrick bool Decl::isParameterPack() const {
221e5dd7070Spatrick   if (const auto *Var = dyn_cast<VarDecl>(this))
222e5dd7070Spatrick     return Var->isParameterPack();
223e5dd7070Spatrick 
224e5dd7070Spatrick   return isTemplateParameterPack();
225e5dd7070Spatrick }
226e5dd7070Spatrick 
getAsFunction()227e5dd7070Spatrick FunctionDecl *Decl::getAsFunction() {
228e5dd7070Spatrick   if (auto *FD = dyn_cast<FunctionDecl>(this))
229e5dd7070Spatrick     return FD;
230e5dd7070Spatrick   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
231e5dd7070Spatrick     return FTD->getTemplatedDecl();
232e5dd7070Spatrick   return nullptr;
233e5dd7070Spatrick }
234e5dd7070Spatrick 
isTemplateDecl() const235e5dd7070Spatrick bool Decl::isTemplateDecl() const {
236e5dd7070Spatrick   return isa<TemplateDecl>(this);
237e5dd7070Spatrick }
238e5dd7070Spatrick 
getDescribedTemplate() const239e5dd7070Spatrick TemplateDecl *Decl::getDescribedTemplate() const {
240e5dd7070Spatrick   if (auto *FD = dyn_cast<FunctionDecl>(this))
241e5dd7070Spatrick     return FD->getDescribedFunctionTemplate();
242a9ac8606Spatrick   if (auto *RD = dyn_cast<CXXRecordDecl>(this))
243e5dd7070Spatrick     return RD->getDescribedClassTemplate();
244a9ac8606Spatrick   if (auto *VD = dyn_cast<VarDecl>(this))
245e5dd7070Spatrick     return VD->getDescribedVarTemplate();
246a9ac8606Spatrick   if (auto *AD = dyn_cast<TypeAliasDecl>(this))
247e5dd7070Spatrick     return AD->getDescribedAliasTemplate();
248e5dd7070Spatrick 
249e5dd7070Spatrick   return nullptr;
250e5dd7070Spatrick }
251e5dd7070Spatrick 
getDescribedTemplateParams() const252ec727ea7Spatrick const TemplateParameterList *Decl::getDescribedTemplateParams() const {
253ec727ea7Spatrick   if (auto *TD = getDescribedTemplate())
254ec727ea7Spatrick     return TD->getTemplateParameters();
255ec727ea7Spatrick   if (auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(this))
256ec727ea7Spatrick     return CTPSD->getTemplateParameters();
257ec727ea7Spatrick   if (auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(this))
258ec727ea7Spatrick     return VTPSD->getTemplateParameters();
259ec727ea7Spatrick   return nullptr;
260ec727ea7Spatrick }
261ec727ea7Spatrick 
isTemplated() const262e5dd7070Spatrick bool Decl::isTemplated() const {
263ec727ea7Spatrick   // A declaration is templated if it is a template or a template pattern, or
264*12c85518Srobert   // is within (lexcially for a friend or local function declaration,
265*12c85518Srobert   // semantically otherwise) a dependent context.
266e5dd7070Spatrick   if (auto *AsDC = dyn_cast<DeclContext>(this))
267e5dd7070Spatrick     return AsDC->isDependentContext();
268*12c85518Srobert   auto *DC = getFriendObjectKind() || isLocalExternDecl()
269*12c85518Srobert       ? getLexicalDeclContext() : getDeclContext();
270ec727ea7Spatrick   return DC->isDependentContext() || isTemplateDecl() ||
271ec727ea7Spatrick          getDescribedTemplateParams();
272ec727ea7Spatrick }
273ec727ea7Spatrick 
getTemplateDepth() const274ec727ea7Spatrick unsigned Decl::getTemplateDepth() const {
275ec727ea7Spatrick   if (auto *DC = dyn_cast<DeclContext>(this))
276ec727ea7Spatrick     if (DC->isFileContext())
277ec727ea7Spatrick       return 0;
278ec727ea7Spatrick 
279ec727ea7Spatrick   if (auto *TPL = getDescribedTemplateParams())
280ec727ea7Spatrick     return TPL->getDepth() + 1;
281ec727ea7Spatrick 
282ec727ea7Spatrick   // If this is a dependent lambda, there might be an enclosing variable
283ec727ea7Spatrick   // template. In this case, the next step is not the parent DeclContext (or
284ec727ea7Spatrick   // even a DeclContext at all).
285ec727ea7Spatrick   auto *RD = dyn_cast<CXXRecordDecl>(this);
286ec727ea7Spatrick   if (RD && RD->isDependentLambda())
287ec727ea7Spatrick     if (Decl *Context = RD->getLambdaContextDecl())
288ec727ea7Spatrick       return Context->getTemplateDepth();
289ec727ea7Spatrick 
290ec727ea7Spatrick   const DeclContext *DC =
291ec727ea7Spatrick       getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
292ec727ea7Spatrick   return cast<Decl>(DC)->getTemplateDepth();
293e5dd7070Spatrick }
294e5dd7070Spatrick 
getParentFunctionOrMethod(bool LexicalParent) const295*12c85518Srobert const DeclContext *Decl::getParentFunctionOrMethod(bool LexicalParent) const {
296*12c85518Srobert   for (const DeclContext *DC = LexicalParent ? getLexicalDeclContext()
297*12c85518Srobert                                              : getDeclContext();
298*12c85518Srobert        DC && !DC->isFileContext(); DC = DC->getParent())
299e5dd7070Spatrick     if (DC->isFunctionOrMethod())
300e5dd7070Spatrick       return DC;
301e5dd7070Spatrick 
302e5dd7070Spatrick   return nullptr;
303e5dd7070Spatrick }
304e5dd7070Spatrick 
305e5dd7070Spatrick //===----------------------------------------------------------------------===//
306e5dd7070Spatrick // PrettyStackTraceDecl Implementation
307e5dd7070Spatrick //===----------------------------------------------------------------------===//
308e5dd7070Spatrick 
print(raw_ostream & OS) const309e5dd7070Spatrick void PrettyStackTraceDecl::print(raw_ostream &OS) const {
310e5dd7070Spatrick   SourceLocation TheLoc = Loc;
311e5dd7070Spatrick   if (TheLoc.isInvalid() && TheDecl)
312e5dd7070Spatrick     TheLoc = TheDecl->getLocation();
313e5dd7070Spatrick 
314e5dd7070Spatrick   if (TheLoc.isValid()) {
315e5dd7070Spatrick     TheLoc.print(OS, SM);
316e5dd7070Spatrick     OS << ": ";
317e5dd7070Spatrick   }
318e5dd7070Spatrick 
319e5dd7070Spatrick   OS << Message;
320e5dd7070Spatrick 
321e5dd7070Spatrick   if (const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
322e5dd7070Spatrick     OS << " '";
323e5dd7070Spatrick     DN->printQualifiedName(OS);
324e5dd7070Spatrick     OS << '\'';
325e5dd7070Spatrick   }
326e5dd7070Spatrick   OS << '\n';
327e5dd7070Spatrick }
328e5dd7070Spatrick 
329e5dd7070Spatrick //===----------------------------------------------------------------------===//
330e5dd7070Spatrick // Decl Implementation
331e5dd7070Spatrick //===----------------------------------------------------------------------===//
332e5dd7070Spatrick 
333e5dd7070Spatrick // Out-of-line virtual method providing a home for Decl.
334e5dd7070Spatrick Decl::~Decl() = default;
335e5dd7070Spatrick 
setDeclContext(DeclContext * DC)336e5dd7070Spatrick void Decl::setDeclContext(DeclContext *DC) {
337e5dd7070Spatrick   DeclCtx = DC;
338e5dd7070Spatrick }
339e5dd7070Spatrick 
setLexicalDeclContext(DeclContext * DC)340e5dd7070Spatrick void Decl::setLexicalDeclContext(DeclContext *DC) {
341e5dd7070Spatrick   if (DC == getLexicalDeclContext())
342e5dd7070Spatrick     return;
343e5dd7070Spatrick 
344e5dd7070Spatrick   if (isInSemaDC()) {
345e5dd7070Spatrick     setDeclContextsImpl(getDeclContext(), DC, getASTContext());
346e5dd7070Spatrick   } else {
347e5dd7070Spatrick     getMultipleDC()->LexicalDC = DC;
348e5dd7070Spatrick   }
349e5dd7070Spatrick 
350e5dd7070Spatrick   // FIXME: We shouldn't be changing the lexical context of declarations
351e5dd7070Spatrick   // imported from AST files.
352e5dd7070Spatrick   if (!isFromASTFile()) {
353e5dd7070Spatrick     setModuleOwnershipKind(getModuleOwnershipKindForChildOf(DC));
354e5dd7070Spatrick     if (hasOwningModule())
355e5dd7070Spatrick       setLocalOwningModule(cast<Decl>(DC)->getOwningModule());
356e5dd7070Spatrick   }
357e5dd7070Spatrick 
358e5dd7070Spatrick   assert(
359e5dd7070Spatrick       (getModuleOwnershipKind() != ModuleOwnershipKind::VisibleWhenImported ||
360e5dd7070Spatrick        getOwningModule()) &&
361e5dd7070Spatrick       "hidden declaration has no owning module");
362e5dd7070Spatrick }
363e5dd7070Spatrick 
setDeclContextsImpl(DeclContext * SemaDC,DeclContext * LexicalDC,ASTContext & Ctx)364e5dd7070Spatrick void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
365e5dd7070Spatrick                                ASTContext &Ctx) {
366e5dd7070Spatrick   if (SemaDC == LexicalDC) {
367e5dd7070Spatrick     DeclCtx = SemaDC;
368e5dd7070Spatrick   } else {
369e5dd7070Spatrick     auto *MDC = new (Ctx) Decl::MultipleDC();
370e5dd7070Spatrick     MDC->SemanticDC = SemaDC;
371e5dd7070Spatrick     MDC->LexicalDC = LexicalDC;
372e5dd7070Spatrick     DeclCtx = MDC;
373e5dd7070Spatrick   }
374e5dd7070Spatrick }
375e5dd7070Spatrick 
isInLocalScopeForInstantiation() const376ec727ea7Spatrick bool Decl::isInLocalScopeForInstantiation() const {
377e5dd7070Spatrick   const DeclContext *LDC = getLexicalDeclContext();
378ec727ea7Spatrick   if (!LDC->isDependentContext())
379ec727ea7Spatrick     return false;
380e5dd7070Spatrick   while (true) {
381e5dd7070Spatrick     if (LDC->isFunctionOrMethod())
382e5dd7070Spatrick       return true;
383e5dd7070Spatrick     if (!isa<TagDecl>(LDC))
384e5dd7070Spatrick       return false;
385389bb291Spatrick     if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))
386389bb291Spatrick       if (CRD->isLambda())
387389bb291Spatrick         return true;
388e5dd7070Spatrick     LDC = LDC->getLexicalParent();
389e5dd7070Spatrick   }
390e5dd7070Spatrick   return false;
391e5dd7070Spatrick }
392e5dd7070Spatrick 
isInAnonymousNamespace() const393e5dd7070Spatrick bool Decl::isInAnonymousNamespace() const {
394e5dd7070Spatrick   for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {
395e5dd7070Spatrick     if (const auto *ND = dyn_cast<NamespaceDecl>(DC))
396e5dd7070Spatrick       if (ND->isAnonymousNamespace())
397e5dd7070Spatrick         return true;
398e5dd7070Spatrick   }
399e5dd7070Spatrick 
400e5dd7070Spatrick   return false;
401e5dd7070Spatrick }
402e5dd7070Spatrick 
isInStdNamespace() const403e5dd7070Spatrick bool Decl::isInStdNamespace() const {
404e5dd7070Spatrick   const DeclContext *DC = getDeclContext();
405e5dd7070Spatrick   return DC && DC->isStdNamespace();
406e5dd7070Spatrick }
407e5dd7070Spatrick 
isFileContextDecl() const408*12c85518Srobert bool Decl::isFileContextDecl() const {
409*12c85518Srobert   const auto *DC = dyn_cast<DeclContext>(this);
410*12c85518Srobert   return DC && DC->isFileContext();
411*12c85518Srobert }
412*12c85518Srobert 
getTranslationUnitDecl()413e5dd7070Spatrick TranslationUnitDecl *Decl::getTranslationUnitDecl() {
414e5dd7070Spatrick   if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
415e5dd7070Spatrick     return TUD;
416e5dd7070Spatrick 
417e5dd7070Spatrick   DeclContext *DC = getDeclContext();
418e5dd7070Spatrick   assert(DC && "This decl is not contained in a translation unit!");
419e5dd7070Spatrick 
420e5dd7070Spatrick   while (!DC->isTranslationUnit()) {
421e5dd7070Spatrick     DC = DC->getParent();
422e5dd7070Spatrick     assert(DC && "This decl is not contained in a translation unit!");
423e5dd7070Spatrick   }
424e5dd7070Spatrick 
425e5dd7070Spatrick   return cast<TranslationUnitDecl>(DC);
426e5dd7070Spatrick }
427e5dd7070Spatrick 
getASTContext() const428e5dd7070Spatrick ASTContext &Decl::getASTContext() const {
429e5dd7070Spatrick   return getTranslationUnitDecl()->getASTContext();
430e5dd7070Spatrick }
431e5dd7070Spatrick 
432ec727ea7Spatrick /// Helper to get the language options from the ASTContext.
433ec727ea7Spatrick /// Defined out of line to avoid depending on ASTContext.h.
getLangOpts() const434ec727ea7Spatrick const LangOptions &Decl::getLangOpts() const {
435ec727ea7Spatrick   return getASTContext().getLangOpts();
436ec727ea7Spatrick }
437ec727ea7Spatrick 
getASTMutationListener() const438e5dd7070Spatrick ASTMutationListener *Decl::getASTMutationListener() const {
439e5dd7070Spatrick   return getASTContext().getASTMutationListener();
440e5dd7070Spatrick }
441e5dd7070Spatrick 
getMaxAlignment() const442e5dd7070Spatrick unsigned Decl::getMaxAlignment() const {
443e5dd7070Spatrick   if (!hasAttrs())
444e5dd7070Spatrick     return 0;
445e5dd7070Spatrick 
446e5dd7070Spatrick   unsigned Align = 0;
447e5dd7070Spatrick   const AttrVec &V = getAttrs();
448e5dd7070Spatrick   ASTContext &Ctx = getASTContext();
449e5dd7070Spatrick   specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());
450ec727ea7Spatrick   for (; I != E; ++I) {
451ec727ea7Spatrick     if (!I->isAlignmentErrorDependent())
452e5dd7070Spatrick       Align = std::max(Align, I->getAlignment(Ctx));
453ec727ea7Spatrick   }
454e5dd7070Spatrick   return Align;
455e5dd7070Spatrick }
456e5dd7070Spatrick 
isUsed(bool CheckUsedAttr) const457e5dd7070Spatrick bool Decl::isUsed(bool CheckUsedAttr) const {
458e5dd7070Spatrick   const Decl *CanonD = getCanonicalDecl();
459e5dd7070Spatrick   if (CanonD->Used)
460e5dd7070Spatrick     return true;
461e5dd7070Spatrick 
462e5dd7070Spatrick   // Check for used attribute.
463e5dd7070Spatrick   // Ask the most recent decl, since attributes accumulate in the redecl chain.
464e5dd7070Spatrick   if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>())
465e5dd7070Spatrick     return true;
466e5dd7070Spatrick 
467e5dd7070Spatrick   // The information may have not been deserialized yet. Force deserialization
468e5dd7070Spatrick   // to complete the needed information.
469e5dd7070Spatrick   return getMostRecentDecl()->getCanonicalDecl()->Used;
470e5dd7070Spatrick }
471e5dd7070Spatrick 
markUsed(ASTContext & C)472e5dd7070Spatrick void Decl::markUsed(ASTContext &C) {
473e5dd7070Spatrick   if (isUsed(false))
474e5dd7070Spatrick     return;
475e5dd7070Spatrick 
476e5dd7070Spatrick   if (C.getASTMutationListener())
477e5dd7070Spatrick     C.getASTMutationListener()->DeclarationMarkedUsed(this);
478e5dd7070Spatrick 
479e5dd7070Spatrick   setIsUsed();
480e5dd7070Spatrick }
481e5dd7070Spatrick 
isReferenced() const482e5dd7070Spatrick bool Decl::isReferenced() const {
483e5dd7070Spatrick   if (Referenced)
484e5dd7070Spatrick     return true;
485e5dd7070Spatrick 
486e5dd7070Spatrick   // Check redeclarations.
487e5dd7070Spatrick   for (const auto *I : redecls())
488e5dd7070Spatrick     if (I->Referenced)
489e5dd7070Spatrick       return true;
490e5dd7070Spatrick 
491e5dd7070Spatrick   return false;
492e5dd7070Spatrick }
493e5dd7070Spatrick 
getExternalSourceSymbolAttr() const494e5dd7070Spatrick ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
495e5dd7070Spatrick   const Decl *Definition = nullptr;
496e5dd7070Spatrick   if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
497e5dd7070Spatrick     Definition = ID->getDefinition();
498e5dd7070Spatrick   } else if (auto *PD = dyn_cast<ObjCProtocolDecl>(this)) {
499e5dd7070Spatrick     Definition = PD->getDefinition();
500e5dd7070Spatrick   } else if (auto *TD = dyn_cast<TagDecl>(this)) {
501e5dd7070Spatrick     Definition = TD->getDefinition();
502e5dd7070Spatrick   }
503e5dd7070Spatrick   if (!Definition)
504e5dd7070Spatrick     Definition = this;
505e5dd7070Spatrick 
506e5dd7070Spatrick   if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())
507e5dd7070Spatrick     return attr;
508e5dd7070Spatrick   if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {
509e5dd7070Spatrick     return dcd->getAttr<ExternalSourceSymbolAttr>();
510e5dd7070Spatrick   }
511e5dd7070Spatrick 
512e5dd7070Spatrick   return nullptr;
513e5dd7070Spatrick }
514e5dd7070Spatrick 
hasDefiningAttr() const515e5dd7070Spatrick bool Decl::hasDefiningAttr() const {
516ec727ea7Spatrick   return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
517ec727ea7Spatrick          hasAttr<LoaderUninitializedAttr>();
518e5dd7070Spatrick }
519e5dd7070Spatrick 
getDefiningAttr() const520e5dd7070Spatrick const Attr *Decl::getDefiningAttr() const {
521e5dd7070Spatrick   if (auto *AA = getAttr<AliasAttr>())
522e5dd7070Spatrick     return AA;
523e5dd7070Spatrick   if (auto *IFA = getAttr<IFuncAttr>())
524e5dd7070Spatrick     return IFA;
525ec727ea7Spatrick   if (auto *NZA = getAttr<LoaderUninitializedAttr>())
526ec727ea7Spatrick     return NZA;
527e5dd7070Spatrick   return nullptr;
528e5dd7070Spatrick }
529e5dd7070Spatrick 
getRealizedPlatform(const AvailabilityAttr * A,const ASTContext & Context)530e5dd7070Spatrick static StringRef getRealizedPlatform(const AvailabilityAttr *A,
531e5dd7070Spatrick                                      const ASTContext &Context) {
532e5dd7070Spatrick   // Check if this is an App Extension "platform", and if so chop off
533e5dd7070Spatrick   // the suffix for matching with the actual platform.
534e5dd7070Spatrick   StringRef RealizedPlatform = A->getPlatform()->getName();
535e5dd7070Spatrick   if (!Context.getLangOpts().AppExt)
536e5dd7070Spatrick     return RealizedPlatform;
537e5dd7070Spatrick   size_t suffix = RealizedPlatform.rfind("_app_extension");
538e5dd7070Spatrick   if (suffix != StringRef::npos)
539e5dd7070Spatrick     return RealizedPlatform.slice(0, suffix);
540e5dd7070Spatrick   return RealizedPlatform;
541e5dd7070Spatrick }
542e5dd7070Spatrick 
543e5dd7070Spatrick /// Determine the availability of the given declaration based on
544e5dd7070Spatrick /// the target platform.
545e5dd7070Spatrick ///
546e5dd7070Spatrick /// When it returns an availability result other than \c AR_Available,
547e5dd7070Spatrick /// if the \p Message parameter is non-NULL, it will be set to a
548e5dd7070Spatrick /// string describing why the entity is unavailable.
549e5dd7070Spatrick ///
550e5dd7070Spatrick /// FIXME: Make these strings localizable, since they end up in
551e5dd7070Spatrick /// diagnostics.
CheckAvailability(ASTContext & Context,const AvailabilityAttr * A,std::string * Message,VersionTuple EnclosingVersion)552e5dd7070Spatrick static AvailabilityResult CheckAvailability(ASTContext &Context,
553e5dd7070Spatrick                                             const AvailabilityAttr *A,
554e5dd7070Spatrick                                             std::string *Message,
555e5dd7070Spatrick                                             VersionTuple EnclosingVersion) {
556e5dd7070Spatrick   if (EnclosingVersion.empty())
557e5dd7070Spatrick     EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();
558e5dd7070Spatrick 
559e5dd7070Spatrick   if (EnclosingVersion.empty())
560e5dd7070Spatrick     return AR_Available;
561e5dd7070Spatrick 
562e5dd7070Spatrick   StringRef ActualPlatform = A->getPlatform()->getName();
563e5dd7070Spatrick   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
564e5dd7070Spatrick 
565e5dd7070Spatrick   // Match the platform name.
566e5dd7070Spatrick   if (getRealizedPlatform(A, Context) != TargetPlatform)
567e5dd7070Spatrick     return AR_Available;
568e5dd7070Spatrick 
569e5dd7070Spatrick   StringRef PrettyPlatformName
570e5dd7070Spatrick     = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
571e5dd7070Spatrick 
572e5dd7070Spatrick   if (PrettyPlatformName.empty())
573e5dd7070Spatrick     PrettyPlatformName = ActualPlatform;
574e5dd7070Spatrick 
575e5dd7070Spatrick   std::string HintMessage;
576e5dd7070Spatrick   if (!A->getMessage().empty()) {
577e5dd7070Spatrick     HintMessage = " - ";
578e5dd7070Spatrick     HintMessage += A->getMessage();
579e5dd7070Spatrick   }
580e5dd7070Spatrick 
581e5dd7070Spatrick   // Make sure that this declaration has not been marked 'unavailable'.
582e5dd7070Spatrick   if (A->getUnavailable()) {
583e5dd7070Spatrick     if (Message) {
584e5dd7070Spatrick       Message->clear();
585e5dd7070Spatrick       llvm::raw_string_ostream Out(*Message);
586e5dd7070Spatrick       Out << "not available on " << PrettyPlatformName
587e5dd7070Spatrick           << HintMessage;
588e5dd7070Spatrick     }
589e5dd7070Spatrick 
590e5dd7070Spatrick     return AR_Unavailable;
591e5dd7070Spatrick   }
592e5dd7070Spatrick 
593e5dd7070Spatrick   // Make sure that this declaration has already been introduced.
594e5dd7070Spatrick   if (!A->getIntroduced().empty() &&
595e5dd7070Spatrick       EnclosingVersion < A->getIntroduced()) {
596e5dd7070Spatrick     if (Message) {
597e5dd7070Spatrick       Message->clear();
598e5dd7070Spatrick       llvm::raw_string_ostream Out(*Message);
599e5dd7070Spatrick       VersionTuple VTI(A->getIntroduced());
600e5dd7070Spatrick       Out << "introduced in " << PrettyPlatformName << ' '
601e5dd7070Spatrick           << VTI << HintMessage;
602e5dd7070Spatrick     }
603e5dd7070Spatrick 
604e5dd7070Spatrick     return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced;
605e5dd7070Spatrick   }
606e5dd7070Spatrick 
607e5dd7070Spatrick   // Make sure that this declaration hasn't been obsoleted.
608e5dd7070Spatrick   if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
609e5dd7070Spatrick     if (Message) {
610e5dd7070Spatrick       Message->clear();
611e5dd7070Spatrick       llvm::raw_string_ostream Out(*Message);
612e5dd7070Spatrick       VersionTuple VTO(A->getObsoleted());
613e5dd7070Spatrick       Out << "obsoleted in " << PrettyPlatformName << ' '
614e5dd7070Spatrick           << VTO << HintMessage;
615e5dd7070Spatrick     }
616e5dd7070Spatrick 
617e5dd7070Spatrick     return AR_Unavailable;
618e5dd7070Spatrick   }
619e5dd7070Spatrick 
620e5dd7070Spatrick   // Make sure that this declaration hasn't been deprecated.
621e5dd7070Spatrick   if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
622e5dd7070Spatrick     if (Message) {
623e5dd7070Spatrick       Message->clear();
624e5dd7070Spatrick       llvm::raw_string_ostream Out(*Message);
625e5dd7070Spatrick       VersionTuple VTD(A->getDeprecated());
626e5dd7070Spatrick       Out << "first deprecated in " << PrettyPlatformName << ' '
627e5dd7070Spatrick           << VTD << HintMessage;
628e5dd7070Spatrick     }
629e5dd7070Spatrick 
630e5dd7070Spatrick     return AR_Deprecated;
631e5dd7070Spatrick   }
632e5dd7070Spatrick 
633e5dd7070Spatrick   return AR_Available;
634e5dd7070Spatrick }
635e5dd7070Spatrick 
getAvailability(std::string * Message,VersionTuple EnclosingVersion,StringRef * RealizedPlatform) const636e5dd7070Spatrick AvailabilityResult Decl::getAvailability(std::string *Message,
637e5dd7070Spatrick                                          VersionTuple EnclosingVersion,
638e5dd7070Spatrick                                          StringRef *RealizedPlatform) const {
639e5dd7070Spatrick   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
640e5dd7070Spatrick     return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
641e5dd7070Spatrick                                                     RealizedPlatform);
642e5dd7070Spatrick 
643e5dd7070Spatrick   AvailabilityResult Result = AR_Available;
644e5dd7070Spatrick   std::string ResultMessage;
645e5dd7070Spatrick 
646e5dd7070Spatrick   for (const auto *A : attrs()) {
647e5dd7070Spatrick     if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
648e5dd7070Spatrick       if (Result >= AR_Deprecated)
649e5dd7070Spatrick         continue;
650e5dd7070Spatrick 
651e5dd7070Spatrick       if (Message)
652ec727ea7Spatrick         ResultMessage = std::string(Deprecated->getMessage());
653e5dd7070Spatrick 
654e5dd7070Spatrick       Result = AR_Deprecated;
655e5dd7070Spatrick       continue;
656e5dd7070Spatrick     }
657e5dd7070Spatrick 
658e5dd7070Spatrick     if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
659e5dd7070Spatrick       if (Message)
660ec727ea7Spatrick         *Message = std::string(Unavailable->getMessage());
661e5dd7070Spatrick       return AR_Unavailable;
662e5dd7070Spatrick     }
663e5dd7070Spatrick 
664e5dd7070Spatrick     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
665e5dd7070Spatrick       AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
666e5dd7070Spatrick                                                 Message, EnclosingVersion);
667e5dd7070Spatrick 
668e5dd7070Spatrick       if (AR == AR_Unavailable) {
669e5dd7070Spatrick         if (RealizedPlatform)
670e5dd7070Spatrick           *RealizedPlatform = Availability->getPlatform()->getName();
671e5dd7070Spatrick         return AR_Unavailable;
672e5dd7070Spatrick       }
673e5dd7070Spatrick 
674e5dd7070Spatrick       if (AR > Result) {
675e5dd7070Spatrick         Result = AR;
676e5dd7070Spatrick         if (Message)
677e5dd7070Spatrick           ResultMessage.swap(*Message);
678e5dd7070Spatrick       }
679e5dd7070Spatrick       continue;
680e5dd7070Spatrick     }
681e5dd7070Spatrick   }
682e5dd7070Spatrick 
683e5dd7070Spatrick   if (Message)
684e5dd7070Spatrick     Message->swap(ResultMessage);
685e5dd7070Spatrick   return Result;
686e5dd7070Spatrick }
687e5dd7070Spatrick 
getVersionIntroduced() const688e5dd7070Spatrick VersionTuple Decl::getVersionIntroduced() const {
689e5dd7070Spatrick   const ASTContext &Context = getASTContext();
690e5dd7070Spatrick   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
691e5dd7070Spatrick   for (const auto *A : attrs()) {
692e5dd7070Spatrick     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
693e5dd7070Spatrick       if (getRealizedPlatform(Availability, Context) != TargetPlatform)
694e5dd7070Spatrick         continue;
695e5dd7070Spatrick       if (!Availability->getIntroduced().empty())
696e5dd7070Spatrick         return Availability->getIntroduced();
697e5dd7070Spatrick     }
698e5dd7070Spatrick   }
699e5dd7070Spatrick   return {};
700e5dd7070Spatrick }
701e5dd7070Spatrick 
canBeWeakImported(bool & IsDefinition) const702e5dd7070Spatrick bool Decl::canBeWeakImported(bool &IsDefinition) const {
703e5dd7070Spatrick   IsDefinition = false;
704e5dd7070Spatrick 
705e5dd7070Spatrick   // Variables, if they aren't definitions.
706e5dd7070Spatrick   if (const auto *Var = dyn_cast<VarDecl>(this)) {
707e5dd7070Spatrick     if (Var->isThisDeclarationADefinition()) {
708e5dd7070Spatrick       IsDefinition = true;
709e5dd7070Spatrick       return false;
710e5dd7070Spatrick     }
711e5dd7070Spatrick     return true;
712a9ac8606Spatrick   }
713e5dd7070Spatrick   // Functions, if they aren't definitions.
714a9ac8606Spatrick   if (const auto *FD = dyn_cast<FunctionDecl>(this)) {
715e5dd7070Spatrick     if (FD->hasBody()) {
716e5dd7070Spatrick       IsDefinition = true;
717e5dd7070Spatrick       return false;
718e5dd7070Spatrick     }
719e5dd7070Spatrick     return true;
720e5dd7070Spatrick 
721a9ac8606Spatrick   }
722e5dd7070Spatrick   // Objective-C classes, if this is the non-fragile runtime.
723a9ac8606Spatrick   if (isa<ObjCInterfaceDecl>(this) &&
724e5dd7070Spatrick              getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {
725e5dd7070Spatrick     return true;
726e5dd7070Spatrick   }
727a9ac8606Spatrick   // Nothing else.
728a9ac8606Spatrick   return false;
729e5dd7070Spatrick }
730e5dd7070Spatrick 
isWeakImported() const731e5dd7070Spatrick bool Decl::isWeakImported() const {
732e5dd7070Spatrick   bool IsDefinition;
733e5dd7070Spatrick   if (!canBeWeakImported(IsDefinition))
734e5dd7070Spatrick     return false;
735e5dd7070Spatrick 
736a9ac8606Spatrick   for (const auto *A : getMostRecentDecl()->attrs()) {
737e5dd7070Spatrick     if (isa<WeakImportAttr>(A))
738e5dd7070Spatrick       return true;
739e5dd7070Spatrick 
740e5dd7070Spatrick     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
741e5dd7070Spatrick       if (CheckAvailability(getASTContext(), Availability, nullptr,
742e5dd7070Spatrick                             VersionTuple()) == AR_NotYetIntroduced)
743e5dd7070Spatrick         return true;
744e5dd7070Spatrick     }
745e5dd7070Spatrick   }
746e5dd7070Spatrick 
747e5dd7070Spatrick   return false;
748e5dd7070Spatrick }
749e5dd7070Spatrick 
getIdentifierNamespaceForKind(Kind DeclKind)750e5dd7070Spatrick unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
751e5dd7070Spatrick   switch (DeclKind) {
752e5dd7070Spatrick     case Function:
753e5dd7070Spatrick     case CXXDeductionGuide:
754e5dd7070Spatrick     case CXXMethod:
755e5dd7070Spatrick     case CXXConstructor:
756e5dd7070Spatrick     case ConstructorUsingShadow:
757e5dd7070Spatrick     case CXXDestructor:
758e5dd7070Spatrick     case CXXConversion:
759e5dd7070Spatrick     case EnumConstant:
760e5dd7070Spatrick     case Var:
761e5dd7070Spatrick     case ImplicitParam:
762e5dd7070Spatrick     case ParmVar:
763e5dd7070Spatrick     case ObjCMethod:
764e5dd7070Spatrick     case ObjCProperty:
765e5dd7070Spatrick     case MSProperty:
766*12c85518Srobert     case HLSLBuffer:
767e5dd7070Spatrick       return IDNS_Ordinary;
768e5dd7070Spatrick     case Label:
769e5dd7070Spatrick       return IDNS_Label;
770e5dd7070Spatrick     case IndirectField:
771e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Member;
772e5dd7070Spatrick 
773e5dd7070Spatrick     case Binding:
774e5dd7070Spatrick     case NonTypeTemplateParm:
775e5dd7070Spatrick     case VarTemplate:
776e5dd7070Spatrick     case Concept:
777e5dd7070Spatrick       // These (C++-only) declarations are found by redeclaration lookup for
778e5dd7070Spatrick       // tag types, so we include them in the tag namespace.
779e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Tag;
780e5dd7070Spatrick 
781e5dd7070Spatrick     case ObjCCompatibleAlias:
782e5dd7070Spatrick     case ObjCInterface:
783e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Type;
784e5dd7070Spatrick 
785e5dd7070Spatrick     case Typedef:
786e5dd7070Spatrick     case TypeAlias:
787e5dd7070Spatrick     case TemplateTypeParm:
788e5dd7070Spatrick     case ObjCTypeParam:
789e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Type;
790e5dd7070Spatrick 
791e5dd7070Spatrick     case UnresolvedUsingTypename:
792e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Type | IDNS_Using;
793e5dd7070Spatrick 
794e5dd7070Spatrick     case UsingShadow:
795e5dd7070Spatrick       return 0; // we'll actually overwrite this later
796e5dd7070Spatrick 
797e5dd7070Spatrick     case UnresolvedUsingValue:
798e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Using;
799e5dd7070Spatrick 
800e5dd7070Spatrick     case Using:
801e5dd7070Spatrick     case UsingPack:
802a9ac8606Spatrick     case UsingEnum:
803e5dd7070Spatrick       return IDNS_Using;
804e5dd7070Spatrick 
805e5dd7070Spatrick     case ObjCProtocol:
806e5dd7070Spatrick       return IDNS_ObjCProtocol;
807e5dd7070Spatrick 
808e5dd7070Spatrick     case Field:
809e5dd7070Spatrick     case ObjCAtDefsField:
810e5dd7070Spatrick     case ObjCIvar:
811e5dd7070Spatrick       return IDNS_Member;
812e5dd7070Spatrick 
813e5dd7070Spatrick     case Record:
814e5dd7070Spatrick     case CXXRecord:
815e5dd7070Spatrick     case Enum:
816e5dd7070Spatrick       return IDNS_Tag | IDNS_Type;
817e5dd7070Spatrick 
818e5dd7070Spatrick     case Namespace:
819e5dd7070Spatrick     case NamespaceAlias:
820e5dd7070Spatrick       return IDNS_Namespace;
821e5dd7070Spatrick 
822e5dd7070Spatrick     case FunctionTemplate:
823e5dd7070Spatrick       return IDNS_Ordinary;
824e5dd7070Spatrick 
825e5dd7070Spatrick     case ClassTemplate:
826e5dd7070Spatrick     case TemplateTemplateParm:
827e5dd7070Spatrick     case TypeAliasTemplate:
828e5dd7070Spatrick       return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
829e5dd7070Spatrick 
830a9ac8606Spatrick     case UnresolvedUsingIfExists:
831a9ac8606Spatrick       return IDNS_Type | IDNS_Ordinary;
832a9ac8606Spatrick 
833e5dd7070Spatrick     case OMPDeclareReduction:
834e5dd7070Spatrick       return IDNS_OMPReduction;
835e5dd7070Spatrick 
836e5dd7070Spatrick     case OMPDeclareMapper:
837e5dd7070Spatrick       return IDNS_OMPMapper;
838e5dd7070Spatrick 
839e5dd7070Spatrick     // Never have names.
840e5dd7070Spatrick     case Friend:
841e5dd7070Spatrick     case FriendTemplate:
842e5dd7070Spatrick     case AccessSpec:
843e5dd7070Spatrick     case LinkageSpec:
844e5dd7070Spatrick     case Export:
845e5dd7070Spatrick     case FileScopeAsm:
846*12c85518Srobert     case TopLevelStmt:
847e5dd7070Spatrick     case StaticAssert:
848e5dd7070Spatrick     case ObjCPropertyImpl:
849e5dd7070Spatrick     case PragmaComment:
850e5dd7070Spatrick     case PragmaDetectMismatch:
851e5dd7070Spatrick     case Block:
852e5dd7070Spatrick     case Captured:
853e5dd7070Spatrick     case TranslationUnit:
854e5dd7070Spatrick     case ExternCContext:
855e5dd7070Spatrick     case Decomposition:
856ec727ea7Spatrick     case MSGuid:
857*12c85518Srobert     case UnnamedGlobalConstant:
858a9ac8606Spatrick     case TemplateParamObject:
859e5dd7070Spatrick 
860e5dd7070Spatrick     case UsingDirective:
861e5dd7070Spatrick     case BuiltinTemplate:
862e5dd7070Spatrick     case ClassTemplateSpecialization:
863e5dd7070Spatrick     case ClassTemplatePartialSpecialization:
864e5dd7070Spatrick     case ClassScopeFunctionSpecialization:
865e5dd7070Spatrick     case VarTemplateSpecialization:
866e5dd7070Spatrick     case VarTemplatePartialSpecialization:
867e5dd7070Spatrick     case ObjCImplementation:
868e5dd7070Spatrick     case ObjCCategory:
869e5dd7070Spatrick     case ObjCCategoryImpl:
870e5dd7070Spatrick     case Import:
871e5dd7070Spatrick     case OMPThreadPrivate:
872e5dd7070Spatrick     case OMPAllocate:
873e5dd7070Spatrick     case OMPRequires:
874e5dd7070Spatrick     case OMPCapturedExpr:
875e5dd7070Spatrick     case Empty:
876e5dd7070Spatrick     case LifetimeExtendedTemporary:
877e5dd7070Spatrick     case RequiresExprBody:
878*12c85518Srobert     case ImplicitConceptSpecialization:
879e5dd7070Spatrick       // Never looked up by name.
880e5dd7070Spatrick       return 0;
881e5dd7070Spatrick   }
882e5dd7070Spatrick 
883e5dd7070Spatrick   llvm_unreachable("Invalid DeclKind!");
884e5dd7070Spatrick }
885e5dd7070Spatrick 
setAttrsImpl(const AttrVec & attrs,ASTContext & Ctx)886e5dd7070Spatrick void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
887e5dd7070Spatrick   assert(!HasAttrs && "Decl already contains attrs.");
888e5dd7070Spatrick 
889e5dd7070Spatrick   AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
890e5dd7070Spatrick   assert(AttrBlank.empty() && "HasAttrs was wrong?");
891e5dd7070Spatrick 
892e5dd7070Spatrick   AttrBlank = attrs;
893e5dd7070Spatrick   HasAttrs = true;
894e5dd7070Spatrick }
895e5dd7070Spatrick 
dropAttrs()896e5dd7070Spatrick void Decl::dropAttrs() {
897e5dd7070Spatrick   if (!HasAttrs) return;
898e5dd7070Spatrick 
899e5dd7070Spatrick   HasAttrs = false;
900e5dd7070Spatrick   getASTContext().eraseDeclAttrs(this);
901e5dd7070Spatrick }
902e5dd7070Spatrick 
addAttr(Attr * A)903e5dd7070Spatrick void Decl::addAttr(Attr *A) {
904e5dd7070Spatrick   if (!hasAttrs()) {
905e5dd7070Spatrick     setAttrs(AttrVec(1, A));
906e5dd7070Spatrick     return;
907e5dd7070Spatrick   }
908e5dd7070Spatrick 
909e5dd7070Spatrick   AttrVec &Attrs = getAttrs();
910e5dd7070Spatrick   if (!A->isInherited()) {
911e5dd7070Spatrick     Attrs.push_back(A);
912e5dd7070Spatrick     return;
913e5dd7070Spatrick   }
914e5dd7070Spatrick 
915e5dd7070Spatrick   // Attribute inheritance is processed after attribute parsing. To keep the
916e5dd7070Spatrick   // order as in the source code, add inherited attributes before non-inherited
917e5dd7070Spatrick   // ones.
918e5dd7070Spatrick   auto I = Attrs.begin(), E = Attrs.end();
919e5dd7070Spatrick   for (; I != E; ++I) {
920e5dd7070Spatrick     if (!(*I)->isInherited())
921e5dd7070Spatrick       break;
922e5dd7070Spatrick   }
923e5dd7070Spatrick   Attrs.insert(I, A);
924e5dd7070Spatrick }
925e5dd7070Spatrick 
getAttrs() const926e5dd7070Spatrick const AttrVec &Decl::getAttrs() const {
927e5dd7070Spatrick   assert(HasAttrs && "No attrs to get!");
928e5dd7070Spatrick   return getASTContext().getDeclAttrs(this);
929e5dd7070Spatrick }
930e5dd7070Spatrick 
castFromDeclContext(const DeclContext * D)931e5dd7070Spatrick Decl *Decl::castFromDeclContext (const DeclContext *D) {
932e5dd7070Spatrick   Decl::Kind DK = D->getDeclKind();
933e5dd7070Spatrick   switch(DK) {
934e5dd7070Spatrick #define DECL(NAME, BASE)
935e5dd7070Spatrick #define DECL_CONTEXT(NAME) \
936e5dd7070Spatrick     case Decl::NAME:       \
937e5dd7070Spatrick       return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
938e5dd7070Spatrick #define DECL_CONTEXT_BASE(NAME)
939e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
940e5dd7070Spatrick     default:
941e5dd7070Spatrick #define DECL(NAME, BASE)
942e5dd7070Spatrick #define DECL_CONTEXT_BASE(NAME)                  \
943e5dd7070Spatrick       if (DK >= first##NAME && DK <= last##NAME) \
944e5dd7070Spatrick         return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
945e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
946e5dd7070Spatrick       llvm_unreachable("a decl that inherits DeclContext isn't handled");
947e5dd7070Spatrick   }
948e5dd7070Spatrick }
949e5dd7070Spatrick 
castToDeclContext(const Decl * D)950e5dd7070Spatrick DeclContext *Decl::castToDeclContext(const Decl *D) {
951e5dd7070Spatrick   Decl::Kind DK = D->getKind();
952e5dd7070Spatrick   switch(DK) {
953e5dd7070Spatrick #define DECL(NAME, BASE)
954e5dd7070Spatrick #define DECL_CONTEXT(NAME) \
955e5dd7070Spatrick     case Decl::NAME:       \
956e5dd7070Spatrick       return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
957e5dd7070Spatrick #define DECL_CONTEXT_BASE(NAME)
958e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
959e5dd7070Spatrick     default:
960e5dd7070Spatrick #define DECL(NAME, BASE)
961e5dd7070Spatrick #define DECL_CONTEXT_BASE(NAME)                                   \
962e5dd7070Spatrick       if (DK >= first##NAME && DK <= last##NAME)                  \
963e5dd7070Spatrick         return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
964e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
965e5dd7070Spatrick       llvm_unreachable("a decl that inherits DeclContext isn't handled");
966e5dd7070Spatrick   }
967e5dd7070Spatrick }
968e5dd7070Spatrick 
getBodyRBrace() const969e5dd7070Spatrick SourceLocation Decl::getBodyRBrace() const {
970e5dd7070Spatrick   // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
971e5dd7070Spatrick   // FunctionDecl stores EndRangeLoc for this purpose.
972e5dd7070Spatrick   if (const auto *FD = dyn_cast<FunctionDecl>(this)) {
973e5dd7070Spatrick     const FunctionDecl *Definition;
974e5dd7070Spatrick     if (FD->hasBody(Definition))
975e5dd7070Spatrick       return Definition->getSourceRange().getEnd();
976e5dd7070Spatrick     return {};
977e5dd7070Spatrick   }
978e5dd7070Spatrick 
979e5dd7070Spatrick   if (Stmt *Body = getBody())
980e5dd7070Spatrick     return Body->getSourceRange().getEnd();
981e5dd7070Spatrick 
982e5dd7070Spatrick   return {};
983e5dd7070Spatrick }
984e5dd7070Spatrick 
AccessDeclContextCheck() const985*12c85518Srobert bool Decl::AccessDeclContextCheck() const {
986e5dd7070Spatrick #ifndef NDEBUG
987e5dd7070Spatrick   // Suppress this check if any of the following hold:
988e5dd7070Spatrick   // 1. this is the translation unit (and thus has no parent)
989e5dd7070Spatrick   // 2. this is a template parameter (and thus doesn't belong to its context)
990e5dd7070Spatrick   // 3. this is a non-type template parameter
991e5dd7070Spatrick   // 4. the context is not a record
992e5dd7070Spatrick   // 5. it's invalid
993e5dd7070Spatrick   // 6. it's a C++0x static_assert.
994e5dd7070Spatrick   // 7. it's a block literal declaration
995a9ac8606Spatrick   // 8. it's a temporary with lifetime extended due to being default value.
996a9ac8606Spatrick   if (isa<TranslationUnitDecl>(this) || isa<TemplateTypeParmDecl>(this) ||
997a9ac8606Spatrick       isa<NonTypeTemplateParmDecl>(this) || !getDeclContext() ||
998a9ac8606Spatrick       !isa<CXXRecordDecl>(getDeclContext()) || isInvalidDecl() ||
999a9ac8606Spatrick       isa<StaticAssertDecl>(this) || isa<BlockDecl>(this) ||
1000e5dd7070Spatrick       // FIXME: a ParmVarDecl can have ClassTemplateSpecialization
1001e5dd7070Spatrick       // as DeclContext (?).
1002e5dd7070Spatrick       isa<ParmVarDecl>(this) ||
1003e5dd7070Spatrick       // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have
1004e5dd7070Spatrick       // AS_none as access specifier.
1005e5dd7070Spatrick       isa<CXXRecordDecl>(this) ||
1006a9ac8606Spatrick       isa<ClassScopeFunctionSpecializationDecl>(this) ||
1007a9ac8606Spatrick       isa<LifetimeExtendedTemporaryDecl>(this))
1008e5dd7070Spatrick     return true;
1009e5dd7070Spatrick 
1010e5dd7070Spatrick   assert(Access != AS_none &&
1011e5dd7070Spatrick          "Access specifier is AS_none inside a record decl");
1012e5dd7070Spatrick #endif
1013e5dd7070Spatrick   return true;
1014e5dd7070Spatrick }
1015e5dd7070Spatrick 
isInExportDeclContext() const1016*12c85518Srobert bool Decl::isInExportDeclContext() const {
1017*12c85518Srobert   const DeclContext *DC = getLexicalDeclContext();
1018*12c85518Srobert 
1019*12c85518Srobert   while (DC && !isa<ExportDecl>(DC))
1020*12c85518Srobert     DC = DC->getLexicalParent();
1021*12c85518Srobert 
1022*12c85518Srobert   return DC && isa<ExportDecl>(DC);
1023*12c85518Srobert }
1024*12c85518Srobert 
getKind(const Decl * D)1025e5dd7070Spatrick static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
getKind(const DeclContext * DC)1026e5dd7070Spatrick static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
1027e5dd7070Spatrick 
getID() const1028e5dd7070Spatrick int64_t Decl::getID() const {
1029e5dd7070Spatrick   return getASTContext().getAllocator().identifyKnownAlignedObject<Decl>(this);
1030e5dd7070Spatrick }
1031e5dd7070Spatrick 
getFunctionType(bool BlocksToo) const1032e5dd7070Spatrick const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
1033e5dd7070Spatrick   QualType Ty;
1034e5dd7070Spatrick   if (const auto *D = dyn_cast<ValueDecl>(this))
1035e5dd7070Spatrick     Ty = D->getType();
1036e5dd7070Spatrick   else if (const auto *D = dyn_cast<TypedefNameDecl>(this))
1037e5dd7070Spatrick     Ty = D->getUnderlyingType();
1038e5dd7070Spatrick   else
1039e5dd7070Spatrick     return nullptr;
1040e5dd7070Spatrick 
1041e5dd7070Spatrick   if (Ty->isFunctionPointerType())
1042e5dd7070Spatrick     Ty = Ty->castAs<PointerType>()->getPointeeType();
1043e5dd7070Spatrick   else if (Ty->isFunctionReferenceType())
1044e5dd7070Spatrick     Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1045e5dd7070Spatrick   else if (BlocksToo && Ty->isBlockPointerType())
1046e5dd7070Spatrick     Ty = Ty->castAs<BlockPointerType>()->getPointeeType();
1047e5dd7070Spatrick 
1048e5dd7070Spatrick   return Ty->getAs<FunctionType>();
1049e5dd7070Spatrick }
1050e5dd7070Spatrick 
getNonTransparentDeclContext()1051*12c85518Srobert DeclContext *Decl::getNonTransparentDeclContext() {
1052*12c85518Srobert   assert(getDeclContext());
1053*12c85518Srobert   return getDeclContext()->getNonTransparentContext();
1054*12c85518Srobert }
1055*12c85518Srobert 
1056e5dd7070Spatrick /// Starting at a given context (a Decl or DeclContext), look for a
1057e5dd7070Spatrick /// code context that is not a closure (a lambda, block, etc.).
getNonClosureContext(T * D)1058e5dd7070Spatrick template <class T> static Decl *getNonClosureContext(T *D) {
1059e5dd7070Spatrick   if (getKind(D) == Decl::CXXMethod) {
1060e5dd7070Spatrick     auto *MD = cast<CXXMethodDecl>(D);
1061e5dd7070Spatrick     if (MD->getOverloadedOperator() == OO_Call &&
1062e5dd7070Spatrick         MD->getParent()->isLambda())
1063e5dd7070Spatrick       return getNonClosureContext(MD->getParent()->getParent());
1064e5dd7070Spatrick     return MD;
1065a9ac8606Spatrick   }
1066a9ac8606Spatrick   if (auto *FD = dyn_cast<FunctionDecl>(D))
1067e5dd7070Spatrick     return FD;
1068a9ac8606Spatrick   if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
1069e5dd7070Spatrick     return MD;
1070a9ac8606Spatrick   if (auto *BD = dyn_cast<BlockDecl>(D))
1071e5dd7070Spatrick     return getNonClosureContext(BD->getParent());
1072a9ac8606Spatrick   if (auto *CD = dyn_cast<CapturedDecl>(D))
1073e5dd7070Spatrick     return getNonClosureContext(CD->getParent());
1074e5dd7070Spatrick   return nullptr;
1075e5dd7070Spatrick }
1076e5dd7070Spatrick 
getNonClosureContext()1077e5dd7070Spatrick Decl *Decl::getNonClosureContext() {
1078e5dd7070Spatrick   return ::getNonClosureContext(this);
1079e5dd7070Spatrick }
1080e5dd7070Spatrick 
getNonClosureAncestor()1081e5dd7070Spatrick Decl *DeclContext::getNonClosureAncestor() {
1082e5dd7070Spatrick   return ::getNonClosureContext(this);
1083e5dd7070Spatrick }
1084e5dd7070Spatrick 
1085e5dd7070Spatrick //===----------------------------------------------------------------------===//
1086e5dd7070Spatrick // DeclContext Implementation
1087e5dd7070Spatrick //===----------------------------------------------------------------------===//
1088e5dd7070Spatrick 
DeclContext(Decl::Kind K)1089e5dd7070Spatrick DeclContext::DeclContext(Decl::Kind K) {
1090e5dd7070Spatrick   DeclContextBits.DeclKind = K;
1091e5dd7070Spatrick   setHasExternalLexicalStorage(false);
1092e5dd7070Spatrick   setHasExternalVisibleStorage(false);
1093e5dd7070Spatrick   setNeedToReconcileExternalVisibleStorage(false);
1094e5dd7070Spatrick   setHasLazyLocalLexicalLookups(false);
1095e5dd7070Spatrick   setHasLazyExternalLexicalLookups(false);
1096e5dd7070Spatrick   setUseQualifiedLookup(false);
1097e5dd7070Spatrick }
1098e5dd7070Spatrick 
classof(const Decl * D)1099e5dd7070Spatrick bool DeclContext::classof(const Decl *D) {
1100e5dd7070Spatrick   switch (D->getKind()) {
1101e5dd7070Spatrick #define DECL(NAME, BASE)
1102e5dd7070Spatrick #define DECL_CONTEXT(NAME) case Decl::NAME:
1103e5dd7070Spatrick #define DECL_CONTEXT_BASE(NAME)
1104e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
1105e5dd7070Spatrick       return true;
1106e5dd7070Spatrick     default:
1107e5dd7070Spatrick #define DECL(NAME, BASE)
1108e5dd7070Spatrick #define DECL_CONTEXT_BASE(NAME)                 \
1109e5dd7070Spatrick       if (D->getKind() >= Decl::first##NAME &&  \
1110e5dd7070Spatrick           D->getKind() <= Decl::last##NAME)     \
1111e5dd7070Spatrick         return true;
1112e5dd7070Spatrick #include "clang/AST/DeclNodes.inc"
1113e5dd7070Spatrick       return false;
1114e5dd7070Spatrick   }
1115e5dd7070Spatrick }
1116e5dd7070Spatrick 
1117e5dd7070Spatrick DeclContext::~DeclContext() = default;
1118e5dd7070Spatrick 
1119e5dd7070Spatrick /// Find the parent context of this context that will be
1120e5dd7070Spatrick /// used for unqualified name lookup.
1121e5dd7070Spatrick ///
1122e5dd7070Spatrick /// Generally, the parent lookup context is the semantic context. However, for
1123e5dd7070Spatrick /// a friend function the parent lookup context is the lexical context, which
1124e5dd7070Spatrick /// is the class in which the friend is declared.
getLookupParent()1125e5dd7070Spatrick DeclContext *DeclContext::getLookupParent() {
1126e5dd7070Spatrick   // FIXME: Find a better way to identify friends.
1127e5dd7070Spatrick   if (isa<FunctionDecl>(this))
1128e5dd7070Spatrick     if (getParent()->getRedeclContext()->isFileContext() &&
1129e5dd7070Spatrick         getLexicalParent()->getRedeclContext()->isRecord())
1130e5dd7070Spatrick       return getLexicalParent();
1131e5dd7070Spatrick 
1132e5dd7070Spatrick   // A lookup within the call operator of a lambda never looks in the lambda
1133e5dd7070Spatrick   // class; instead, skip to the context in which that closure type is
1134e5dd7070Spatrick   // declared.
1135e5dd7070Spatrick   if (isLambdaCallOperator(this))
1136e5dd7070Spatrick     return getParent()->getParent();
1137e5dd7070Spatrick 
1138e5dd7070Spatrick   return getParent();
1139e5dd7070Spatrick }
1140e5dd7070Spatrick 
getInnermostBlockDecl() const1141e5dd7070Spatrick const BlockDecl *DeclContext::getInnermostBlockDecl() const {
1142e5dd7070Spatrick   const DeclContext *Ctx = this;
1143e5dd7070Spatrick 
1144e5dd7070Spatrick   do {
1145e5dd7070Spatrick     if (Ctx->isClosure())
1146e5dd7070Spatrick       return cast<BlockDecl>(Ctx);
1147e5dd7070Spatrick     Ctx = Ctx->getParent();
1148e5dd7070Spatrick   } while (Ctx);
1149e5dd7070Spatrick 
1150e5dd7070Spatrick   return nullptr;
1151e5dd7070Spatrick }
1152e5dd7070Spatrick 
isInlineNamespace() const1153e5dd7070Spatrick bool DeclContext::isInlineNamespace() const {
1154e5dd7070Spatrick   return isNamespace() &&
1155e5dd7070Spatrick          cast<NamespaceDecl>(this)->isInline();
1156e5dd7070Spatrick }
1157e5dd7070Spatrick 
isStdNamespace() const1158e5dd7070Spatrick bool DeclContext::isStdNamespace() const {
1159e5dd7070Spatrick   if (!isNamespace())
1160e5dd7070Spatrick     return false;
1161e5dd7070Spatrick 
1162e5dd7070Spatrick   const auto *ND = cast<NamespaceDecl>(this);
1163e5dd7070Spatrick   if (ND->isInline()) {
1164e5dd7070Spatrick     return ND->getParent()->isStdNamespace();
1165e5dd7070Spatrick   }
1166e5dd7070Spatrick 
1167e5dd7070Spatrick   if (!getParent()->getRedeclContext()->isTranslationUnit())
1168e5dd7070Spatrick     return false;
1169e5dd7070Spatrick 
1170e5dd7070Spatrick   const IdentifierInfo *II = ND->getIdentifier();
1171e5dd7070Spatrick   return II && II->isStr("std");
1172e5dd7070Spatrick }
1173e5dd7070Spatrick 
isDependentContext() const1174e5dd7070Spatrick bool DeclContext::isDependentContext() const {
1175e5dd7070Spatrick   if (isFileContext())
1176e5dd7070Spatrick     return false;
1177e5dd7070Spatrick 
1178e5dd7070Spatrick   if (isa<ClassTemplatePartialSpecializationDecl>(this))
1179e5dd7070Spatrick     return true;
1180e5dd7070Spatrick 
1181e5dd7070Spatrick   if (const auto *Record = dyn_cast<CXXRecordDecl>(this)) {
1182e5dd7070Spatrick     if (Record->getDescribedClassTemplate())
1183e5dd7070Spatrick       return true;
1184e5dd7070Spatrick 
1185e5dd7070Spatrick     if (Record->isDependentLambda())
1186e5dd7070Spatrick       return true;
1187*12c85518Srobert     if (Record->isNeverDependentLambda())
1188*12c85518Srobert       return false;
1189e5dd7070Spatrick   }
1190e5dd7070Spatrick 
1191e5dd7070Spatrick   if (const auto *Function = dyn_cast<FunctionDecl>(this)) {
1192e5dd7070Spatrick     if (Function->getDescribedFunctionTemplate())
1193e5dd7070Spatrick       return true;
1194e5dd7070Spatrick 
1195e5dd7070Spatrick     // Friend function declarations are dependent if their *lexical*
1196e5dd7070Spatrick     // context is dependent.
1197e5dd7070Spatrick     if (cast<Decl>(this)->getFriendObjectKind())
1198e5dd7070Spatrick       return getLexicalParent()->isDependentContext();
1199e5dd7070Spatrick   }
1200e5dd7070Spatrick 
1201e5dd7070Spatrick   // FIXME: A variable template is a dependent context, but is not a
1202e5dd7070Spatrick   // DeclContext. A context within it (such as a lambda-expression)
1203e5dd7070Spatrick   // should be considered dependent.
1204e5dd7070Spatrick 
1205e5dd7070Spatrick   return getParent() && getParent()->isDependentContext();
1206e5dd7070Spatrick }
1207e5dd7070Spatrick 
isTransparentContext() const1208e5dd7070Spatrick bool DeclContext::isTransparentContext() const {
1209e5dd7070Spatrick   if (getDeclKind() == Decl::Enum)
1210e5dd7070Spatrick     return !cast<EnumDecl>(this)->isScoped();
1211e5dd7070Spatrick 
1212*12c85518Srobert   return isa<LinkageSpecDecl, ExportDecl, HLSLBufferDecl>(this);
1213e5dd7070Spatrick }
1214e5dd7070Spatrick 
isLinkageSpecContext(const DeclContext * DC,LinkageSpecDecl::LanguageIDs ID)1215e5dd7070Spatrick static bool isLinkageSpecContext(const DeclContext *DC,
1216e5dd7070Spatrick                                  LinkageSpecDecl::LanguageIDs ID) {
1217e5dd7070Spatrick   while (DC->getDeclKind() != Decl::TranslationUnit) {
1218e5dd7070Spatrick     if (DC->getDeclKind() == Decl::LinkageSpec)
1219e5dd7070Spatrick       return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
1220e5dd7070Spatrick     DC = DC->getLexicalParent();
1221e5dd7070Spatrick   }
1222e5dd7070Spatrick   return false;
1223e5dd7070Spatrick }
1224e5dd7070Spatrick 
isExternCContext() const1225e5dd7070Spatrick bool DeclContext::isExternCContext() const {
1226e5dd7070Spatrick   return isLinkageSpecContext(this, LinkageSpecDecl::lang_c);
1227e5dd7070Spatrick }
1228e5dd7070Spatrick 
getExternCContext() const1229e5dd7070Spatrick const LinkageSpecDecl *DeclContext::getExternCContext() const {
1230e5dd7070Spatrick   const DeclContext *DC = this;
1231e5dd7070Spatrick   while (DC->getDeclKind() != Decl::TranslationUnit) {
1232e5dd7070Spatrick     if (DC->getDeclKind() == Decl::LinkageSpec &&
1233e5dd7070Spatrick         cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecDecl::lang_c)
1234e5dd7070Spatrick       return cast<LinkageSpecDecl>(DC);
1235e5dd7070Spatrick     DC = DC->getLexicalParent();
1236e5dd7070Spatrick   }
1237e5dd7070Spatrick   return nullptr;
1238e5dd7070Spatrick }
1239e5dd7070Spatrick 
isExternCXXContext() const1240e5dd7070Spatrick bool DeclContext::isExternCXXContext() const {
1241e5dd7070Spatrick   return isLinkageSpecContext(this, LinkageSpecDecl::lang_cxx);
1242e5dd7070Spatrick }
1243e5dd7070Spatrick 
Encloses(const DeclContext * DC) const1244e5dd7070Spatrick bool DeclContext::Encloses(const DeclContext *DC) const {
1245e5dd7070Spatrick   if (getPrimaryContext() != this)
1246e5dd7070Spatrick     return getPrimaryContext()->Encloses(DC);
1247e5dd7070Spatrick 
1248e5dd7070Spatrick   for (; DC; DC = DC->getParent())
1249*12c85518Srobert     if (!isa<LinkageSpecDecl>(DC) && !isa<ExportDecl>(DC) &&
1250*12c85518Srobert         DC->getPrimaryContext() == this)
1251e5dd7070Spatrick       return true;
1252e5dd7070Spatrick   return false;
1253e5dd7070Spatrick }
1254e5dd7070Spatrick 
getNonTransparentContext()1255*12c85518Srobert DeclContext *DeclContext::getNonTransparentContext() {
1256*12c85518Srobert   DeclContext *DC = this;
1257*12c85518Srobert   while (DC->isTransparentContext()) {
1258*12c85518Srobert     DC = DC->getParent();
1259*12c85518Srobert     assert(DC && "All transparent contexts should have a parent!");
1260*12c85518Srobert   }
1261*12c85518Srobert   return DC;
1262*12c85518Srobert }
1263*12c85518Srobert 
getPrimaryContext()1264e5dd7070Spatrick DeclContext *DeclContext::getPrimaryContext() {
1265e5dd7070Spatrick   switch (getDeclKind()) {
1266e5dd7070Spatrick   case Decl::ExternCContext:
1267e5dd7070Spatrick   case Decl::LinkageSpec:
1268e5dd7070Spatrick   case Decl::Export:
1269e5dd7070Spatrick   case Decl::Block:
1270e5dd7070Spatrick   case Decl::Captured:
1271e5dd7070Spatrick   case Decl::OMPDeclareReduction:
1272e5dd7070Spatrick   case Decl::OMPDeclareMapper:
1273e5dd7070Spatrick   case Decl::RequiresExprBody:
1274e5dd7070Spatrick     // There is only one DeclContext for these entities.
1275e5dd7070Spatrick     return this;
1276e5dd7070Spatrick 
1277*12c85518Srobert   case Decl::HLSLBuffer:
1278*12c85518Srobert     // Each buffer, even with the same name, is a distinct construct.
1279*12c85518Srobert     // Multiple buffers with the same name are allowed for backward
1280*12c85518Srobert     // compatibility.
1281*12c85518Srobert     // As long as buffers have unique resource bindings the names don't matter.
1282*12c85518Srobert     // The names get exposed via the CPU-side reflection API which
1283*12c85518Srobert     // supports querying bindings, so we cannot remove them.
1284*12c85518Srobert     return this;
1285*12c85518Srobert 
1286a9ac8606Spatrick   case Decl::TranslationUnit:
1287a9ac8606Spatrick     return static_cast<TranslationUnitDecl *>(this)->getFirstDecl();
1288e5dd7070Spatrick   case Decl::Namespace:
1289e5dd7070Spatrick     // The original namespace is our primary context.
1290e5dd7070Spatrick     return static_cast<NamespaceDecl *>(this)->getOriginalNamespace();
1291e5dd7070Spatrick 
1292e5dd7070Spatrick   case Decl::ObjCMethod:
1293e5dd7070Spatrick     return this;
1294e5dd7070Spatrick 
1295e5dd7070Spatrick   case Decl::ObjCInterface:
1296e5dd7070Spatrick     if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))
1297e5dd7070Spatrick       if (auto *Def = OID->getDefinition())
1298e5dd7070Spatrick         return Def;
1299e5dd7070Spatrick     return this;
1300e5dd7070Spatrick 
1301e5dd7070Spatrick   case Decl::ObjCProtocol:
1302e5dd7070Spatrick     if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))
1303e5dd7070Spatrick       if (auto *Def = OPD->getDefinition())
1304e5dd7070Spatrick         return Def;
1305e5dd7070Spatrick     return this;
1306e5dd7070Spatrick 
1307e5dd7070Spatrick   case Decl::ObjCCategory:
1308e5dd7070Spatrick     return this;
1309e5dd7070Spatrick 
1310e5dd7070Spatrick   case Decl::ObjCImplementation:
1311e5dd7070Spatrick   case Decl::ObjCCategoryImpl:
1312e5dd7070Spatrick     return this;
1313e5dd7070Spatrick 
1314e5dd7070Spatrick   default:
1315e5dd7070Spatrick     if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
1316e5dd7070Spatrick       // If this is a tag type that has a definition or is currently
1317e5dd7070Spatrick       // being defined, that definition is our primary context.
1318e5dd7070Spatrick       auto *Tag = cast<TagDecl>(this);
1319e5dd7070Spatrick 
1320e5dd7070Spatrick       if (TagDecl *Def = Tag->getDefinition())
1321e5dd7070Spatrick         return Def;
1322e5dd7070Spatrick 
1323e5dd7070Spatrick       if (const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
1324e5dd7070Spatrick         // Note, TagType::getDecl returns the (partial) definition one exists.
1325e5dd7070Spatrick         TagDecl *PossiblePartialDef = TagTy->getDecl();
1326e5dd7070Spatrick         if (PossiblePartialDef->isBeingDefined())
1327e5dd7070Spatrick           return PossiblePartialDef;
1328e5dd7070Spatrick       } else {
1329e5dd7070Spatrick         assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1330e5dd7070Spatrick       }
1331e5dd7070Spatrick 
1332e5dd7070Spatrick       return Tag;
1333e5dd7070Spatrick     }
1334e5dd7070Spatrick 
1335e5dd7070Spatrick     assert(getDeclKind() >= Decl::firstFunction &&
1336e5dd7070Spatrick            getDeclKind() <= Decl::lastFunction &&
1337e5dd7070Spatrick           "Unknown DeclContext kind");
1338e5dd7070Spatrick     return this;
1339e5dd7070Spatrick   }
1340e5dd7070Spatrick }
1341e5dd7070Spatrick 
1342a9ac8606Spatrick template <typename T>
collectAllContextsImpl(T * Self,SmallVectorImpl<DeclContext * > & Contexts)1343a9ac8606Spatrick void collectAllContextsImpl(T *Self, SmallVectorImpl<DeclContext *> &Contexts) {
1344a9ac8606Spatrick   for (T *D = Self->getMostRecentDecl(); D; D = D->getPreviousDecl())
1345a9ac8606Spatrick     Contexts.push_back(D);
1346e5dd7070Spatrick 
1347e5dd7070Spatrick   std::reverse(Contexts.begin(), Contexts.end());
1348e5dd7070Spatrick }
1349e5dd7070Spatrick 
collectAllContexts(SmallVectorImpl<DeclContext * > & Contexts)1350a9ac8606Spatrick void DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts) {
1351a9ac8606Spatrick   Contexts.clear();
1352a9ac8606Spatrick 
1353a9ac8606Spatrick   Decl::Kind Kind = getDeclKind();
1354a9ac8606Spatrick 
1355a9ac8606Spatrick   if (Kind == Decl::TranslationUnit)
1356a9ac8606Spatrick     collectAllContextsImpl(static_cast<TranslationUnitDecl *>(this), Contexts);
1357a9ac8606Spatrick   else if (Kind == Decl::Namespace)
1358a9ac8606Spatrick     collectAllContextsImpl(static_cast<NamespaceDecl *>(this), Contexts);
1359a9ac8606Spatrick   else
1360a9ac8606Spatrick     Contexts.push_back(this);
1361a9ac8606Spatrick }
1362a9ac8606Spatrick 
1363e5dd7070Spatrick std::pair<Decl *, Decl *>
BuildDeclChain(ArrayRef<Decl * > Decls,bool FieldsAlreadyLoaded)1364e5dd7070Spatrick DeclContext::BuildDeclChain(ArrayRef<Decl *> Decls,
1365e5dd7070Spatrick                             bool FieldsAlreadyLoaded) {
1366e5dd7070Spatrick   // Build up a chain of declarations via the Decl::NextInContextAndBits field.
1367e5dd7070Spatrick   Decl *FirstNewDecl = nullptr;
1368e5dd7070Spatrick   Decl *PrevDecl = nullptr;
1369e5dd7070Spatrick   for (auto *D : Decls) {
1370e5dd7070Spatrick     if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1371e5dd7070Spatrick       continue;
1372e5dd7070Spatrick 
1373e5dd7070Spatrick     if (PrevDecl)
1374e5dd7070Spatrick       PrevDecl->NextInContextAndBits.setPointer(D);
1375e5dd7070Spatrick     else
1376e5dd7070Spatrick       FirstNewDecl = D;
1377e5dd7070Spatrick 
1378e5dd7070Spatrick     PrevDecl = D;
1379e5dd7070Spatrick   }
1380e5dd7070Spatrick 
1381e5dd7070Spatrick   return std::make_pair(FirstNewDecl, PrevDecl);
1382e5dd7070Spatrick }
1383e5dd7070Spatrick 
1384e5dd7070Spatrick /// We have just acquired external visible storage, and we already have
1385e5dd7070Spatrick /// built a lookup map. For every name in the map, pull in the new names from
1386e5dd7070Spatrick /// the external storage.
reconcileExternalVisibleStorage() const1387e5dd7070Spatrick void DeclContext::reconcileExternalVisibleStorage() const {
1388e5dd7070Spatrick   assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1389e5dd7070Spatrick   setNeedToReconcileExternalVisibleStorage(false);
1390e5dd7070Spatrick 
1391e5dd7070Spatrick   for (auto &Lookup : *LookupPtr)
1392e5dd7070Spatrick     Lookup.second.setHasExternalDecls();
1393e5dd7070Spatrick }
1394e5dd7070Spatrick 
1395e5dd7070Spatrick /// Load the declarations within this lexical storage from an
1396e5dd7070Spatrick /// external source.
1397e5dd7070Spatrick /// \return \c true if any declarations were added.
1398e5dd7070Spatrick bool
LoadLexicalDeclsFromExternalStorage() const1399e5dd7070Spatrick DeclContext::LoadLexicalDeclsFromExternalStorage() const {
1400e5dd7070Spatrick   ExternalASTSource *Source = getParentASTContext().getExternalSource();
1401e5dd7070Spatrick   assert(hasExternalLexicalStorage() && Source && "No external storage?");
1402e5dd7070Spatrick 
1403e5dd7070Spatrick   // Notify that we have a DeclContext that is initializing.
1404e5dd7070Spatrick   ExternalASTSource::Deserializing ADeclContext(Source);
1405e5dd7070Spatrick 
1406e5dd7070Spatrick   // Load the external declarations, if any.
1407e5dd7070Spatrick   SmallVector<Decl*, 64> Decls;
1408e5dd7070Spatrick   setHasExternalLexicalStorage(false);
1409e5dd7070Spatrick   Source->FindExternalLexicalDecls(this, Decls);
1410e5dd7070Spatrick 
1411e5dd7070Spatrick   if (Decls.empty())
1412e5dd7070Spatrick     return false;
1413e5dd7070Spatrick 
1414e5dd7070Spatrick   // We may have already loaded just the fields of this record, in which case
1415e5dd7070Spatrick   // we need to ignore them.
1416e5dd7070Spatrick   bool FieldsAlreadyLoaded = false;
1417e5dd7070Spatrick   if (const auto *RD = dyn_cast<RecordDecl>(this))
1418e5dd7070Spatrick     FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1419e5dd7070Spatrick 
1420e5dd7070Spatrick   // Splice the newly-read declarations into the beginning of the list
1421e5dd7070Spatrick   // of declarations.
1422e5dd7070Spatrick   Decl *ExternalFirst, *ExternalLast;
1423e5dd7070Spatrick   std::tie(ExternalFirst, ExternalLast) =
1424e5dd7070Spatrick       BuildDeclChain(Decls, FieldsAlreadyLoaded);
1425e5dd7070Spatrick   ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
1426e5dd7070Spatrick   FirstDecl = ExternalFirst;
1427e5dd7070Spatrick   if (!LastDecl)
1428e5dd7070Spatrick     LastDecl = ExternalLast;
1429e5dd7070Spatrick   return true;
1430e5dd7070Spatrick }
1431e5dd7070Spatrick 
1432e5dd7070Spatrick DeclContext::lookup_result
SetNoExternalVisibleDeclsForName(const DeclContext * DC,DeclarationName Name)1433e5dd7070Spatrick ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
1434e5dd7070Spatrick                                                     DeclarationName Name) {
1435e5dd7070Spatrick   ASTContext &Context = DC->getParentASTContext();
1436e5dd7070Spatrick   StoredDeclsMap *Map;
1437e5dd7070Spatrick   if (!(Map = DC->LookupPtr))
1438e5dd7070Spatrick     Map = DC->CreateStoredDeclsMap(Context);
1439e5dd7070Spatrick   if (DC->hasNeedToReconcileExternalVisibleStorage())
1440e5dd7070Spatrick     DC->reconcileExternalVisibleStorage();
1441e5dd7070Spatrick 
1442e5dd7070Spatrick   (*Map)[Name].removeExternalDecls();
1443e5dd7070Spatrick 
1444e5dd7070Spatrick   return DeclContext::lookup_result();
1445e5dd7070Spatrick }
1446e5dd7070Spatrick 
1447e5dd7070Spatrick DeclContext::lookup_result
SetExternalVisibleDeclsForName(const DeclContext * DC,DeclarationName Name,ArrayRef<NamedDecl * > Decls)1448e5dd7070Spatrick ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
1449e5dd7070Spatrick                                                   DeclarationName Name,
1450e5dd7070Spatrick                                                   ArrayRef<NamedDecl*> Decls) {
1451e5dd7070Spatrick   ASTContext &Context = DC->getParentASTContext();
1452e5dd7070Spatrick   StoredDeclsMap *Map;
1453e5dd7070Spatrick   if (!(Map = DC->LookupPtr))
1454e5dd7070Spatrick     Map = DC->CreateStoredDeclsMap(Context);
1455e5dd7070Spatrick   if (DC->hasNeedToReconcileExternalVisibleStorage())
1456e5dd7070Spatrick     DC->reconcileExternalVisibleStorage();
1457e5dd7070Spatrick 
1458e5dd7070Spatrick   StoredDeclsList &List = (*Map)[Name];
1459a9ac8606Spatrick   List.replaceExternalDecls(Decls);
1460e5dd7070Spatrick   return List.getLookupResult();
1461e5dd7070Spatrick }
1462e5dd7070Spatrick 
decls_begin() const1463e5dd7070Spatrick DeclContext::decl_iterator DeclContext::decls_begin() const {
1464e5dd7070Spatrick   if (hasExternalLexicalStorage())
1465e5dd7070Spatrick     LoadLexicalDeclsFromExternalStorage();
1466e5dd7070Spatrick   return decl_iterator(FirstDecl);
1467e5dd7070Spatrick }
1468e5dd7070Spatrick 
decls_empty() const1469e5dd7070Spatrick bool DeclContext::decls_empty() const {
1470e5dd7070Spatrick   if (hasExternalLexicalStorage())
1471e5dd7070Spatrick     LoadLexicalDeclsFromExternalStorage();
1472e5dd7070Spatrick 
1473e5dd7070Spatrick   return !FirstDecl;
1474e5dd7070Spatrick }
1475e5dd7070Spatrick 
containsDecl(Decl * D) const1476e5dd7070Spatrick bool DeclContext::containsDecl(Decl *D) const {
1477e5dd7070Spatrick   return (D->getLexicalDeclContext() == this &&
1478e5dd7070Spatrick           (D->NextInContextAndBits.getPointer() || D == LastDecl));
1479e5dd7070Spatrick }
1480e5dd7070Spatrick 
containsDeclAndLoad(Decl * D) const1481e5dd7070Spatrick bool DeclContext::containsDeclAndLoad(Decl *D) const {
1482e5dd7070Spatrick   if (hasExternalLexicalStorage())
1483e5dd7070Spatrick     LoadLexicalDeclsFromExternalStorage();
1484e5dd7070Spatrick   return containsDecl(D);
1485e5dd7070Spatrick }
1486e5dd7070Spatrick 
1487e5dd7070Spatrick /// shouldBeHidden - Determine whether a declaration which was declared
1488e5dd7070Spatrick /// within its semantic context should be invisible to qualified name lookup.
shouldBeHidden(NamedDecl * D)1489e5dd7070Spatrick static bool shouldBeHidden(NamedDecl *D) {
1490e5dd7070Spatrick   // Skip unnamed declarations.
1491e5dd7070Spatrick   if (!D->getDeclName())
1492e5dd7070Spatrick     return true;
1493e5dd7070Spatrick 
1494e5dd7070Spatrick   // Skip entities that can't be found by name lookup into a particular
1495e5dd7070Spatrick   // context.
1496e5dd7070Spatrick   if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
1497e5dd7070Spatrick       D->isTemplateParameter())
1498e5dd7070Spatrick     return true;
1499e5dd7070Spatrick 
1500e5dd7070Spatrick   // Skip friends and local extern declarations unless they're the first
1501e5dd7070Spatrick   // declaration of the entity.
1502e5dd7070Spatrick   if ((D->isLocalExternDecl() || D->getFriendObjectKind()) &&
1503e5dd7070Spatrick       D != D->getCanonicalDecl())
1504e5dd7070Spatrick     return true;
1505e5dd7070Spatrick 
1506e5dd7070Spatrick   // Skip template specializations.
1507e5dd7070Spatrick   // FIXME: This feels like a hack. Should DeclarationName support
1508e5dd7070Spatrick   // template-ids, or is there a better way to keep specializations
1509e5dd7070Spatrick   // from being visible?
1510e5dd7070Spatrick   if (isa<ClassTemplateSpecializationDecl>(D))
1511e5dd7070Spatrick     return true;
1512e5dd7070Spatrick   if (auto *FD = dyn_cast<FunctionDecl>(D))
1513e5dd7070Spatrick     if (FD->isFunctionTemplateSpecialization())
1514e5dd7070Spatrick       return true;
1515e5dd7070Spatrick 
1516ec727ea7Spatrick   // Hide destructors that are invalid. There should always be one destructor,
1517ec727ea7Spatrick   // but if it is an invalid decl, another one is created. We need to hide the
1518ec727ea7Spatrick   // invalid one from places that expect exactly one destructor, like the
1519ec727ea7Spatrick   // serialization code.
1520ec727ea7Spatrick   if (isa<CXXDestructorDecl>(D) && D->isInvalidDecl())
1521ec727ea7Spatrick     return true;
1522ec727ea7Spatrick 
1523e5dd7070Spatrick   return false;
1524e5dd7070Spatrick }
1525e5dd7070Spatrick 
removeDecl(Decl * D)1526e5dd7070Spatrick void DeclContext::removeDecl(Decl *D) {
1527e5dd7070Spatrick   assert(D->getLexicalDeclContext() == this &&
1528e5dd7070Spatrick          "decl being removed from non-lexical context");
1529e5dd7070Spatrick   assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
1530e5dd7070Spatrick          "decl is not in decls list");
1531e5dd7070Spatrick 
1532e5dd7070Spatrick   // Remove D from the decl chain.  This is O(n) but hopefully rare.
1533e5dd7070Spatrick   if (D == FirstDecl) {
1534e5dd7070Spatrick     if (D == LastDecl)
1535e5dd7070Spatrick       FirstDecl = LastDecl = nullptr;
1536e5dd7070Spatrick     else
1537e5dd7070Spatrick       FirstDecl = D->NextInContextAndBits.getPointer();
1538e5dd7070Spatrick   } else {
1539e5dd7070Spatrick     for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {
1540e5dd7070Spatrick       assert(I && "decl not found in linked list");
1541e5dd7070Spatrick       if (I->NextInContextAndBits.getPointer() == D) {
1542e5dd7070Spatrick         I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
1543e5dd7070Spatrick         if (D == LastDecl) LastDecl = I;
1544e5dd7070Spatrick         break;
1545e5dd7070Spatrick       }
1546e5dd7070Spatrick     }
1547e5dd7070Spatrick   }
1548e5dd7070Spatrick 
1549e5dd7070Spatrick   // Mark that D is no longer in the decl chain.
1550e5dd7070Spatrick   D->NextInContextAndBits.setPointer(nullptr);
1551e5dd7070Spatrick 
1552e5dd7070Spatrick   // Remove D from the lookup table if necessary.
1553e5dd7070Spatrick   if (isa<NamedDecl>(D)) {
1554e5dd7070Spatrick     auto *ND = cast<NamedDecl>(D);
1555e5dd7070Spatrick 
1556e5dd7070Spatrick     // Do not try to remove the declaration if that is invisible to qualified
1557e5dd7070Spatrick     // lookup.  E.g. template specializations are skipped.
1558e5dd7070Spatrick     if (shouldBeHidden(ND))
1559e5dd7070Spatrick       return;
1560e5dd7070Spatrick 
1561e5dd7070Spatrick     // Remove only decls that have a name
1562e5dd7070Spatrick     if (!ND->getDeclName())
1563e5dd7070Spatrick       return;
1564e5dd7070Spatrick 
1565e5dd7070Spatrick     auto *DC = D->getDeclContext();
1566e5dd7070Spatrick     do {
1567e5dd7070Spatrick       StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr;
1568e5dd7070Spatrick       if (Map) {
1569e5dd7070Spatrick         StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1570e5dd7070Spatrick         assert(Pos != Map->end() && "no lookup entry for decl");
1571*12c85518Srobert         StoredDeclsList &List = Pos->second;
1572*12c85518Srobert         List.remove(ND);
1573*12c85518Srobert         // Clean up the entry if there are no more decls.
1574*12c85518Srobert         if (List.isNull())
1575*12c85518Srobert           Map->erase(Pos);
1576e5dd7070Spatrick       }
1577e5dd7070Spatrick     } while (DC->isTransparentContext() && (DC = DC->getParent()));
1578e5dd7070Spatrick   }
1579e5dd7070Spatrick }
1580e5dd7070Spatrick 
addHiddenDecl(Decl * D)1581e5dd7070Spatrick void DeclContext::addHiddenDecl(Decl *D) {
1582e5dd7070Spatrick   assert(D->getLexicalDeclContext() == this &&
1583e5dd7070Spatrick          "Decl inserted into wrong lexical context");
1584e5dd7070Spatrick   assert(!D->getNextDeclInContext() && D != LastDecl &&
1585e5dd7070Spatrick          "Decl already inserted into a DeclContext");
1586e5dd7070Spatrick 
1587e5dd7070Spatrick   if (FirstDecl) {
1588e5dd7070Spatrick     LastDecl->NextInContextAndBits.setPointer(D);
1589e5dd7070Spatrick     LastDecl = D;
1590e5dd7070Spatrick   } else {
1591e5dd7070Spatrick     FirstDecl = LastDecl = D;
1592e5dd7070Spatrick   }
1593e5dd7070Spatrick 
1594e5dd7070Spatrick   // Notify a C++ record declaration that we've added a member, so it can
1595e5dd7070Spatrick   // update its class-specific state.
1596e5dd7070Spatrick   if (auto *Record = dyn_cast<CXXRecordDecl>(this))
1597e5dd7070Spatrick     Record->addedMember(D);
1598e5dd7070Spatrick 
1599e5dd7070Spatrick   // If this is a newly-created (not de-serialized) import declaration, wire
1600e5dd7070Spatrick   // it in to the list of local import declarations.
1601e5dd7070Spatrick   if (!D->isFromASTFile()) {
1602e5dd7070Spatrick     if (auto *Import = dyn_cast<ImportDecl>(D))
1603e5dd7070Spatrick       D->getASTContext().addedLocalImportDecl(Import);
1604e5dd7070Spatrick   }
1605e5dd7070Spatrick }
1606e5dd7070Spatrick 
addDecl(Decl * D)1607e5dd7070Spatrick void DeclContext::addDecl(Decl *D) {
1608e5dd7070Spatrick   addHiddenDecl(D);
1609e5dd7070Spatrick 
1610e5dd7070Spatrick   if (auto *ND = dyn_cast<NamedDecl>(D))
1611e5dd7070Spatrick     ND->getDeclContext()->getPrimaryContext()->
1612e5dd7070Spatrick         makeDeclVisibleInContextWithFlags(ND, false, true);
1613e5dd7070Spatrick }
1614e5dd7070Spatrick 
addDeclInternal(Decl * D)1615e5dd7070Spatrick void DeclContext::addDeclInternal(Decl *D) {
1616e5dd7070Spatrick   addHiddenDecl(D);
1617e5dd7070Spatrick 
1618e5dd7070Spatrick   if (auto *ND = dyn_cast<NamedDecl>(D))
1619e5dd7070Spatrick     ND->getDeclContext()->getPrimaryContext()->
1620e5dd7070Spatrick         makeDeclVisibleInContextWithFlags(ND, true, true);
1621e5dd7070Spatrick }
1622e5dd7070Spatrick 
1623e5dd7070Spatrick /// buildLookup - Build the lookup data structure with all of the
1624e5dd7070Spatrick /// declarations in this DeclContext (and any other contexts linked
1625e5dd7070Spatrick /// to it or transparent contexts nested within it) and return it.
1626e5dd7070Spatrick ///
1627e5dd7070Spatrick /// Note that the produced map may miss out declarations from an
1628e5dd7070Spatrick /// external source. If it does, those entries will be marked with
1629e5dd7070Spatrick /// the 'hasExternalDecls' flag.
buildLookup()1630e5dd7070Spatrick StoredDeclsMap *DeclContext::buildLookup() {
1631e5dd7070Spatrick   assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
1632e5dd7070Spatrick 
1633e5dd7070Spatrick   if (!hasLazyLocalLexicalLookups() &&
1634e5dd7070Spatrick       !hasLazyExternalLexicalLookups())
1635e5dd7070Spatrick     return LookupPtr;
1636e5dd7070Spatrick 
1637e5dd7070Spatrick   SmallVector<DeclContext *, 2> Contexts;
1638e5dd7070Spatrick   collectAllContexts(Contexts);
1639e5dd7070Spatrick 
1640e5dd7070Spatrick   if (hasLazyExternalLexicalLookups()) {
1641e5dd7070Spatrick     setHasLazyExternalLexicalLookups(false);
1642e5dd7070Spatrick     for (auto *DC : Contexts) {
1643e5dd7070Spatrick       if (DC->hasExternalLexicalStorage()) {
1644e5dd7070Spatrick         bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1645e5dd7070Spatrick         setHasLazyLocalLexicalLookups(
1646e5dd7070Spatrick             hasLazyLocalLexicalLookups() | LoadedDecls );
1647e5dd7070Spatrick       }
1648e5dd7070Spatrick     }
1649e5dd7070Spatrick 
1650e5dd7070Spatrick     if (!hasLazyLocalLexicalLookups())
1651e5dd7070Spatrick       return LookupPtr;
1652e5dd7070Spatrick   }
1653e5dd7070Spatrick 
1654e5dd7070Spatrick   for (auto *DC : Contexts)
1655e5dd7070Spatrick     buildLookupImpl(DC, hasExternalVisibleStorage());
1656e5dd7070Spatrick 
1657e5dd7070Spatrick   // We no longer have any lazy decls.
1658e5dd7070Spatrick   setHasLazyLocalLexicalLookups(false);
1659e5dd7070Spatrick   return LookupPtr;
1660e5dd7070Spatrick }
1661e5dd7070Spatrick 
1662e5dd7070Spatrick /// buildLookupImpl - Build part of the lookup data structure for the
1663e5dd7070Spatrick /// declarations contained within DCtx, which will either be this
1664e5dd7070Spatrick /// DeclContext, a DeclContext linked to it, or a transparent context
1665e5dd7070Spatrick /// nested within it.
buildLookupImpl(DeclContext * DCtx,bool Internal)1666e5dd7070Spatrick void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) {
1667e5dd7070Spatrick   for (auto *D : DCtx->noload_decls()) {
1668e5dd7070Spatrick     // Insert this declaration into the lookup structure, but only if
1669e5dd7070Spatrick     // it's semantically within its decl context. Any other decls which
1670e5dd7070Spatrick     // should be found in this context are added eagerly.
1671e5dd7070Spatrick     //
1672e5dd7070Spatrick     // If it's from an AST file, don't add it now. It'll get handled by
1673e5dd7070Spatrick     // FindExternalVisibleDeclsByName if needed. Exception: if we're not
1674e5dd7070Spatrick     // in C++, we do not track external visible decls for the TU, so in
1675e5dd7070Spatrick     // that case we need to collect them all here.
1676e5dd7070Spatrick     if (auto *ND = dyn_cast<NamedDecl>(D))
1677e5dd7070Spatrick       if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&
1678e5dd7070Spatrick           (!ND->isFromASTFile() ||
1679e5dd7070Spatrick            (isTranslationUnit() &&
1680e5dd7070Spatrick             !getParentASTContext().getLangOpts().CPlusPlus)))
1681e5dd7070Spatrick         makeDeclVisibleInContextImpl(ND, Internal);
1682e5dd7070Spatrick 
1683e5dd7070Spatrick     // If this declaration is itself a transparent declaration context
1684e5dd7070Spatrick     // or inline namespace, add the members of this declaration of that
1685e5dd7070Spatrick     // context (recursively).
1686e5dd7070Spatrick     if (auto *InnerCtx = dyn_cast<DeclContext>(D))
1687e5dd7070Spatrick       if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1688e5dd7070Spatrick         buildLookupImpl(InnerCtx, Internal);
1689e5dd7070Spatrick   }
1690e5dd7070Spatrick }
1691e5dd7070Spatrick 
1692e5dd7070Spatrick DeclContext::lookup_result
lookup(DeclarationName Name) const1693e5dd7070Spatrick DeclContext::lookup(DeclarationName Name) const {
1694*12c85518Srobert   // For transparent DeclContext, we should lookup in their enclosing context.
1695*12c85518Srobert   if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
1696*12c85518Srobert     return getParent()->lookup(Name);
1697e5dd7070Spatrick 
1698e5dd7070Spatrick   const DeclContext *PrimaryContext = getPrimaryContext();
1699e5dd7070Spatrick   if (PrimaryContext != this)
1700e5dd7070Spatrick     return PrimaryContext->lookup(Name);
1701e5dd7070Spatrick 
1702e5dd7070Spatrick   // If we have an external source, ensure that any later redeclarations of this
1703e5dd7070Spatrick   // context have been loaded, since they may add names to the result of this
1704e5dd7070Spatrick   // lookup (or add external visible storage).
1705e5dd7070Spatrick   ExternalASTSource *Source = getParentASTContext().getExternalSource();
1706e5dd7070Spatrick   if (Source)
1707e5dd7070Spatrick     (void)cast<Decl>(this)->getMostRecentDecl();
1708e5dd7070Spatrick 
1709e5dd7070Spatrick   if (hasExternalVisibleStorage()) {
1710e5dd7070Spatrick     assert(Source && "external visible storage but no external source?");
1711e5dd7070Spatrick 
1712e5dd7070Spatrick     if (hasNeedToReconcileExternalVisibleStorage())
1713e5dd7070Spatrick       reconcileExternalVisibleStorage();
1714e5dd7070Spatrick 
1715e5dd7070Spatrick     StoredDeclsMap *Map = LookupPtr;
1716e5dd7070Spatrick 
1717e5dd7070Spatrick     if (hasLazyLocalLexicalLookups() ||
1718e5dd7070Spatrick         hasLazyExternalLexicalLookups())
1719e5dd7070Spatrick       // FIXME: Make buildLookup const?
1720e5dd7070Spatrick       Map = const_cast<DeclContext*>(this)->buildLookup();
1721e5dd7070Spatrick 
1722e5dd7070Spatrick     if (!Map)
1723e5dd7070Spatrick       Map = CreateStoredDeclsMap(getParentASTContext());
1724e5dd7070Spatrick 
1725e5dd7070Spatrick     // If we have a lookup result with no external decls, we are done.
1726e5dd7070Spatrick     std::pair<StoredDeclsMap::iterator, bool> R =
1727e5dd7070Spatrick         Map->insert(std::make_pair(Name, StoredDeclsList()));
1728e5dd7070Spatrick     if (!R.second && !R.first->second.hasExternalDecls())
1729e5dd7070Spatrick       return R.first->second.getLookupResult();
1730e5dd7070Spatrick 
1731e5dd7070Spatrick     if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
1732e5dd7070Spatrick       if (StoredDeclsMap *Map = LookupPtr) {
1733e5dd7070Spatrick         StoredDeclsMap::iterator I = Map->find(Name);
1734e5dd7070Spatrick         if (I != Map->end())
1735e5dd7070Spatrick           return I->second.getLookupResult();
1736e5dd7070Spatrick       }
1737e5dd7070Spatrick     }
1738e5dd7070Spatrick 
1739e5dd7070Spatrick     return {};
1740e5dd7070Spatrick   }
1741e5dd7070Spatrick 
1742e5dd7070Spatrick   StoredDeclsMap *Map = LookupPtr;
1743e5dd7070Spatrick   if (hasLazyLocalLexicalLookups() ||
1744e5dd7070Spatrick       hasLazyExternalLexicalLookups())
1745e5dd7070Spatrick     Map = const_cast<DeclContext*>(this)->buildLookup();
1746e5dd7070Spatrick 
1747e5dd7070Spatrick   if (!Map)
1748e5dd7070Spatrick     return {};
1749e5dd7070Spatrick 
1750e5dd7070Spatrick   StoredDeclsMap::iterator I = Map->find(Name);
1751e5dd7070Spatrick   if (I == Map->end())
1752e5dd7070Spatrick     return {};
1753e5dd7070Spatrick 
1754e5dd7070Spatrick   return I->second.getLookupResult();
1755e5dd7070Spatrick }
1756e5dd7070Spatrick 
1757e5dd7070Spatrick DeclContext::lookup_result
noload_lookup(DeclarationName Name)1758e5dd7070Spatrick DeclContext::noload_lookup(DeclarationName Name) {
1759e5dd7070Spatrick   assert(getDeclKind() != Decl::LinkageSpec &&
1760e5dd7070Spatrick          getDeclKind() != Decl::Export &&
1761e5dd7070Spatrick          "should not perform lookups into transparent contexts");
1762e5dd7070Spatrick 
1763e5dd7070Spatrick   DeclContext *PrimaryContext = getPrimaryContext();
1764e5dd7070Spatrick   if (PrimaryContext != this)
1765e5dd7070Spatrick     return PrimaryContext->noload_lookup(Name);
1766e5dd7070Spatrick 
1767e5dd7070Spatrick   loadLazyLocalLexicalLookups();
1768e5dd7070Spatrick   StoredDeclsMap *Map = LookupPtr;
1769e5dd7070Spatrick   if (!Map)
1770e5dd7070Spatrick     return {};
1771e5dd7070Spatrick 
1772e5dd7070Spatrick   StoredDeclsMap::iterator I = Map->find(Name);
1773e5dd7070Spatrick   return I != Map->end() ? I->second.getLookupResult()
1774e5dd7070Spatrick                          : lookup_result();
1775e5dd7070Spatrick }
1776e5dd7070Spatrick 
1777e5dd7070Spatrick // If we have any lazy lexical declarations not in our lookup map, add them
1778e5dd7070Spatrick // now. Don't import any external declarations, not even if we know we have
1779e5dd7070Spatrick // some missing from the external visible lookups.
loadLazyLocalLexicalLookups()1780e5dd7070Spatrick void DeclContext::loadLazyLocalLexicalLookups() {
1781e5dd7070Spatrick   if (hasLazyLocalLexicalLookups()) {
1782e5dd7070Spatrick     SmallVector<DeclContext *, 2> Contexts;
1783e5dd7070Spatrick     collectAllContexts(Contexts);
1784e5dd7070Spatrick     for (auto *Context : Contexts)
1785e5dd7070Spatrick       buildLookupImpl(Context, hasExternalVisibleStorage());
1786e5dd7070Spatrick     setHasLazyLocalLexicalLookups(false);
1787e5dd7070Spatrick   }
1788e5dd7070Spatrick }
1789e5dd7070Spatrick 
localUncachedLookup(DeclarationName Name,SmallVectorImpl<NamedDecl * > & Results)1790e5dd7070Spatrick void DeclContext::localUncachedLookup(DeclarationName Name,
1791e5dd7070Spatrick                                       SmallVectorImpl<NamedDecl *> &Results) {
1792e5dd7070Spatrick   Results.clear();
1793e5dd7070Spatrick 
1794e5dd7070Spatrick   // If there's no external storage, just perform a normal lookup and copy
1795e5dd7070Spatrick   // the results.
1796e5dd7070Spatrick   if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
1797e5dd7070Spatrick     lookup_result LookupResults = lookup(Name);
1798e5dd7070Spatrick     Results.insert(Results.end(), LookupResults.begin(), LookupResults.end());
1799*12c85518Srobert     if (!Results.empty())
1800e5dd7070Spatrick       return;
1801e5dd7070Spatrick   }
1802e5dd7070Spatrick 
1803e5dd7070Spatrick   // If we have a lookup table, check there first. Maybe we'll get lucky.
1804e5dd7070Spatrick   // FIXME: Should we be checking these flags on the primary context?
1805e5dd7070Spatrick   if (Name && !hasLazyLocalLexicalLookups() &&
1806e5dd7070Spatrick       !hasLazyExternalLexicalLookups()) {
1807e5dd7070Spatrick     if (StoredDeclsMap *Map = LookupPtr) {
1808e5dd7070Spatrick       StoredDeclsMap::iterator Pos = Map->find(Name);
1809e5dd7070Spatrick       if (Pos != Map->end()) {
1810e5dd7070Spatrick         Results.insert(Results.end(),
1811e5dd7070Spatrick                        Pos->second.getLookupResult().begin(),
1812e5dd7070Spatrick                        Pos->second.getLookupResult().end());
1813e5dd7070Spatrick         return;
1814e5dd7070Spatrick       }
1815e5dd7070Spatrick     }
1816e5dd7070Spatrick   }
1817e5dd7070Spatrick 
1818e5dd7070Spatrick   // Slow case: grovel through the declarations in our chain looking for
1819e5dd7070Spatrick   // matches.
1820e5dd7070Spatrick   // FIXME: If we have lazy external declarations, this will not find them!
1821e5dd7070Spatrick   // FIXME: Should we CollectAllContexts and walk them all here?
1822e5dd7070Spatrick   for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {
1823e5dd7070Spatrick     if (auto *ND = dyn_cast<NamedDecl>(D))
1824e5dd7070Spatrick       if (ND->getDeclName() == Name)
1825e5dd7070Spatrick         Results.push_back(ND);
1826e5dd7070Spatrick   }
1827e5dd7070Spatrick }
1828e5dd7070Spatrick 
getRedeclContext()1829e5dd7070Spatrick DeclContext *DeclContext::getRedeclContext() {
1830e5dd7070Spatrick   DeclContext *Ctx = this;
1831e5dd7070Spatrick 
1832e5dd7070Spatrick   // In C, a record type is the redeclaration context for its fields only. If
1833e5dd7070Spatrick   // we arrive at a record context after skipping anything else, we should skip
1834e5dd7070Spatrick   // the record as well. Currently, this means skipping enumerations because
1835e5dd7070Spatrick   // they're the only transparent context that can exist within a struct or
1836e5dd7070Spatrick   // union.
1837e5dd7070Spatrick   bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
1838e5dd7070Spatrick                      !getParentASTContext().getLangOpts().CPlusPlus;
1839e5dd7070Spatrick 
1840e5dd7070Spatrick   // Skip through contexts to get to the redeclaration context. Transparent
1841e5dd7070Spatrick   // contexts are always skipped.
1842e5dd7070Spatrick   while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())
1843e5dd7070Spatrick     Ctx = Ctx->getParent();
1844e5dd7070Spatrick   return Ctx;
1845e5dd7070Spatrick }
1846e5dd7070Spatrick 
getEnclosingNamespaceContext()1847e5dd7070Spatrick DeclContext *DeclContext::getEnclosingNamespaceContext() {
1848e5dd7070Spatrick   DeclContext *Ctx = this;
1849e5dd7070Spatrick   // Skip through non-namespace, non-translation-unit contexts.
1850e5dd7070Spatrick   while (!Ctx->isFileContext())
1851e5dd7070Spatrick     Ctx = Ctx->getParent();
1852e5dd7070Spatrick   return Ctx->getPrimaryContext();
1853e5dd7070Spatrick }
1854e5dd7070Spatrick 
getOuterLexicalRecordContext()1855e5dd7070Spatrick RecordDecl *DeclContext::getOuterLexicalRecordContext() {
1856e5dd7070Spatrick   // Loop until we find a non-record context.
1857e5dd7070Spatrick   RecordDecl *OutermostRD = nullptr;
1858e5dd7070Spatrick   DeclContext *DC = this;
1859e5dd7070Spatrick   while (DC->isRecord()) {
1860e5dd7070Spatrick     OutermostRD = cast<RecordDecl>(DC);
1861e5dd7070Spatrick     DC = DC->getLexicalParent();
1862e5dd7070Spatrick   }
1863e5dd7070Spatrick   return OutermostRD;
1864e5dd7070Spatrick }
1865e5dd7070Spatrick 
InEnclosingNamespaceSetOf(const DeclContext * O) const1866e5dd7070Spatrick bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const {
1867e5dd7070Spatrick   // For non-file contexts, this is equivalent to Equals.
1868e5dd7070Spatrick   if (!isFileContext())
1869e5dd7070Spatrick     return O->Equals(this);
1870e5dd7070Spatrick 
1871e5dd7070Spatrick   do {
1872e5dd7070Spatrick     if (O->Equals(this))
1873e5dd7070Spatrick       return true;
1874e5dd7070Spatrick 
1875e5dd7070Spatrick     const auto *NS = dyn_cast<NamespaceDecl>(O);
1876e5dd7070Spatrick     if (!NS || !NS->isInline())
1877e5dd7070Spatrick       break;
1878e5dd7070Spatrick     O = NS->getParent();
1879e5dd7070Spatrick   } while (O);
1880e5dd7070Spatrick 
1881e5dd7070Spatrick   return false;
1882e5dd7070Spatrick }
1883e5dd7070Spatrick 
makeDeclVisibleInContext(NamedDecl * D)1884e5dd7070Spatrick void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
1885e5dd7070Spatrick   DeclContext *PrimaryDC = this->getPrimaryContext();
1886e5dd7070Spatrick   DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();
1887e5dd7070Spatrick   // If the decl is being added outside of its semantic decl context, we
1888e5dd7070Spatrick   // need to ensure that we eagerly build the lookup information for it.
1889e5dd7070Spatrick   PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);
1890e5dd7070Spatrick }
1891e5dd7070Spatrick 
makeDeclVisibleInContextWithFlags(NamedDecl * D,bool Internal,bool Recoverable)1892e5dd7070Spatrick void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
1893e5dd7070Spatrick                                                     bool Recoverable) {
1894e5dd7070Spatrick   assert(this == getPrimaryContext() && "expected a primary DC");
1895e5dd7070Spatrick 
1896e5dd7070Spatrick   if (!isLookupContext()) {
1897e5dd7070Spatrick     if (isTransparentContext())
1898e5dd7070Spatrick       getParent()->getPrimaryContext()
1899e5dd7070Spatrick         ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1900e5dd7070Spatrick     return;
1901e5dd7070Spatrick   }
1902e5dd7070Spatrick 
1903e5dd7070Spatrick   // Skip declarations which should be invisible to name lookup.
1904e5dd7070Spatrick   if (shouldBeHidden(D))
1905e5dd7070Spatrick     return;
1906e5dd7070Spatrick 
1907e5dd7070Spatrick   // If we already have a lookup data structure, perform the insertion into
1908e5dd7070Spatrick   // it. If we might have externally-stored decls with this name, look them
1909e5dd7070Spatrick   // up and perform the insertion. If this decl was declared outside its
1910e5dd7070Spatrick   // semantic context, buildLookup won't add it, so add it now.
1911e5dd7070Spatrick   //
1912e5dd7070Spatrick   // FIXME: As a performance hack, don't add such decls into the translation
1913e5dd7070Spatrick   // unit unless we're in C++, since qualified lookup into the TU is never
1914e5dd7070Spatrick   // performed.
1915e5dd7070Spatrick   if (LookupPtr || hasExternalVisibleStorage() ||
1916e5dd7070Spatrick       ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&
1917e5dd7070Spatrick        (getParentASTContext().getLangOpts().CPlusPlus ||
1918e5dd7070Spatrick         !isTranslationUnit()))) {
1919e5dd7070Spatrick     // If we have lazily omitted any decls, they might have the same name as
1920e5dd7070Spatrick     // the decl which we are adding, so build a full lookup table before adding
1921e5dd7070Spatrick     // this decl.
1922e5dd7070Spatrick     buildLookup();
1923e5dd7070Spatrick     makeDeclVisibleInContextImpl(D, Internal);
1924e5dd7070Spatrick   } else {
1925e5dd7070Spatrick     setHasLazyLocalLexicalLookups(true);
1926e5dd7070Spatrick   }
1927e5dd7070Spatrick 
1928e5dd7070Spatrick   // If we are a transparent context or inline namespace, insert into our
1929e5dd7070Spatrick   // parent context, too. This operation is recursive.
1930e5dd7070Spatrick   if (isTransparentContext() || isInlineNamespace())
1931e5dd7070Spatrick     getParent()->getPrimaryContext()->
1932e5dd7070Spatrick         makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1933e5dd7070Spatrick 
1934e5dd7070Spatrick   auto *DCAsDecl = cast<Decl>(this);
1935e5dd7070Spatrick   // Notify that a decl was made visible unless we are a Tag being defined.
1936e5dd7070Spatrick   if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1937e5dd7070Spatrick     if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())
1938e5dd7070Spatrick       L->AddedVisibleDecl(this, D);
1939e5dd7070Spatrick }
1940e5dd7070Spatrick 
makeDeclVisibleInContextImpl(NamedDecl * D,bool Internal)1941e5dd7070Spatrick void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
1942e5dd7070Spatrick   // Find or create the stored declaration map.
1943e5dd7070Spatrick   StoredDeclsMap *Map = LookupPtr;
1944e5dd7070Spatrick   if (!Map) {
1945e5dd7070Spatrick     ASTContext *C = &getParentASTContext();
1946e5dd7070Spatrick     Map = CreateStoredDeclsMap(*C);
1947e5dd7070Spatrick   }
1948e5dd7070Spatrick 
1949e5dd7070Spatrick   // If there is an external AST source, load any declarations it knows about
1950e5dd7070Spatrick   // with this declaration's name.
1951e5dd7070Spatrick   // If the lookup table contains an entry about this name it means that we
1952e5dd7070Spatrick   // have already checked the external source.
1953e5dd7070Spatrick   if (!Internal)
1954e5dd7070Spatrick     if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
1955e5dd7070Spatrick       if (hasExternalVisibleStorage() &&
1956e5dd7070Spatrick           Map->find(D->getDeclName()) == Map->end())
1957e5dd7070Spatrick         Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
1958e5dd7070Spatrick 
1959e5dd7070Spatrick   // Insert this declaration into the map.
1960e5dd7070Spatrick   StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];
1961e5dd7070Spatrick 
1962e5dd7070Spatrick   if (Internal) {
1963e5dd7070Spatrick     // If this is being added as part of loading an external declaration,
1964e5dd7070Spatrick     // this may not be the only external declaration with this name.
1965e5dd7070Spatrick     // In this case, we never try to replace an existing declaration; we'll
1966e5dd7070Spatrick     // handle that when we finalize the list of declarations for this name.
1967e5dd7070Spatrick     DeclNameEntries.setHasExternalDecls();
1968a9ac8606Spatrick     DeclNameEntries.prependDeclNoReplace(D);
1969e5dd7070Spatrick     return;
1970e5dd7070Spatrick   }
1971e5dd7070Spatrick 
1972a9ac8606Spatrick   DeclNameEntries.addOrReplaceDecl(D);
1973e5dd7070Spatrick }
1974e5dd7070Spatrick 
operator *() const1975e5dd7070Spatrick UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const {
1976e5dd7070Spatrick   return cast<UsingDirectiveDecl>(*I);
1977e5dd7070Spatrick }
1978e5dd7070Spatrick 
1979e5dd7070Spatrick /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
1980e5dd7070Spatrick /// this context.
using_directives() const1981e5dd7070Spatrick DeclContext::udir_range DeclContext::using_directives() const {
1982e5dd7070Spatrick   // FIXME: Use something more efficient than normal lookup for using
1983e5dd7070Spatrick   // directives. In C++, using directives are looked up more than anything else.
1984e5dd7070Spatrick   lookup_result Result = lookup(UsingDirectiveDecl::getName());
1985e5dd7070Spatrick   return udir_range(Result.begin(), Result.end());
1986e5dd7070Spatrick }
1987e5dd7070Spatrick 
1988e5dd7070Spatrick //===----------------------------------------------------------------------===//
1989e5dd7070Spatrick // Creation and Destruction of StoredDeclsMaps.                               //
1990e5dd7070Spatrick //===----------------------------------------------------------------------===//
1991e5dd7070Spatrick 
CreateStoredDeclsMap(ASTContext & C) const1992e5dd7070Spatrick StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {
1993e5dd7070Spatrick   assert(!LookupPtr && "context already has a decls map");
1994e5dd7070Spatrick   assert(getPrimaryContext() == this &&
1995e5dd7070Spatrick          "creating decls map on non-primary context");
1996e5dd7070Spatrick 
1997e5dd7070Spatrick   StoredDeclsMap *M;
1998e5dd7070Spatrick   bool Dependent = isDependentContext();
1999e5dd7070Spatrick   if (Dependent)
2000e5dd7070Spatrick     M = new DependentStoredDeclsMap();
2001e5dd7070Spatrick   else
2002e5dd7070Spatrick     M = new StoredDeclsMap();
2003e5dd7070Spatrick   M->Previous = C.LastSDM;
2004e5dd7070Spatrick   C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
2005e5dd7070Spatrick   LookupPtr = M;
2006e5dd7070Spatrick   return M;
2007e5dd7070Spatrick }
2008e5dd7070Spatrick 
ReleaseDeclContextMaps()2009e5dd7070Spatrick void ASTContext::ReleaseDeclContextMaps() {
2010e5dd7070Spatrick   // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap
2011e5dd7070Spatrick   // pointer because the subclass doesn't add anything that needs to
2012e5dd7070Spatrick   // be deleted.
2013e5dd7070Spatrick   StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());
2014*12c85518Srobert   LastSDM.setPointer(nullptr);
2015e5dd7070Spatrick }
2016e5dd7070Spatrick 
DestroyAll(StoredDeclsMap * Map,bool Dependent)2017e5dd7070Spatrick void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {
2018e5dd7070Spatrick   while (Map) {
2019e5dd7070Spatrick     // Advance the iteration before we invalidate memory.
2020e5dd7070Spatrick     llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
2021e5dd7070Spatrick 
2022e5dd7070Spatrick     if (Dependent)
2023e5dd7070Spatrick       delete static_cast<DependentStoredDeclsMap*>(Map);
2024e5dd7070Spatrick     else
2025e5dd7070Spatrick       delete Map;
2026e5dd7070Spatrick 
2027e5dd7070Spatrick     Map = Next.getPointer();
2028e5dd7070Spatrick     Dependent = Next.getInt();
2029e5dd7070Spatrick   }
2030e5dd7070Spatrick }
2031e5dd7070Spatrick 
Create(ASTContext & C,DeclContext * Parent,const PartialDiagnostic & PDiag)2032e5dd7070Spatrick DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
2033e5dd7070Spatrick                                                  DeclContext *Parent,
2034e5dd7070Spatrick                                            const PartialDiagnostic &PDiag) {
2035e5dd7070Spatrick   assert(Parent->isDependentContext()
2036e5dd7070Spatrick          && "cannot iterate dependent diagnostics of non-dependent context");
2037e5dd7070Spatrick   Parent = Parent->getPrimaryContext();
2038e5dd7070Spatrick   if (!Parent->LookupPtr)
2039e5dd7070Spatrick     Parent->CreateStoredDeclsMap(C);
2040e5dd7070Spatrick 
2041e5dd7070Spatrick   auto *Map = static_cast<DependentStoredDeclsMap *>(Parent->LookupPtr);
2042e5dd7070Spatrick 
2043e5dd7070Spatrick   // Allocate the copy of the PartialDiagnostic via the ASTContext's
2044e5dd7070Spatrick   // BumpPtrAllocator, rather than the ASTContext itself.
2045a9ac8606Spatrick   DiagnosticStorage *DiagStorage = nullptr;
2046e5dd7070Spatrick   if (PDiag.hasStorage())
2047a9ac8606Spatrick     DiagStorage = new (C) DiagnosticStorage;
2048e5dd7070Spatrick 
2049e5dd7070Spatrick   auto *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);
2050e5dd7070Spatrick 
2051e5dd7070Spatrick   // TODO: Maybe we shouldn't reverse the order during insertion.
2052e5dd7070Spatrick   DD->NextDiagnostic = Map->FirstDiagnostic;
2053e5dd7070Spatrick   Map->FirstDiagnostic = DD;
2054e5dd7070Spatrick 
2055e5dd7070Spatrick   return DD;
2056e5dd7070Spatrick }
2057