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