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