Path: blob/main/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
35260 views
//===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the Decl and DeclContext classes.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/DeclBase.h"13#include "clang/AST/ASTContext.h"14#include "clang/AST/ASTLambda.h"15#include "clang/AST/ASTMutationListener.h"16#include "clang/AST/Attr.h"17#include "clang/AST/AttrIterator.h"18#include "clang/AST/Decl.h"19#include "clang/AST/DeclCXX.h"20#include "clang/AST/DeclContextInternals.h"21#include "clang/AST/DeclFriend.h"22#include "clang/AST/DeclObjC.h"23#include "clang/AST/DeclOpenMP.h"24#include "clang/AST/DeclTemplate.h"25#include "clang/AST/DependentDiagnostic.h"26#include "clang/AST/ExternalASTSource.h"27#include "clang/AST/Stmt.h"28#include "clang/AST/Type.h"29#include "clang/Basic/IdentifierTable.h"30#include "clang/Basic/LLVM.h"31#include "clang/Basic/Module.h"32#include "clang/Basic/ObjCRuntime.h"33#include "clang/Basic/PartialDiagnostic.h"34#include "clang/Basic/SourceLocation.h"35#include "clang/Basic/TargetInfo.h"36#include "llvm/ADT/ArrayRef.h"37#include "llvm/ADT/PointerIntPair.h"38#include "llvm/ADT/SmallVector.h"39#include "llvm/ADT/StringRef.h"40#include "llvm/Support/Casting.h"41#include "llvm/Support/ErrorHandling.h"42#include "llvm/Support/MathExtras.h"43#include "llvm/Support/VersionTuple.h"44#include "llvm/Support/raw_ostream.h"45#include <algorithm>46#include <cassert>47#include <cstddef>48#include <string>49#include <tuple>50#include <utility>5152using namespace clang;5354//===----------------------------------------------------------------------===//55// Statistics56//===----------------------------------------------------------------------===//5758#define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;59#define ABSTRACT_DECL(DECL)60#include "clang/AST/DeclNodes.inc"6162void Decl::updateOutOfDate(IdentifierInfo &II) const {63getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);64}6566#define DECL(DERIVED, BASE) \67static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \68"Alignment sufficient after objects prepended to " #DERIVED);69#define ABSTRACT_DECL(DECL)70#include "clang/AST/DeclNodes.inc"7172void *Decl::operator new(std::size_t Size, const ASTContext &Context,73GlobalDeclID ID, std::size_t Extra) {74// Allocate an extra 8 bytes worth of storage, which ensures that the75// resulting pointer will still be 8-byte aligned.76static_assert(sizeof(uint64_t) >= alignof(Decl), "Decl won't be misaligned");77void *Start = Context.Allocate(Size + Extra + 8);78void *Result = (char*)Start + 8;7980uint64_t *PrefixPtr = (uint64_t *)Result - 1;8182*PrefixPtr = ID.getRawValue();8384// We leave the upper 16 bits to store the module IDs. 48 bits should be85// sufficient to store a declaration ID.86assert(*PrefixPtr < llvm::maskTrailingOnes<uint64_t>(48));8788return Result;89}9091void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,92DeclContext *Parent, std::size_t Extra) {93assert(!Parent || &Parent->getParentASTContext() == &Ctx);94// With local visibility enabled, we track the owning module even for local95// declarations. We create the TU decl early and may not yet know what the96// LangOpts are, so conservatively allocate the storage.97if (Ctx.getLangOpts().trackLocalOwningModule() || !Parent) {98// Ensure required alignment of the resulting object by adding extra99// padding at the start if required.100size_t ExtraAlign =101llvm::offsetToAlignment(sizeof(Module *), llvm::Align(alignof(Decl)));102auto *Buffer = reinterpret_cast<char *>(103::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));104Buffer += ExtraAlign;105auto *ParentModule =106Parent ? cast<Decl>(Parent)->getOwningModule() : nullptr;107return new (Buffer) Module*(ParentModule) + 1;108}109return ::operator new(Size + Extra, Ctx);110}111112GlobalDeclID Decl::getGlobalID() const {113if (!isFromASTFile())114return GlobalDeclID();115// See the comments in `Decl::operator new` for details.116uint64_t ID = *((const uint64_t *)this - 1);117return GlobalDeclID(ID & llvm::maskTrailingOnes<uint64_t>(48));118}119120unsigned Decl::getOwningModuleID() const {121if (!isFromASTFile())122return 0;123124uint64_t ID = *((const uint64_t *)this - 1);125return ID >> 48;126}127128void Decl::setOwningModuleID(unsigned ID) {129assert(isFromASTFile() && "Only works on a deserialized declaration");130uint64_t *IDAddress = (uint64_t *)this - 1;131*IDAddress &= llvm::maskTrailingOnes<uint64_t>(48);132*IDAddress |= (uint64_t)ID << 48;133}134135Module *Decl::getOwningModuleSlow() const {136assert(isFromASTFile() && "Not from AST file?");137return getASTContext().getExternalSource()->getModule(getOwningModuleID());138}139140bool Decl::hasLocalOwningModuleStorage() const {141return getASTContext().getLangOpts().trackLocalOwningModule();142}143144const char *Decl::getDeclKindName() const {145switch (DeclKind) {146default: llvm_unreachable("Declaration not in DeclNodes.inc!");147#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;148#define ABSTRACT_DECL(DECL)149#include "clang/AST/DeclNodes.inc"150}151}152153void Decl::setInvalidDecl(bool Invalid) {154InvalidDecl = Invalid;155assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());156if (!Invalid) {157return;158}159160if (!isa<ParmVarDecl>(this)) {161// Defensive maneuver for ill-formed code: we're likely not to make it to162// a point where we set the access specifier, so default it to "public"163// to avoid triggering asserts elsewhere in the front end.164setAccess(AS_public);165}166167// Marking a DecompositionDecl as invalid implies all the child BindingDecl's168// are invalid too.169if (auto *DD = dyn_cast<DecompositionDecl>(this)) {170for (auto *Binding : DD->bindings()) {171Binding->setInvalidDecl();172}173}174}175176bool DeclContext::hasValidDeclKind() const {177switch (getDeclKind()) {178#define DECL(DERIVED, BASE) case Decl::DERIVED: return true;179#define ABSTRACT_DECL(DECL)180#include "clang/AST/DeclNodes.inc"181}182return false;183}184185const char *DeclContext::getDeclKindName() const {186switch (getDeclKind()) {187#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;188#define ABSTRACT_DECL(DECL)189#include "clang/AST/DeclNodes.inc"190}191llvm_unreachable("Declaration context not in DeclNodes.inc!");192}193194bool Decl::StatisticsEnabled = false;195void Decl::EnableStatistics() {196StatisticsEnabled = true;197}198199void Decl::PrintStats() {200llvm::errs() << "\n*** Decl Stats:\n";201202int totalDecls = 0;203#define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;204#define ABSTRACT_DECL(DECL)205#include "clang/AST/DeclNodes.inc"206llvm::errs() << " " << totalDecls << " decls total.\n";207208int totalBytes = 0;209#define DECL(DERIVED, BASE) \210if (n##DERIVED##s > 0) { \211totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \212llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \213<< sizeof(DERIVED##Decl) << " each (" \214<< n##DERIVED##s * sizeof(DERIVED##Decl) \215<< " bytes)\n"; \216}217#define ABSTRACT_DECL(DECL)218#include "clang/AST/DeclNodes.inc"219220llvm::errs() << "Total bytes = " << totalBytes << "\n";221}222223void Decl::add(Kind k) {224switch (k) {225#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;226#define ABSTRACT_DECL(DECL)227#include "clang/AST/DeclNodes.inc"228}229}230231bool Decl::isTemplateParameterPack() const {232if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(this))233return TTP->isParameterPack();234if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(this))235return NTTP->isParameterPack();236if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(this))237return TTP->isParameterPack();238return false;239}240241bool Decl::isParameterPack() const {242if (const auto *Var = dyn_cast<VarDecl>(this))243return Var->isParameterPack();244245return isTemplateParameterPack();246}247248FunctionDecl *Decl::getAsFunction() {249if (auto *FD = dyn_cast<FunctionDecl>(this))250return FD;251if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(this))252return FTD->getTemplatedDecl();253return nullptr;254}255256bool Decl::isTemplateDecl() const {257return isa<TemplateDecl>(this);258}259260TemplateDecl *Decl::getDescribedTemplate() const {261if (auto *FD = dyn_cast<FunctionDecl>(this))262return FD->getDescribedFunctionTemplate();263if (auto *RD = dyn_cast<CXXRecordDecl>(this))264return RD->getDescribedClassTemplate();265if (auto *VD = dyn_cast<VarDecl>(this))266return VD->getDescribedVarTemplate();267if (auto *AD = dyn_cast<TypeAliasDecl>(this))268return AD->getDescribedAliasTemplate();269270return nullptr;271}272273const TemplateParameterList *Decl::getDescribedTemplateParams() const {274if (auto *TD = getDescribedTemplate())275return TD->getTemplateParameters();276if (auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(this))277return CTPSD->getTemplateParameters();278if (auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(this))279return VTPSD->getTemplateParameters();280return nullptr;281}282283bool Decl::isTemplated() const {284// A declaration is templated if it is a template or a template pattern, or285// is within (lexcially for a friend or local function declaration,286// semantically otherwise) a dependent context.287if (auto *AsDC = dyn_cast<DeclContext>(this))288return AsDC->isDependentContext();289auto *DC = getFriendObjectKind() || isLocalExternDecl()290? getLexicalDeclContext() : getDeclContext();291return DC->isDependentContext() || isTemplateDecl() ||292getDescribedTemplateParams();293}294295unsigned Decl::getTemplateDepth() const {296if (auto *DC = dyn_cast<DeclContext>(this))297if (DC->isFileContext())298return 0;299300if (auto *TPL = getDescribedTemplateParams())301return TPL->getDepth() + 1;302303// If this is a dependent lambda, there might be an enclosing variable304// template. In this case, the next step is not the parent DeclContext (or305// even a DeclContext at all).306auto *RD = dyn_cast<CXXRecordDecl>(this);307if (RD && RD->isDependentLambda())308if (Decl *Context = RD->getLambdaContextDecl())309return Context->getTemplateDepth();310311const DeclContext *DC =312getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();313return cast<Decl>(DC)->getTemplateDepth();314}315316const DeclContext *Decl::getParentFunctionOrMethod(bool LexicalParent) const {317for (const DeclContext *DC = LexicalParent ? getLexicalDeclContext()318: getDeclContext();319DC && !DC->isFileContext(); DC = DC->getParent())320if (DC->isFunctionOrMethod())321return DC;322323return nullptr;324}325326//===----------------------------------------------------------------------===//327// PrettyStackTraceDecl Implementation328//===----------------------------------------------------------------------===//329330void PrettyStackTraceDecl::print(raw_ostream &OS) const {331SourceLocation TheLoc = Loc;332if (TheLoc.isInvalid() && TheDecl)333TheLoc = TheDecl->getLocation();334335if (TheLoc.isValid()) {336TheLoc.print(OS, SM);337OS << ": ";338}339340OS << Message;341342if (const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {343OS << " '";344DN->printQualifiedName(OS);345OS << '\'';346}347OS << '\n';348}349350//===----------------------------------------------------------------------===//351// Decl Implementation352//===----------------------------------------------------------------------===//353354// Out-of-line virtual method providing a home for Decl.355Decl::~Decl() = default;356357void Decl::setDeclContext(DeclContext *DC) {358DeclCtx = DC;359}360361void Decl::setLexicalDeclContext(DeclContext *DC) {362if (DC == getLexicalDeclContext())363return;364365if (isInSemaDC()) {366setDeclContextsImpl(getDeclContext(), DC, getASTContext());367} else {368getMultipleDC()->LexicalDC = DC;369}370371// FIXME: We shouldn't be changing the lexical context of declarations372// imported from AST files.373if (!isFromASTFile()) {374setModuleOwnershipKind(getModuleOwnershipKindForChildOf(DC));375if (hasOwningModule())376setLocalOwningModule(cast<Decl>(DC)->getOwningModule());377}378379assert(380(getModuleOwnershipKind() != ModuleOwnershipKind::VisibleWhenImported ||381getOwningModule()) &&382"hidden declaration has no owning module");383}384385void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,386ASTContext &Ctx) {387if (SemaDC == LexicalDC) {388DeclCtx = SemaDC;389} else {390auto *MDC = new (Ctx) Decl::MultipleDC();391MDC->SemanticDC = SemaDC;392MDC->LexicalDC = LexicalDC;393DeclCtx = MDC;394}395}396397bool Decl::isInLocalScopeForInstantiation() const {398const DeclContext *LDC = getLexicalDeclContext();399if (!LDC->isDependentContext())400return false;401while (true) {402if (LDC->isFunctionOrMethod())403return true;404if (!isa<TagDecl>(LDC))405return false;406if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))407if (CRD->isLambda())408return true;409LDC = LDC->getLexicalParent();410}411return false;412}413414bool Decl::isInAnonymousNamespace() const {415for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {416if (const auto *ND = dyn_cast<NamespaceDecl>(DC))417if (ND->isAnonymousNamespace())418return true;419}420421return false;422}423424bool Decl::isInStdNamespace() const {425const DeclContext *DC = getDeclContext();426return DC && DC->getNonTransparentContext()->isStdNamespace();427}428429bool Decl::isFileContextDecl() const {430const auto *DC = dyn_cast<DeclContext>(this);431return DC && DC->isFileContext();432}433434bool Decl::isFlexibleArrayMemberLike(435ASTContext &Ctx, const Decl *D, QualType Ty,436LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,437bool IgnoreTemplateOrMacroSubstitution) {438// For compatibility with existing code, we treat arrays of length 0 or439// 1 as flexible array members.440const auto *CAT = Ctx.getAsConstantArrayType(Ty);441if (CAT) {442using FAMKind = LangOptions::StrictFlexArraysLevelKind;443444llvm::APInt Size = CAT->getSize();445if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)446return false;447448// GCC extension, only allowed to represent a FAM.449if (Size.isZero())450return true;451452if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))453return false;454455if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))456return false;457} else if (!Ctx.getAsIncompleteArrayType(Ty)) {458return false;459}460461if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D))462return OID->getNextIvar() == nullptr;463464const auto *FD = dyn_cast_if_present<FieldDecl>(D);465if (!FD)466return false;467468if (CAT) {469// GCC treats an array memeber of a union as an FAM if the size is one or470// zero.471llvm::APInt Size = CAT->getSize();472if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))473return true;474}475476// Don't consider sizes resulting from macro expansions or template argument477// substitution to form C89 tail-padded arrays.478if (IgnoreTemplateOrMacroSubstitution) {479TypeSourceInfo *TInfo = FD->getTypeSourceInfo();480while (TInfo) {481TypeLoc TL = TInfo->getTypeLoc();482483// Look through typedefs.484if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {485const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();486TInfo = TDL->getTypeSourceInfo();487continue;488}489490if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) {491if (const Expr *SizeExpr =492dyn_cast_if_present<IntegerLiteral>(CTL.getSizeExpr());493!SizeExpr || SizeExpr->getExprLoc().isMacroID())494return false;495}496497break;498}499}500501// Test that the field is the last in the structure.502RecordDecl::field_iterator FI(503DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));504return ++FI == FD->getParent()->field_end();505}506507TranslationUnitDecl *Decl::getTranslationUnitDecl() {508if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))509return TUD;510511DeclContext *DC = getDeclContext();512assert(DC && "This decl is not contained in a translation unit!");513514while (!DC->isTranslationUnit()) {515DC = DC->getParent();516assert(DC && "This decl is not contained in a translation unit!");517}518519return cast<TranslationUnitDecl>(DC);520}521522ASTContext &Decl::getASTContext() const {523return getTranslationUnitDecl()->getASTContext();524}525526/// Helper to get the language options from the ASTContext.527/// Defined out of line to avoid depending on ASTContext.h.528const LangOptions &Decl::getLangOpts() const {529return getASTContext().getLangOpts();530}531532ASTMutationListener *Decl::getASTMutationListener() const {533return getASTContext().getASTMutationListener();534}535536unsigned Decl::getMaxAlignment() const {537if (!hasAttrs())538return 0;539540unsigned Align = 0;541const AttrVec &V = getAttrs();542ASTContext &Ctx = getASTContext();543specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());544for (; I != E; ++I) {545if (!I->isAlignmentErrorDependent())546Align = std::max(Align, I->getAlignment(Ctx));547}548return Align;549}550551bool Decl::isUsed(bool CheckUsedAttr) const {552const Decl *CanonD = getCanonicalDecl();553if (CanonD->Used)554return true;555556// Check for used attribute.557// Ask the most recent decl, since attributes accumulate in the redecl chain.558if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>())559return true;560561// The information may have not been deserialized yet. Force deserialization562// to complete the needed information.563return getMostRecentDecl()->getCanonicalDecl()->Used;564}565566void Decl::markUsed(ASTContext &C) {567if (isUsed(false))568return;569570if (C.getASTMutationListener())571C.getASTMutationListener()->DeclarationMarkedUsed(this);572573setIsUsed();574}575576bool Decl::isReferenced() const {577if (Referenced)578return true;579580// Check redeclarations.581for (const auto *I : redecls())582if (I->Referenced)583return true;584585return false;586}587588ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {589const Decl *Definition = nullptr;590if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {591Definition = ID->getDefinition();592} else if (auto *PD = dyn_cast<ObjCProtocolDecl>(this)) {593Definition = PD->getDefinition();594} else if (auto *TD = dyn_cast<TagDecl>(this)) {595Definition = TD->getDefinition();596}597if (!Definition)598Definition = this;599600if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())601return attr;602if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {603return dcd->getAttr<ExternalSourceSymbolAttr>();604}605606return nullptr;607}608609bool Decl::hasDefiningAttr() const {610return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||611hasAttr<LoaderUninitializedAttr>();612}613614const Attr *Decl::getDefiningAttr() const {615if (auto *AA = getAttr<AliasAttr>())616return AA;617if (auto *IFA = getAttr<IFuncAttr>())618return IFA;619if (auto *NZA = getAttr<LoaderUninitializedAttr>())620return NZA;621return nullptr;622}623624static StringRef getRealizedPlatform(const AvailabilityAttr *A,625const ASTContext &Context) {626// Check if this is an App Extension "platform", and if so chop off627// the suffix for matching with the actual platform.628StringRef RealizedPlatform = A->getPlatform()->getName();629if (!Context.getLangOpts().AppExt)630return RealizedPlatform;631size_t suffix = RealizedPlatform.rfind("_app_extension");632if (suffix != StringRef::npos)633return RealizedPlatform.slice(0, suffix);634return RealizedPlatform;635}636637/// Determine the availability of the given declaration based on638/// the target platform.639///640/// When it returns an availability result other than \c AR_Available,641/// if the \p Message parameter is non-NULL, it will be set to a642/// string describing why the entity is unavailable.643///644/// FIXME: Make these strings localizable, since they end up in645/// diagnostics.646static AvailabilityResult CheckAvailability(ASTContext &Context,647const AvailabilityAttr *A,648std::string *Message,649VersionTuple EnclosingVersion) {650if (EnclosingVersion.empty())651EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();652653if (EnclosingVersion.empty())654return AR_Available;655656StringRef ActualPlatform = A->getPlatform()->getName();657StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();658659// Match the platform name.660if (getRealizedPlatform(A, Context) != TargetPlatform)661return AR_Available;662663StringRef PrettyPlatformName664= AvailabilityAttr::getPrettyPlatformName(ActualPlatform);665666if (PrettyPlatformName.empty())667PrettyPlatformName = ActualPlatform;668669std::string HintMessage;670if (!A->getMessage().empty()) {671HintMessage = " - ";672HintMessage += A->getMessage();673}674675// Make sure that this declaration has not been marked 'unavailable'.676if (A->getUnavailable()) {677if (Message) {678Message->clear();679llvm::raw_string_ostream Out(*Message);680Out << "not available on " << PrettyPlatformName681<< HintMessage;682}683684return AR_Unavailable;685}686687// Make sure that this declaration has already been introduced.688if (!A->getIntroduced().empty() &&689EnclosingVersion < A->getIntroduced()) {690IdentifierInfo *IIEnv = A->getEnvironment();691StringRef TargetEnv =692Context.getTargetInfo().getTriple().getEnvironmentName();693StringRef EnvName = llvm::Triple::getEnvironmentTypeName(694Context.getTargetInfo().getTriple().getEnvironment());695// Matching environment or no environment on attribute696if (!IIEnv || (!TargetEnv.empty() && IIEnv->getName() == TargetEnv)) {697if (Message) {698Message->clear();699llvm::raw_string_ostream Out(*Message);700VersionTuple VTI(A->getIntroduced());701Out << "introduced in " << PrettyPlatformName << " " << VTI << " "702<< EnvName << HintMessage;703}704}705// Non-matching environment or no environment on target706else {707if (Message) {708Message->clear();709llvm::raw_string_ostream Out(*Message);710Out << "not available on " << PrettyPlatformName << " " << EnvName711<< HintMessage;712}713}714715return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced;716}717718// Make sure that this declaration hasn't been obsoleted.719if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {720if (Message) {721Message->clear();722llvm::raw_string_ostream Out(*Message);723VersionTuple VTO(A->getObsoleted());724Out << "obsoleted in " << PrettyPlatformName << ' '725<< VTO << HintMessage;726}727728return AR_Unavailable;729}730731// Make sure that this declaration hasn't been deprecated.732if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {733if (Message) {734Message->clear();735llvm::raw_string_ostream Out(*Message);736VersionTuple VTD(A->getDeprecated());737Out << "first deprecated in " << PrettyPlatformName << ' '738<< VTD << HintMessage;739}740741return AR_Deprecated;742}743744return AR_Available;745}746747AvailabilityResult Decl::getAvailability(std::string *Message,748VersionTuple EnclosingVersion,749StringRef *RealizedPlatform) const {750if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))751return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,752RealizedPlatform);753754AvailabilityResult Result = AR_Available;755std::string ResultMessage;756757for (const auto *A : attrs()) {758if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {759if (Result >= AR_Deprecated)760continue;761762if (Message)763ResultMessage = std::string(Deprecated->getMessage());764765Result = AR_Deprecated;766continue;767}768769if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {770if (Message)771*Message = std::string(Unavailable->getMessage());772return AR_Unavailable;773}774775if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {776AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,777Message, EnclosingVersion);778779if (AR == AR_Unavailable) {780if (RealizedPlatform)781*RealizedPlatform = Availability->getPlatform()->getName();782return AR_Unavailable;783}784785if (AR > Result) {786Result = AR;787if (Message)788ResultMessage.swap(*Message);789}790continue;791}792}793794if (Message)795Message->swap(ResultMessage);796return Result;797}798799VersionTuple Decl::getVersionIntroduced() const {800const ASTContext &Context = getASTContext();801StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();802for (const auto *A : attrs()) {803if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {804if (getRealizedPlatform(Availability, Context) != TargetPlatform)805continue;806if (!Availability->getIntroduced().empty())807return Availability->getIntroduced();808}809}810return {};811}812813bool Decl::canBeWeakImported(bool &IsDefinition) const {814IsDefinition = false;815816// Variables, if they aren't definitions.817if (const auto *Var = dyn_cast<VarDecl>(this)) {818if (Var->isThisDeclarationADefinition()) {819IsDefinition = true;820return false;821}822return true;823}824// Functions, if they aren't definitions.825if (const auto *FD = dyn_cast<FunctionDecl>(this)) {826if (FD->hasBody()) {827IsDefinition = true;828return false;829}830return true;831832}833// Objective-C classes, if this is the non-fragile runtime.834if (isa<ObjCInterfaceDecl>(this) &&835getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {836return true;837}838// Nothing else.839return false;840}841842bool Decl::isWeakImported() const {843bool IsDefinition;844if (!canBeWeakImported(IsDefinition))845return false;846847for (const auto *A : getMostRecentDecl()->attrs()) {848if (isa<WeakImportAttr>(A))849return true;850851if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {852if (CheckAvailability(getASTContext(), Availability, nullptr,853VersionTuple()) == AR_NotYetIntroduced)854return true;855}856}857858return false;859}860861unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {862switch (DeclKind) {863case Function:864case CXXDeductionGuide:865case CXXMethod:866case CXXConstructor:867case ConstructorUsingShadow:868case CXXDestructor:869case CXXConversion:870case EnumConstant:871case Var:872case ImplicitParam:873case ParmVar:874case ObjCMethod:875case ObjCProperty:876case MSProperty:877case HLSLBuffer:878return IDNS_Ordinary;879case Label:880return IDNS_Label;881case IndirectField:882return IDNS_Ordinary | IDNS_Member;883884case Binding:885case NonTypeTemplateParm:886case VarTemplate:887case Concept:888// These (C++-only) declarations are found by redeclaration lookup for889// tag types, so we include them in the tag namespace.890return IDNS_Ordinary | IDNS_Tag;891892case ObjCCompatibleAlias:893case ObjCInterface:894return IDNS_Ordinary | IDNS_Type;895896case Typedef:897case TypeAlias:898case TemplateTypeParm:899case ObjCTypeParam:900return IDNS_Ordinary | IDNS_Type;901902case UnresolvedUsingTypename:903return IDNS_Ordinary | IDNS_Type | IDNS_Using;904905case UsingShadow:906return 0; // we'll actually overwrite this later907908case UnresolvedUsingValue:909return IDNS_Ordinary | IDNS_Using;910911case Using:912case UsingPack:913case UsingEnum:914return IDNS_Using;915916case ObjCProtocol:917return IDNS_ObjCProtocol;918919case Field:920case ObjCAtDefsField:921case ObjCIvar:922return IDNS_Member;923924case Record:925case CXXRecord:926case Enum:927return IDNS_Tag | IDNS_Type;928929case Namespace:930case NamespaceAlias:931return IDNS_Namespace;932933case FunctionTemplate:934return IDNS_Ordinary;935936case ClassTemplate:937case TemplateTemplateParm:938case TypeAliasTemplate:939return IDNS_Ordinary | IDNS_Tag | IDNS_Type;940941case UnresolvedUsingIfExists:942return IDNS_Type | IDNS_Ordinary;943944case OMPDeclareReduction:945return IDNS_OMPReduction;946947case OMPDeclareMapper:948return IDNS_OMPMapper;949950// Never have names.951case Friend:952case FriendTemplate:953case AccessSpec:954case LinkageSpec:955case Export:956case FileScopeAsm:957case TopLevelStmt:958case StaticAssert:959case ObjCPropertyImpl:960case PragmaComment:961case PragmaDetectMismatch:962case Block:963case Captured:964case TranslationUnit:965case ExternCContext:966case Decomposition:967case MSGuid:968case UnnamedGlobalConstant:969case TemplateParamObject:970971case UsingDirective:972case BuiltinTemplate:973case ClassTemplateSpecialization:974case ClassTemplatePartialSpecialization:975case VarTemplateSpecialization:976case VarTemplatePartialSpecialization:977case ObjCImplementation:978case ObjCCategory:979case ObjCCategoryImpl:980case Import:981case OMPThreadPrivate:982case OMPAllocate:983case OMPRequires:984case OMPCapturedExpr:985case Empty:986case LifetimeExtendedTemporary:987case RequiresExprBody:988case ImplicitConceptSpecialization:989// Never looked up by name.990return 0;991}992993llvm_unreachable("Invalid DeclKind!");994}995996void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {997assert(!HasAttrs && "Decl already contains attrs.");998999AttrVec &AttrBlank = Ctx.getDeclAttrs(this);1000assert(AttrBlank.empty() && "HasAttrs was wrong?");10011002AttrBlank = attrs;1003HasAttrs = true;1004}10051006void Decl::dropAttrs() {1007if (!HasAttrs) return;10081009HasAttrs = false;1010getASTContext().eraseDeclAttrs(this);1011}10121013void Decl::addAttr(Attr *A) {1014if (!hasAttrs()) {1015setAttrs(AttrVec(1, A));1016return;1017}10181019AttrVec &Attrs = getAttrs();1020if (!A->isInherited()) {1021Attrs.push_back(A);1022return;1023}10241025// Attribute inheritance is processed after attribute parsing. To keep the1026// order as in the source code, add inherited attributes before non-inherited1027// ones.1028auto I = Attrs.begin(), E = Attrs.end();1029for (; I != E; ++I) {1030if (!(*I)->isInherited())1031break;1032}1033Attrs.insert(I, A);1034}10351036const AttrVec &Decl::getAttrs() const {1037assert(HasAttrs && "No attrs to get!");1038return getASTContext().getDeclAttrs(this);1039}10401041Decl *Decl::castFromDeclContext (const DeclContext *D) {1042Decl::Kind DK = D->getDeclKind();1043switch (DK) {1044#define DECL(NAME, BASE)1045#define DECL_CONTEXT(NAME) \1046case Decl::NAME: \1047return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));1048#include "clang/AST/DeclNodes.inc"1049default:1050llvm_unreachable("a decl that inherits DeclContext isn't handled");1051}1052}10531054DeclContext *Decl::castToDeclContext(const Decl *D) {1055Decl::Kind DK = D->getKind();1056switch(DK) {1057#define DECL(NAME, BASE)1058#define DECL_CONTEXT(NAME) \1059case Decl::NAME: \1060return static_cast<NAME##Decl *>(const_cast<Decl *>(D));1061#include "clang/AST/DeclNodes.inc"1062default:1063llvm_unreachable("a decl that inherits DeclContext isn't handled");1064}1065}10661067SourceLocation Decl::getBodyRBrace() const {1068// Special handling of FunctionDecl to avoid de-serializing the body from PCH.1069// FunctionDecl stores EndRangeLoc for this purpose.1070if (const auto *FD = dyn_cast<FunctionDecl>(this)) {1071const FunctionDecl *Definition;1072if (FD->hasBody(Definition))1073return Definition->getSourceRange().getEnd();1074return {};1075}10761077if (Stmt *Body = getBody())1078return Body->getSourceRange().getEnd();10791080return {};1081}10821083bool Decl::AccessDeclContextCheck() const {1084#ifndef NDEBUG1085// Suppress this check if any of the following hold:1086// 1. this is the translation unit (and thus has no parent)1087// 2. this is a template parameter (and thus doesn't belong to its context)1088// 3. this is a non-type template parameter1089// 4. the context is not a record1090// 5. it's invalid1091// 6. it's a C++0x static_assert.1092// 7. it's a block literal declaration1093// 8. it's a temporary with lifetime extended due to being default value.1094if (isa<TranslationUnitDecl>(this) || isa<TemplateTypeParmDecl>(this) ||1095isa<NonTypeTemplateParmDecl>(this) || !getDeclContext() ||1096!isa<CXXRecordDecl>(getDeclContext()) || isInvalidDecl() ||1097isa<StaticAssertDecl>(this) || isa<BlockDecl>(this) ||1098// FIXME: a ParmVarDecl can have ClassTemplateSpecialization1099// as DeclContext (?).1100isa<ParmVarDecl>(this) ||1101// FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have1102// AS_none as access specifier.1103isa<CXXRecordDecl>(this) || isa<LifetimeExtendedTemporaryDecl>(this))1104return true;11051106assert(Access != AS_none &&1107"Access specifier is AS_none inside a record decl");1108#endif1109return true;1110}11111112bool Decl::isInExportDeclContext() const {1113const DeclContext *DC = getLexicalDeclContext();11141115while (DC && !isa<ExportDecl>(DC))1116DC = DC->getLexicalParent();11171118return isa_and_nonnull<ExportDecl>(DC);1119}11201121bool Decl::isInAnotherModuleUnit() const {1122auto *M = getOwningModule();11231124if (!M)1125return false;11261127// FIXME or NOTE: maybe we need to be clear about the semantics1128// of clang header modules. e.g., if this lives in a clang header1129// module included by the current unit, should we return false1130// here?1131//1132// This is clear for header units as the specification says the1133// header units live in a synthesised translation unit. So we1134// can return false here.1135M = M->getTopLevelModule();1136if (!M->isNamedModule())1137return false;11381139return M != getASTContext().getCurrentNamedModule();1140}11411142bool Decl::isInCurrentModuleUnit() const {1143auto *M = getOwningModule();11441145if (!M || !M->isNamedModule())1146return false;11471148return M == getASTContext().getCurrentNamedModule();1149}11501151bool Decl::shouldEmitInExternalSource() const {1152ExternalASTSource *Source = getASTContext().getExternalSource();1153if (!Source)1154return false;11551156return Source->hasExternalDefinitions(this) == ExternalASTSource::EK_Always;1157}11581159bool Decl::isFromExplicitGlobalModule() const {1160return getOwningModule() && getOwningModule()->isExplicitGlobalModule();1161}11621163bool Decl::isFromGlobalModule() const {1164return getOwningModule() && getOwningModule()->isGlobalModule();1165}11661167bool Decl::isInNamedModule() const {1168return getOwningModule() && getOwningModule()->isNamedModule();1169}11701171static Decl::Kind getKind(const Decl *D) { return D->getKind(); }1172static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }11731174int64_t Decl::getID() const {1175return getASTContext().getAllocator().identifyKnownAlignedObject<Decl>(this);1176}11771178const FunctionType *Decl::getFunctionType(bool BlocksToo) const {1179QualType Ty;1180if (isa<BindingDecl>(this))1181return nullptr;1182else if (const auto *D = dyn_cast<ValueDecl>(this))1183Ty = D->getType();1184else if (const auto *D = dyn_cast<TypedefNameDecl>(this))1185Ty = D->getUnderlyingType();1186else1187return nullptr;11881189if (Ty->isFunctionPointerType())1190Ty = Ty->castAs<PointerType>()->getPointeeType();1191else if (Ty->isFunctionReferenceType())1192Ty = Ty->castAs<ReferenceType>()->getPointeeType();1193else if (BlocksToo && Ty->isBlockPointerType())1194Ty = Ty->castAs<BlockPointerType>()->getPointeeType();11951196return Ty->getAs<FunctionType>();1197}11981199bool Decl::isFunctionPointerType() const {1200QualType Ty;1201if (const auto *D = dyn_cast<ValueDecl>(this))1202Ty = D->getType();1203else if (const auto *D = dyn_cast<TypedefNameDecl>(this))1204Ty = D->getUnderlyingType();1205else1206return false;12071208return Ty.getCanonicalType()->isFunctionPointerType();1209}12101211DeclContext *Decl::getNonTransparentDeclContext() {1212assert(getDeclContext());1213return getDeclContext()->getNonTransparentContext();1214}12151216/// Starting at a given context (a Decl or DeclContext), look for a1217/// code context that is not a closure (a lambda, block, etc.).1218template <class T> static Decl *getNonClosureContext(T *D) {1219if (getKind(D) == Decl::CXXMethod) {1220auto *MD = cast<CXXMethodDecl>(D);1221if (MD->getOverloadedOperator() == OO_Call &&1222MD->getParent()->isLambda())1223return getNonClosureContext(MD->getParent()->getParent());1224return MD;1225}1226if (auto *FD = dyn_cast<FunctionDecl>(D))1227return FD;1228if (auto *MD = dyn_cast<ObjCMethodDecl>(D))1229return MD;1230if (auto *BD = dyn_cast<BlockDecl>(D))1231return getNonClosureContext(BD->getParent());1232if (auto *CD = dyn_cast<CapturedDecl>(D))1233return getNonClosureContext(CD->getParent());1234return nullptr;1235}12361237Decl *Decl::getNonClosureContext() {1238return ::getNonClosureContext(this);1239}12401241Decl *DeclContext::getNonClosureAncestor() {1242return ::getNonClosureContext(this);1243}12441245//===----------------------------------------------------------------------===//1246// DeclContext Implementation1247//===----------------------------------------------------------------------===//12481249DeclContext::DeclContext(Decl::Kind K) {1250DeclContextBits.DeclKind = K;1251setHasExternalLexicalStorage(false);1252setHasExternalVisibleStorage(false);1253setNeedToReconcileExternalVisibleStorage(false);1254setHasLazyLocalLexicalLookups(false);1255setHasLazyExternalLexicalLookups(false);1256setUseQualifiedLookup(false);1257}12581259bool DeclContext::classof(const Decl *D) {1260Decl::Kind DK = D->getKind();1261switch (DK) {1262#define DECL(NAME, BASE)1263#define DECL_CONTEXT(NAME) case Decl::NAME:1264#include "clang/AST/DeclNodes.inc"1265return true;1266default:1267return false;1268}1269}12701271DeclContext::~DeclContext() = default;12721273/// Find the parent context of this context that will be1274/// used for unqualified name lookup.1275///1276/// Generally, the parent lookup context is the semantic context. However, for1277/// a friend function the parent lookup context is the lexical context, which1278/// is the class in which the friend is declared.1279DeclContext *DeclContext::getLookupParent() {1280// FIXME: Find a better way to identify friends.1281if (isa<FunctionDecl>(this))1282if (getParent()->getRedeclContext()->isFileContext() &&1283getLexicalParent()->getRedeclContext()->isRecord())1284return getLexicalParent();12851286// A lookup within the call operator of a lambda never looks in the lambda1287// class; instead, skip to the context in which that closure type is1288// declared.1289if (isLambdaCallOperator(this))1290return getParent()->getParent();12911292return getParent();1293}12941295const BlockDecl *DeclContext::getInnermostBlockDecl() const {1296const DeclContext *Ctx = this;12971298do {1299if (Ctx->isClosure())1300return cast<BlockDecl>(Ctx);1301Ctx = Ctx->getParent();1302} while (Ctx);13031304return nullptr;1305}13061307bool DeclContext::isInlineNamespace() const {1308return isNamespace() &&1309cast<NamespaceDecl>(this)->isInline();1310}13111312bool DeclContext::isStdNamespace() const {1313if (!isNamespace())1314return false;13151316const auto *ND = cast<NamespaceDecl>(this);1317if (ND->isInline()) {1318return ND->getParent()->isStdNamespace();1319}13201321if (!getParent()->getRedeclContext()->isTranslationUnit())1322return false;13231324const IdentifierInfo *II = ND->getIdentifier();1325return II && II->isStr("std");1326}13271328bool DeclContext::isDependentContext() const {1329if (isFileContext())1330return false;13311332if (isa<ClassTemplatePartialSpecializationDecl>(this))1333return true;13341335if (const auto *Record = dyn_cast<CXXRecordDecl>(this)) {1336if (Record->getDescribedClassTemplate())1337return true;13381339if (Record->isDependentLambda())1340return true;1341if (Record->isNeverDependentLambda())1342return false;1343}13441345if (const auto *Function = dyn_cast<FunctionDecl>(this)) {1346if (Function->getDescribedFunctionTemplate())1347return true;13481349// Friend function declarations are dependent if their *lexical*1350// context is dependent.1351if (cast<Decl>(this)->getFriendObjectKind())1352return getLexicalParent()->isDependentContext();1353}13541355// FIXME: A variable template is a dependent context, but is not a1356// DeclContext. A context within it (such as a lambda-expression)1357// should be considered dependent.13581359return getParent() && getParent()->isDependentContext();1360}13611362bool DeclContext::isTransparentContext() const {1363if (getDeclKind() == Decl::Enum)1364return !cast<EnumDecl>(this)->isScoped();13651366return isa<LinkageSpecDecl, ExportDecl, HLSLBufferDecl>(this);1367}13681369static bool isLinkageSpecContext(const DeclContext *DC,1370LinkageSpecLanguageIDs ID) {1371while (DC->getDeclKind() != Decl::TranslationUnit) {1372if (DC->getDeclKind() == Decl::LinkageSpec)1373return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;1374DC = DC->getLexicalParent();1375}1376return false;1377}13781379bool DeclContext::isExternCContext() const {1380return isLinkageSpecContext(this, LinkageSpecLanguageIDs::C);1381}13821383const LinkageSpecDecl *DeclContext::getExternCContext() const {1384const DeclContext *DC = this;1385while (DC->getDeclKind() != Decl::TranslationUnit) {1386if (DC->getDeclKind() == Decl::LinkageSpec &&1387cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecLanguageIDs::C)1388return cast<LinkageSpecDecl>(DC);1389DC = DC->getLexicalParent();1390}1391return nullptr;1392}13931394bool DeclContext::isExternCXXContext() const {1395return isLinkageSpecContext(this, LinkageSpecLanguageIDs::CXX);1396}13971398bool DeclContext::Encloses(const DeclContext *DC) const {1399if (getPrimaryContext() != this)1400return getPrimaryContext()->Encloses(DC);14011402for (; DC; DC = DC->getParent())1403if (!isa<LinkageSpecDecl>(DC) && !isa<ExportDecl>(DC) &&1404DC->getPrimaryContext() == this)1405return true;1406return false;1407}14081409DeclContext *DeclContext::getNonTransparentContext() {1410DeclContext *DC = this;1411while (DC->isTransparentContext()) {1412DC = DC->getParent();1413assert(DC && "All transparent contexts should have a parent!");1414}1415return DC;1416}14171418DeclContext *DeclContext::getPrimaryContext() {1419switch (getDeclKind()) {1420case Decl::ExternCContext:1421case Decl::LinkageSpec:1422case Decl::Export:1423case Decl::TopLevelStmt:1424case Decl::Block:1425case Decl::Captured:1426case Decl::OMPDeclareReduction:1427case Decl::OMPDeclareMapper:1428case Decl::RequiresExprBody:1429// There is only one DeclContext for these entities.1430return this;14311432case Decl::HLSLBuffer:1433// Each buffer, even with the same name, is a distinct construct.1434// Multiple buffers with the same name are allowed for backward1435// compatibility.1436// As long as buffers have unique resource bindings the names don't matter.1437// The names get exposed via the CPU-side reflection API which1438// supports querying bindings, so we cannot remove them.1439return this;14401441case Decl::TranslationUnit:1442return static_cast<TranslationUnitDecl *>(this)->getFirstDecl();1443case Decl::Namespace:1444return static_cast<NamespaceDecl *>(this)->getFirstDecl();14451446case Decl::ObjCMethod:1447return this;14481449case Decl::ObjCInterface:1450if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))1451if (auto *Def = OID->getDefinition())1452return Def;1453return this;14541455case Decl::ObjCProtocol:1456if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))1457if (auto *Def = OPD->getDefinition())1458return Def;1459return this;14601461case Decl::ObjCCategory:1462return this;14631464case Decl::ObjCImplementation:1465case Decl::ObjCCategoryImpl:1466return this;14671468default:1469if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {1470// If this is a tag type that has a definition or is currently1471// being defined, that definition is our primary context.1472auto *Tag = cast<TagDecl>(this);14731474if (TagDecl *Def = Tag->getDefinition())1475return Def;14761477if (const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {1478// Note, TagType::getDecl returns the (partial) definition one exists.1479TagDecl *PossiblePartialDef = TagTy->getDecl();1480if (PossiblePartialDef->isBeingDefined())1481return PossiblePartialDef;1482} else {1483assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));1484}14851486return Tag;1487}14881489assert(getDeclKind() >= Decl::firstFunction &&1490getDeclKind() <= Decl::lastFunction &&1491"Unknown DeclContext kind");1492return this;1493}1494}14951496template <typename T>1497void collectAllContextsImpl(T *Self, SmallVectorImpl<DeclContext *> &Contexts) {1498for (T *D = Self->getMostRecentDecl(); D; D = D->getPreviousDecl())1499Contexts.push_back(D);15001501std::reverse(Contexts.begin(), Contexts.end());1502}15031504void DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts) {1505Contexts.clear();15061507Decl::Kind Kind = getDeclKind();15081509if (Kind == Decl::TranslationUnit)1510collectAllContextsImpl(static_cast<TranslationUnitDecl *>(this), Contexts);1511else if (Kind == Decl::Namespace)1512collectAllContextsImpl(static_cast<NamespaceDecl *>(this), Contexts);1513else1514Contexts.push_back(this);1515}15161517std::pair<Decl *, Decl *>1518DeclContext::BuildDeclChain(ArrayRef<Decl *> Decls,1519bool FieldsAlreadyLoaded) {1520// Build up a chain of declarations via the Decl::NextInContextAndBits field.1521Decl *FirstNewDecl = nullptr;1522Decl *PrevDecl = nullptr;1523for (auto *D : Decls) {1524if (FieldsAlreadyLoaded && isa<FieldDecl>(D))1525continue;15261527if (PrevDecl)1528PrevDecl->NextInContextAndBits.setPointer(D);1529else1530FirstNewDecl = D;15311532PrevDecl = D;1533}15341535return std::make_pair(FirstNewDecl, PrevDecl);1536}15371538/// We have just acquired external visible storage, and we already have1539/// built a lookup map. For every name in the map, pull in the new names from1540/// the external storage.1541void DeclContext::reconcileExternalVisibleStorage() const {1542assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);1543setNeedToReconcileExternalVisibleStorage(false);15441545for (auto &Lookup : *LookupPtr)1546Lookup.second.setHasExternalDecls();1547}15481549/// Load the declarations within this lexical storage from an1550/// external source.1551/// \return \c true if any declarations were added.1552bool1553DeclContext::LoadLexicalDeclsFromExternalStorage() const {1554ExternalASTSource *Source = getParentASTContext().getExternalSource();1555assert(hasExternalLexicalStorage() && Source && "No external storage?");15561557// Notify that we have a DeclContext that is initializing.1558ExternalASTSource::Deserializing ADeclContext(Source);15591560// Load the external declarations, if any.1561SmallVector<Decl*, 64> Decls;1562setHasExternalLexicalStorage(false);1563Source->FindExternalLexicalDecls(this, Decls);15641565if (Decls.empty())1566return false;15671568// We may have already loaded just the fields of this record, in which case1569// we need to ignore them.1570bool FieldsAlreadyLoaded = false;1571if (const auto *RD = dyn_cast<RecordDecl>(this))1572FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();15731574// Splice the newly-read declarations into the beginning of the list1575// of declarations.1576Decl *ExternalFirst, *ExternalLast;1577std::tie(ExternalFirst, ExternalLast) =1578BuildDeclChain(Decls, FieldsAlreadyLoaded);1579ExternalLast->NextInContextAndBits.setPointer(FirstDecl);1580FirstDecl = ExternalFirst;1581if (!LastDecl)1582LastDecl = ExternalLast;1583return true;1584}15851586DeclContext::lookup_result1587ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,1588DeclarationName Name) {1589ASTContext &Context = DC->getParentASTContext();1590StoredDeclsMap *Map;1591if (!(Map = DC->LookupPtr))1592Map = DC->CreateStoredDeclsMap(Context);1593if (DC->hasNeedToReconcileExternalVisibleStorage())1594DC->reconcileExternalVisibleStorage();15951596(*Map)[Name].removeExternalDecls();15971598return DeclContext::lookup_result();1599}16001601DeclContext::lookup_result1602ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,1603DeclarationName Name,1604ArrayRef<NamedDecl*> Decls) {1605ASTContext &Context = DC->getParentASTContext();1606StoredDeclsMap *Map;1607if (!(Map = DC->LookupPtr))1608Map = DC->CreateStoredDeclsMap(Context);1609if (DC->hasNeedToReconcileExternalVisibleStorage())1610DC->reconcileExternalVisibleStorage();16111612StoredDeclsList &List = (*Map)[Name];1613List.replaceExternalDecls(Decls);1614return List.getLookupResult();1615}16161617DeclContext::decl_iterator DeclContext::decls_begin() const {1618if (hasExternalLexicalStorage())1619LoadLexicalDeclsFromExternalStorage();1620return decl_iterator(FirstDecl);1621}16221623bool DeclContext::decls_empty() const {1624if (hasExternalLexicalStorage())1625LoadLexicalDeclsFromExternalStorage();16261627return !FirstDecl;1628}16291630bool DeclContext::containsDecl(Decl *D) const {1631return (D->getLexicalDeclContext() == this &&1632(D->NextInContextAndBits.getPointer() || D == LastDecl));1633}16341635bool DeclContext::containsDeclAndLoad(Decl *D) const {1636if (hasExternalLexicalStorage())1637LoadLexicalDeclsFromExternalStorage();1638return containsDecl(D);1639}16401641/// shouldBeHidden - Determine whether a declaration which was declared1642/// within its semantic context should be invisible to qualified name lookup.1643static bool shouldBeHidden(NamedDecl *D) {1644// Skip unnamed declarations.1645if (!D->getDeclName())1646return true;16471648// Skip entities that can't be found by name lookup into a particular1649// context.1650if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||1651D->isTemplateParameter())1652return true;16531654// Skip friends and local extern declarations unless they're the first1655// declaration of the entity.1656if ((D->isLocalExternDecl() || D->getFriendObjectKind()) &&1657D != D->getCanonicalDecl())1658return true;16591660// Skip template specializations.1661// FIXME: This feels like a hack. Should DeclarationName support1662// template-ids, or is there a better way to keep specializations1663// from being visible?1664if (isa<ClassTemplateSpecializationDecl>(D))1665return true;1666if (auto *FD = dyn_cast<FunctionDecl>(D))1667if (FD->isFunctionTemplateSpecialization())1668return true;16691670// Hide destructors that are invalid. There should always be one destructor,1671// but if it is an invalid decl, another one is created. We need to hide the1672// invalid one from places that expect exactly one destructor, like the1673// serialization code.1674if (isa<CXXDestructorDecl>(D) && D->isInvalidDecl())1675return true;16761677return false;1678}16791680void DeclContext::removeDecl(Decl *D) {1681assert(D->getLexicalDeclContext() == this &&1682"decl being removed from non-lexical context");1683assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&1684"decl is not in decls list");16851686// Remove D from the decl chain. This is O(n) but hopefully rare.1687if (D == FirstDecl) {1688if (D == LastDecl)1689FirstDecl = LastDecl = nullptr;1690else1691FirstDecl = D->NextInContextAndBits.getPointer();1692} else {1693for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {1694assert(I && "decl not found in linked list");1695if (I->NextInContextAndBits.getPointer() == D) {1696I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());1697if (D == LastDecl) LastDecl = I;1698break;1699}1700}1701}17021703// Mark that D is no longer in the decl chain.1704D->NextInContextAndBits.setPointer(nullptr);17051706// Remove D from the lookup table if necessary.1707if (isa<NamedDecl>(D)) {1708auto *ND = cast<NamedDecl>(D);17091710// Do not try to remove the declaration if that is invisible to qualified1711// lookup. E.g. template specializations are skipped.1712if (shouldBeHidden(ND))1713return;17141715// Remove only decls that have a name1716if (!ND->getDeclName())1717return;17181719auto *DC = D->getDeclContext();1720do {1721StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr;1722if (Map) {1723StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());1724assert(Pos != Map->end() && "no lookup entry for decl");1725StoredDeclsList &List = Pos->second;1726List.remove(ND);1727// Clean up the entry if there are no more decls.1728if (List.isNull())1729Map->erase(Pos);1730}1731} while (DC->isTransparentContext() && (DC = DC->getParent()));1732}1733}17341735void DeclContext::addHiddenDecl(Decl *D) {1736assert(D->getLexicalDeclContext() == this &&1737"Decl inserted into wrong lexical context");1738assert(!D->getNextDeclInContext() && D != LastDecl &&1739"Decl already inserted into a DeclContext");17401741if (FirstDecl) {1742LastDecl->NextInContextAndBits.setPointer(D);1743LastDecl = D;1744} else {1745FirstDecl = LastDecl = D;1746}17471748// Notify a C++ record declaration that we've added a member, so it can1749// update its class-specific state.1750if (auto *Record = dyn_cast<CXXRecordDecl>(this))1751Record->addedMember(D);17521753// If this is a newly-created (not de-serialized) import declaration, wire1754// it in to the list of local import declarations.1755if (!D->isFromASTFile()) {1756if (auto *Import = dyn_cast<ImportDecl>(D))1757D->getASTContext().addedLocalImportDecl(Import);1758}1759}17601761void DeclContext::addDecl(Decl *D) {1762addHiddenDecl(D);17631764if (auto *ND = dyn_cast<NamedDecl>(D))1765ND->getDeclContext()->getPrimaryContext()->1766makeDeclVisibleInContextWithFlags(ND, false, true);1767}17681769void DeclContext::addDeclInternal(Decl *D) {1770addHiddenDecl(D);17711772if (auto *ND = dyn_cast<NamedDecl>(D))1773ND->getDeclContext()->getPrimaryContext()->1774makeDeclVisibleInContextWithFlags(ND, true, true);1775}17761777/// buildLookup - Build the lookup data structure with all of the1778/// declarations in this DeclContext (and any other contexts linked1779/// to it or transparent contexts nested within it) and return it.1780///1781/// Note that the produced map may miss out declarations from an1782/// external source. If it does, those entries will be marked with1783/// the 'hasExternalDecls' flag.1784StoredDeclsMap *DeclContext::buildLookup() {1785assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");17861787if (!hasLazyLocalLexicalLookups() &&1788!hasLazyExternalLexicalLookups())1789return LookupPtr;17901791SmallVector<DeclContext *, 2> Contexts;1792collectAllContexts(Contexts);17931794if (hasLazyExternalLexicalLookups()) {1795setHasLazyExternalLexicalLookups(false);1796for (auto *DC : Contexts) {1797if (DC->hasExternalLexicalStorage()) {1798bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();1799setHasLazyLocalLexicalLookups(1800hasLazyLocalLexicalLookups() | LoadedDecls );1801}1802}18031804if (!hasLazyLocalLexicalLookups())1805return LookupPtr;1806}18071808for (auto *DC : Contexts)1809buildLookupImpl(DC, hasExternalVisibleStorage());18101811// We no longer have any lazy decls.1812setHasLazyLocalLexicalLookups(false);1813return LookupPtr;1814}18151816/// buildLookupImpl - Build part of the lookup data structure for the1817/// declarations contained within DCtx, which will either be this1818/// DeclContext, a DeclContext linked to it, or a transparent context1819/// nested within it.1820void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) {1821for (auto *D : DCtx->noload_decls()) {1822// Insert this declaration into the lookup structure, but only if1823// it's semantically within its decl context. Any other decls which1824// should be found in this context are added eagerly.1825//1826// If it's from an AST file, don't add it now. It'll get handled by1827// FindExternalVisibleDeclsByName if needed. Exception: if we're not1828// in C++, we do not track external visible decls for the TU, so in1829// that case we need to collect them all here.1830if (auto *ND = dyn_cast<NamedDecl>(D))1831if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&1832(!ND->isFromASTFile() ||1833(isTranslationUnit() &&1834!getParentASTContext().getLangOpts().CPlusPlus)))1835makeDeclVisibleInContextImpl(ND, Internal);18361837// If this declaration is itself a transparent declaration context1838// or inline namespace, add the members of this declaration of that1839// context (recursively).1840if (auto *InnerCtx = dyn_cast<DeclContext>(D))1841if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())1842buildLookupImpl(InnerCtx, Internal);1843}1844}18451846DeclContext::lookup_result1847DeclContext::lookup(DeclarationName Name) const {1848// For transparent DeclContext, we should lookup in their enclosing context.1849if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)1850return getParent()->lookup(Name);18511852const DeclContext *PrimaryContext = getPrimaryContext();1853if (PrimaryContext != this)1854return PrimaryContext->lookup(Name);18551856// If we have an external source, ensure that any later redeclarations of this1857// context have been loaded, since they may add names to the result of this1858// lookup (or add external visible storage).1859ExternalASTSource *Source = getParentASTContext().getExternalSource();1860if (Source)1861(void)cast<Decl>(this)->getMostRecentDecl();18621863if (hasExternalVisibleStorage()) {1864assert(Source && "external visible storage but no external source?");18651866if (hasNeedToReconcileExternalVisibleStorage())1867reconcileExternalVisibleStorage();18681869StoredDeclsMap *Map = LookupPtr;18701871if (hasLazyLocalLexicalLookups() ||1872hasLazyExternalLexicalLookups())1873// FIXME: Make buildLookup const?1874Map = const_cast<DeclContext*>(this)->buildLookup();18751876if (!Map)1877Map = CreateStoredDeclsMap(getParentASTContext());18781879// If we have a lookup result with no external decls, we are done.1880std::pair<StoredDeclsMap::iterator, bool> R =1881Map->insert(std::make_pair(Name, StoredDeclsList()));1882if (!R.second && !R.first->second.hasExternalDecls())1883return R.first->second.getLookupResult();18841885if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {1886if (StoredDeclsMap *Map = LookupPtr) {1887StoredDeclsMap::iterator I = Map->find(Name);1888if (I != Map->end())1889return I->second.getLookupResult();1890}1891}18921893return {};1894}18951896StoredDeclsMap *Map = LookupPtr;1897if (hasLazyLocalLexicalLookups() ||1898hasLazyExternalLexicalLookups())1899Map = const_cast<DeclContext*>(this)->buildLookup();19001901if (!Map)1902return {};19031904StoredDeclsMap::iterator I = Map->find(Name);1905if (I == Map->end())1906return {};19071908return I->second.getLookupResult();1909}19101911DeclContext::lookup_result1912DeclContext::noload_lookup(DeclarationName Name) {1913// For transparent DeclContext, we should lookup in their enclosing context.1914if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)1915return getParent()->noload_lookup(Name);19161917DeclContext *PrimaryContext = getPrimaryContext();1918if (PrimaryContext != this)1919return PrimaryContext->noload_lookup(Name);19201921loadLazyLocalLexicalLookups();1922StoredDeclsMap *Map = LookupPtr;1923if (!Map)1924return {};19251926StoredDeclsMap::iterator I = Map->find(Name);1927return I != Map->end() ? I->second.getLookupResult()1928: lookup_result();1929}19301931// If we have any lazy lexical declarations not in our lookup map, add them1932// now. Don't import any external declarations, not even if we know we have1933// some missing from the external visible lookups.1934void DeclContext::loadLazyLocalLexicalLookups() {1935if (hasLazyLocalLexicalLookups()) {1936SmallVector<DeclContext *, 2> Contexts;1937collectAllContexts(Contexts);1938for (auto *Context : Contexts)1939buildLookupImpl(Context, hasExternalVisibleStorage());1940setHasLazyLocalLexicalLookups(false);1941}1942}19431944void DeclContext::localUncachedLookup(DeclarationName Name,1945SmallVectorImpl<NamedDecl *> &Results) {1946Results.clear();19471948// If there's no external storage, just perform a normal lookup and copy1949// the results.1950if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {1951lookup_result LookupResults = lookup(Name);1952Results.insert(Results.end(), LookupResults.begin(), LookupResults.end());1953if (!Results.empty())1954return;1955}19561957// If we have a lookup table, check there first. Maybe we'll get lucky.1958// FIXME: Should we be checking these flags on the primary context?1959if (Name && !hasLazyLocalLexicalLookups() &&1960!hasLazyExternalLexicalLookups()) {1961if (StoredDeclsMap *Map = LookupPtr) {1962StoredDeclsMap::iterator Pos = Map->find(Name);1963if (Pos != Map->end()) {1964Results.insert(Results.end(),1965Pos->second.getLookupResult().begin(),1966Pos->second.getLookupResult().end());1967return;1968}1969}1970}19711972// Slow case: grovel through the declarations in our chain looking for1973// matches.1974// FIXME: If we have lazy external declarations, this will not find them!1975// FIXME: Should we CollectAllContexts and walk them all here?1976for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {1977if (auto *ND = dyn_cast<NamedDecl>(D))1978if (ND->getDeclName() == Name)1979Results.push_back(ND);1980}1981}19821983DeclContext *DeclContext::getRedeclContext() {1984DeclContext *Ctx = this;19851986// In C, a record type is the redeclaration context for its fields only. If1987// we arrive at a record context after skipping anything else, we should skip1988// the record as well. Currently, this means skipping enumerations because1989// they're the only transparent context that can exist within a struct or1990// union.1991bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&1992!getParentASTContext().getLangOpts().CPlusPlus;19931994// Skip through contexts to get to the redeclaration context. Transparent1995// contexts are always skipped.1996while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())1997Ctx = Ctx->getParent();1998return Ctx;1999}20002001DeclContext *DeclContext::getEnclosingNamespaceContext() {2002DeclContext *Ctx = this;2003// Skip through non-namespace, non-translation-unit contexts.2004while (!Ctx->isFileContext())2005Ctx = Ctx->getParent();2006return Ctx->getPrimaryContext();2007}20082009RecordDecl *DeclContext::getOuterLexicalRecordContext() {2010// Loop until we find a non-record context.2011RecordDecl *OutermostRD = nullptr;2012DeclContext *DC = this;2013while (DC->isRecord()) {2014OutermostRD = cast<RecordDecl>(DC);2015DC = DC->getLexicalParent();2016}2017return OutermostRD;2018}20192020bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const {2021// For non-file contexts, this is equivalent to Equals.2022if (!isFileContext())2023return O->Equals(this);20242025do {2026if (O->Equals(this))2027return true;20282029const auto *NS = dyn_cast<NamespaceDecl>(O);2030if (!NS || !NS->isInline())2031break;2032O = NS->getParent();2033} while (O);20342035return false;2036}20372038void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {2039DeclContext *PrimaryDC = this->getPrimaryContext();2040DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();2041// If the decl is being added outside of its semantic decl context, we2042// need to ensure that we eagerly build the lookup information for it.2043PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);2044}20452046void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,2047bool Recoverable) {2048assert(this == getPrimaryContext() && "expected a primary DC");20492050if (!isLookupContext()) {2051if (isTransparentContext())2052getParent()->getPrimaryContext()2053->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);2054return;2055}20562057// Skip declarations which should be invisible to name lookup.2058if (shouldBeHidden(D))2059return;20602061// If we already have a lookup data structure, perform the insertion into2062// it. If we might have externally-stored decls with this name, look them2063// up and perform the insertion. If this decl was declared outside its2064// semantic context, buildLookup won't add it, so add it now.2065//2066// FIXME: As a performance hack, don't add such decls into the translation2067// unit unless we're in C++, since qualified lookup into the TU is never2068// performed.2069if (LookupPtr || hasExternalVisibleStorage() ||2070((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&2071(getParentASTContext().getLangOpts().CPlusPlus ||2072!isTranslationUnit()))) {2073// If we have lazily omitted any decls, they might have the same name as2074// the decl which we are adding, so build a full lookup table before adding2075// this decl.2076buildLookup();2077makeDeclVisibleInContextImpl(D, Internal);2078} else {2079setHasLazyLocalLexicalLookups(true);2080}20812082// If we are a transparent context or inline namespace, insert into our2083// parent context, too. This operation is recursive.2084if (isTransparentContext() || isInlineNamespace())2085getParent()->getPrimaryContext()->2086makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);20872088auto *DCAsDecl = cast<Decl>(this);2089// Notify that a decl was made visible unless we are a Tag being defined.2090if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))2091if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())2092L->AddedVisibleDecl(this, D);2093}20942095void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {2096// Find or create the stored declaration map.2097StoredDeclsMap *Map = LookupPtr;2098if (!Map) {2099ASTContext *C = &getParentASTContext();2100Map = CreateStoredDeclsMap(*C);2101}21022103// If there is an external AST source, load any declarations it knows about2104// with this declaration's name.2105// If the lookup table contains an entry about this name it means that we2106// have already checked the external source.2107if (!Internal)2108if (ExternalASTSource *Source = getParentASTContext().getExternalSource())2109if (hasExternalVisibleStorage() &&2110Map->find(D->getDeclName()) == Map->end())2111Source->FindExternalVisibleDeclsByName(this, D->getDeclName());21122113// Insert this declaration into the map.2114StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];21152116if (Internal) {2117// If this is being added as part of loading an external declaration,2118// this may not be the only external declaration with this name.2119// In this case, we never try to replace an existing declaration; we'll2120// handle that when we finalize the list of declarations for this name.2121DeclNameEntries.setHasExternalDecls();2122DeclNameEntries.prependDeclNoReplace(D);2123return;2124}21252126DeclNameEntries.addOrReplaceDecl(D);2127}21282129UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const {2130return cast<UsingDirectiveDecl>(*I);2131}21322133/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within2134/// this context.2135DeclContext::udir_range DeclContext::using_directives() const {2136// FIXME: Use something more efficient than normal lookup for using2137// directives. In C++, using directives are looked up more than anything else.2138lookup_result Result = lookup(UsingDirectiveDecl::getName());2139return udir_range(Result.begin(), Result.end());2140}21412142//===----------------------------------------------------------------------===//2143// Creation and Destruction of StoredDeclsMaps. //2144//===----------------------------------------------------------------------===//21452146StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {2147assert(!LookupPtr && "context already has a decls map");2148assert(getPrimaryContext() == this &&2149"creating decls map on non-primary context");21502151StoredDeclsMap *M;2152bool Dependent = isDependentContext();2153if (Dependent)2154M = new DependentStoredDeclsMap();2155else2156M = new StoredDeclsMap();2157M->Previous = C.LastSDM;2158C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);2159LookupPtr = M;2160return M;2161}21622163void ASTContext::ReleaseDeclContextMaps() {2164// It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap2165// pointer because the subclass doesn't add anything that needs to2166// be deleted.2167StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());2168LastSDM.setPointer(nullptr);2169}21702171void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {2172while (Map) {2173// Advance the iteration before we invalidate memory.2174llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;21752176if (Dependent)2177delete static_cast<DependentStoredDeclsMap*>(Map);2178else2179delete Map;21802181Map = Next.getPointer();2182Dependent = Next.getInt();2183}2184}21852186DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,2187DeclContext *Parent,2188const PartialDiagnostic &PDiag) {2189assert(Parent->isDependentContext()2190&& "cannot iterate dependent diagnostics of non-dependent context");2191Parent = Parent->getPrimaryContext();2192if (!Parent->LookupPtr)2193Parent->CreateStoredDeclsMap(C);21942195auto *Map = static_cast<DependentStoredDeclsMap *>(Parent->LookupPtr);21962197// Allocate the copy of the PartialDiagnostic via the ASTContext's2198// BumpPtrAllocator, rather than the ASTContext itself.2199DiagnosticStorage *DiagStorage = nullptr;2200if (PDiag.hasStorage())2201DiagStorage = new (C) DiagnosticStorage;22022203auto *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);22042205// TODO: Maybe we shouldn't reverse the order during insertion.2206DD->NextDiagnostic = Map->FirstDiagnostic;2207Map->FirstDiagnostic = DD;22082209return DD;2210}22112212unsigned DeclIDBase::getLocalDeclIndex() const {2213return ID & llvm::maskTrailingOnes<DeclID>(32);2214}221522162217