2277 lines · cpp
1//===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the Decl and DeclContext classes.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/DeclBase.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/ASTLambda.h"16#include "clang/AST/ASTMutationListener.h"17#include "clang/AST/Attr.h"18#include "clang/AST/AttrIterator.h"19#include "clang/AST/Decl.h"20#include "clang/AST/DeclCXX.h"21#include "clang/AST/DeclContextInternals.h"22#include "clang/AST/DeclFriend.h"23#include "clang/AST/DeclObjC.h"24#include "clang/AST/DeclOpenACC.h"25#include "clang/AST/DeclOpenMP.h"26#include "clang/AST/DeclTemplate.h"27#include "clang/AST/DependentDiagnostic.h"28#include "clang/AST/ExternalASTSource.h"29#include "clang/AST/Stmt.h"30#include "clang/AST/Type.h"31#include "clang/Basic/IdentifierTable.h"32#include "clang/Basic/LLVM.h"33#include "clang/Basic/Module.h"34#include "clang/Basic/ObjCRuntime.h"35#include "clang/Basic/PartialDiagnostic.h"36#include "clang/Basic/SourceLocation.h"37#include "clang/Basic/TargetInfo.h"38#include "llvm/ADT/PointerIntPair.h"39#include "llvm/ADT/StringRef.h"40#include "llvm/Support/ErrorHandling.h"41#include "llvm/Support/MathExtras.h"42#include "llvm/Support/VersionTuple.h"43#include "llvm/Support/raw_ostream.h"44#include <algorithm>45#include <cassert>46#include <cstddef>47#include <string>48#include <tuple>49#include <utility>50 51using namespace clang;52 53//===----------------------------------------------------------------------===//54// Statistics55//===----------------------------------------------------------------------===//56 57#define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;58#define ABSTRACT_DECL(DECL)59#include "clang/AST/DeclNodes.inc"60 61#define DECL(DERIVED, BASE) \62 static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \63 "Alignment sufficient after objects prepended to " #DERIVED);64#define ABSTRACT_DECL(DECL)65#include "clang/AST/DeclNodes.inc"66 67void *Decl::operator new(std::size_t Size, const ASTContext &Context,68 GlobalDeclID ID, std::size_t Extra) {69 // Allocate an extra 8 bytes worth of storage, which ensures that the70 // resulting pointer will still be 8-byte aligned.71 static_assert(sizeof(uint64_t) >= alignof(Decl), "Decl won't be misaligned");72 void *Start = Context.Allocate(Size + Extra + 8);73 void *Result = (char*)Start + 8;74 75 uint64_t *PrefixPtr = (uint64_t *)Result - 1;76 77 *PrefixPtr = ID.getRawValue();78 79 // We leave the upper 16 bits to store the module IDs. 48 bits should be80 // sufficient to store a declaration ID. See the comments in setOwningModuleID81 // for details.82 assert((*PrefixPtr < llvm::maskTrailingOnes<uint64_t>(48)) &&83 "Current Implementation limits the number of module files to not "84 "exceed 2^16. Contact Clang Developers to remove the limitation.");85 86 return Result;87}88 89void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,90 DeclContext *Parent, std::size_t Extra) {91 assert(!Parent || &Parent->getParentASTContext() == &Ctx);92 // With local visibility enabled, we track the owning module even for local93 // declarations. We create the TU decl early and may not yet know what the94 // LangOpts are, so conservatively allocate the storage.95 if (Ctx.getLangOpts().trackLocalOwningModule() || !Parent) {96 // Ensure required alignment of the resulting object by adding extra97 // padding at the start if required.98 size_t ExtraAlign =99 llvm::offsetToAlignment(sizeof(Module *), llvm::Align(alignof(Decl)));100 auto *Buffer = reinterpret_cast<char *>(101 ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));102 Buffer += ExtraAlign;103 auto *ParentModule =104 Parent ? cast<Decl>(Parent)->getOwningModule() : nullptr;105 return new (Buffer) Module*(ParentModule) + 1;106 }107 return ::operator new(Size + Extra, Ctx);108}109 110GlobalDeclID Decl::getGlobalID() const {111 if (!isFromASTFile())112 return GlobalDeclID();113 // See the comments in `Decl::operator new` for details.114 uint64_t ID = *((const uint64_t *)this - 1);115 return GlobalDeclID(ID & llvm::maskTrailingOnes<uint64_t>(48));116}117 118unsigned Decl::getOwningModuleID() const {119 if (!isFromASTFile())120 return 0;121 122 uint64_t ID = *((const uint64_t *)this - 1);123 return ID >> 48;124}125 126void Decl::setOwningModuleID(unsigned ID) {127 assert(isFromASTFile() && "Only works on a deserialized declaration");128 // Currently, we use 64 bits to store the GlobalDeclID and the module ID129 // to save the space. See `Decl::operator new` for details. To make it,130 // we split the higher 32 bits to 2 16bits for the module file index of131 // GlobalDeclID and the module ID. This introduces a limitation that the132 // number of modules can't exceed 2^16. (The number of module files should be133 // less than the number of modules).134 //135 // It is counter-intuitive to store both the module file index and the136 // module ID as it seems redundant. However, this is not true.137 // The module ID may be different from the module file where it is serialized138 // from for implicit template instantiations. See139 // https://github.com/llvm/llvm-project/issues/101939140 //141 // If we reach the limitation, we have to remove the limitation by asking142 // every deserialized declaration to pay for yet another 32 bits, or we have143 // to review the above issue to decide what we should do for it.144 assert((ID < llvm::maskTrailingOnes<unsigned>(16)) &&145 "Current Implementation limits the number of modules to not exceed "146 "2^16. Contact Clang Developers to remove the limitation.");147 uint64_t *IDAddress = (uint64_t *)this - 1;148 *IDAddress &= llvm::maskTrailingOnes<uint64_t>(48);149 *IDAddress |= (uint64_t)ID << 48;150}151 152Module *Decl::getTopLevelOwningNamedModule() const {153 if (getOwningModule() &&154 getOwningModule()->getTopLevelModule()->isNamedModule())155 return getOwningModule()->getTopLevelModule();156 157 return nullptr;158}159 160Module *Decl::getOwningModuleSlow() const {161 assert(isFromASTFile() && "Not from AST file?");162 return getASTContext().getExternalSource()->getModule(getOwningModuleID());163}164 165bool Decl::hasLocalOwningModuleStorage() const {166 return getASTContext().getLangOpts().trackLocalOwningModule();167}168 169const char *Decl::getDeclKindName() const {170 switch (DeclKind) {171 default: llvm_unreachable("Declaration not in DeclNodes.inc!");172#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;173#define ABSTRACT_DECL(DECL)174#include "clang/AST/DeclNodes.inc"175 }176}177 178void Decl::setInvalidDecl(bool Invalid) {179 InvalidDecl = Invalid;180 assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());181 if (!Invalid) {182 return;183 }184 185 if (!isa<ParmVarDecl>(this)) {186 // Defensive maneuver for ill-formed code: we're likely not to make it to187 // a point where we set the access specifier, so default it to "public"188 // to avoid triggering asserts elsewhere in the front end.189 setAccess(AS_public);190 }191 192 // Marking a DecompositionDecl as invalid implies all the child BindingDecl's193 // are invalid too.194 if (auto *DD = dyn_cast<DecompositionDecl>(this)) {195 for (auto *Binding : DD->bindings()) {196 Binding->setInvalidDecl();197 }198 }199}200 201bool DeclContext::hasValidDeclKind() const {202 switch (getDeclKind()) {203#define DECL(DERIVED, BASE) case Decl::DERIVED: return true;204#define ABSTRACT_DECL(DECL)205#include "clang/AST/DeclNodes.inc"206 }207 return false;208}209 210const char *DeclContext::getDeclKindName() const {211 switch (getDeclKind()) {212#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;213#define ABSTRACT_DECL(DECL)214#include "clang/AST/DeclNodes.inc"215 }216 llvm_unreachable("Declaration context not in DeclNodes.inc!");217}218 219bool Decl::StatisticsEnabled = false;220void Decl::EnableStatistics() {221 StatisticsEnabled = true;222}223 224void Decl::PrintStats() {225 llvm::errs() << "\n*** Decl Stats:\n";226 227 int totalDecls = 0;228#define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;229#define ABSTRACT_DECL(DECL)230#include "clang/AST/DeclNodes.inc"231 llvm::errs() << " " << totalDecls << " decls total.\n";232 233 int totalBytes = 0;234#define DECL(DERIVED, BASE) \235 if (n##DERIVED##s > 0) { \236 totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \237 llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \238 << sizeof(DERIVED##Decl) << " each (" \239 << n##DERIVED##s * sizeof(DERIVED##Decl) \240 << " bytes)\n"; \241 }242#define ABSTRACT_DECL(DECL)243#include "clang/AST/DeclNodes.inc"244 245 llvm::errs() << "Total bytes = " << totalBytes << "\n";246}247 248void Decl::add(Kind k) {249 switch (k) {250#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;251#define ABSTRACT_DECL(DECL)252#include "clang/AST/DeclNodes.inc"253 }254}255 256bool Decl::isTemplateParameterPack() const {257 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(this))258 return TTP->isParameterPack();259 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(this))260 return NTTP->isParameterPack();261 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(this))262 return TTP->isParameterPack();263 return false;264}265 266bool Decl::isParameterPack() const {267 if (const auto *Var = dyn_cast<ValueDecl>(this))268 return Var->isParameterPack();269 270 return isTemplateParameterPack();271}272 273FunctionDecl *Decl::getAsFunction() {274 if (auto *FD = dyn_cast<FunctionDecl>(this))275 return FD;276 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(this))277 return FTD->getTemplatedDecl();278 return nullptr;279}280 281bool Decl::isTemplateDecl() const {282 return isa<TemplateDecl>(this);283}284 285TemplateDecl *Decl::getDescribedTemplate() const {286 if (auto *FD = dyn_cast<FunctionDecl>(this))287 return FD->getDescribedFunctionTemplate();288 if (auto *RD = dyn_cast<CXXRecordDecl>(this))289 return RD->getDescribedClassTemplate();290 if (auto *VD = dyn_cast<VarDecl>(this))291 return VD->getDescribedVarTemplate();292 if (auto *AD = dyn_cast<TypeAliasDecl>(this))293 return AD->getDescribedAliasTemplate();294 295 return nullptr;296}297 298const TemplateParameterList *Decl::getDescribedTemplateParams() const {299 if (auto *TD = getDescribedTemplate())300 return TD->getTemplateParameters();301 if (auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(this))302 return CTPSD->getTemplateParameters();303 if (auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(this))304 return VTPSD->getTemplateParameters();305 return nullptr;306}307 308bool Decl::isTemplated() const {309 // A declaration is templated if it is a template or a template pattern, or310 // is within (lexcially for a friend or local function declaration,311 // semantically otherwise) a dependent context.312 if (auto *AsDC = dyn_cast<DeclContext>(this))313 return AsDC->isDependentContext();314 auto *DC = getFriendObjectKind() || isLocalExternDecl()315 ? getLexicalDeclContext() : getDeclContext();316 return DC->isDependentContext() || isTemplateDecl() ||317 getDescribedTemplateParams();318}319 320unsigned Decl::getTemplateDepth() const {321 if (auto *DC = dyn_cast<DeclContext>(this))322 if (DC->isFileContext())323 return 0;324 325 if (auto *TPL = getDescribedTemplateParams())326 return TPL->getDepth() + 1;327 328 // If this is a dependent lambda, there might be an enclosing variable329 // template. In this case, the next step is not the parent DeclContext (or330 // even a DeclContext at all).331 auto *RD = dyn_cast<CXXRecordDecl>(this);332 if (RD && RD->isDependentLambda())333 if (Decl *Context = RD->getLambdaContextDecl())334 return Context->getTemplateDepth();335 336 const DeclContext *DC =337 getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();338 return cast<Decl>(DC)->getTemplateDepth();339}340 341const DeclContext *Decl::getParentFunctionOrMethod(bool LexicalParent) const {342 for (const DeclContext *DC = LexicalParent ? getLexicalDeclContext()343 : getDeclContext();344 DC && !DC->isFileContext(); DC = DC->getParent())345 if (DC->isFunctionOrMethod())346 return DC;347 348 return nullptr;349}350 351//===----------------------------------------------------------------------===//352// PrettyStackTraceDecl Implementation353//===----------------------------------------------------------------------===//354 355void PrettyStackTraceDecl::print(raw_ostream &OS) const {356 SourceLocation TheLoc = Loc;357 if (TheLoc.isInvalid() && TheDecl)358 TheLoc = TheDecl->getLocation();359 360 if (TheLoc.isValid()) {361 TheLoc.print(OS, SM);362 OS << ": ";363 }364 365 OS << Message;366 367 if (const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {368 OS << " '";369 DN->printQualifiedName(OS);370 OS << '\'';371 }372 OS << '\n';373}374 375//===----------------------------------------------------------------------===//376// Decl Implementation377//===----------------------------------------------------------------------===//378 379// Out-of-line virtual method providing a home for Decl.380Decl::~Decl() = default;381 382void Decl::setDeclContext(DeclContext *DC) {383 DeclCtx = DC;384}385 386void Decl::setLexicalDeclContext(DeclContext *DC) {387 if (DC == getLexicalDeclContext())388 return;389 390 if (isInSemaDC()) {391 setDeclContextsImpl(getDeclContext(), DC, getASTContext());392 } else {393 getMultipleDC()->LexicalDC = DC;394 }395 396 // FIXME: We shouldn't be changing the lexical context of declarations397 // imported from AST files.398 if (!isFromASTFile()) {399 setModuleOwnershipKind(getModuleOwnershipKindForChildOf(DC));400 if (hasOwningModule())401 setLocalOwningModule(cast<Decl>(DC)->getOwningModule());402 }403 404 assert(405 (getModuleOwnershipKind() != ModuleOwnershipKind::VisibleWhenImported ||406 getOwningModule()) &&407 "hidden declaration has no owning module");408}409 410void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,411 ASTContext &Ctx) {412 if (SemaDC == LexicalDC) {413 DeclCtx = SemaDC;414 } else {415 auto *MDC = new (Ctx) Decl::MultipleDC();416 MDC->SemanticDC = SemaDC;417 MDC->LexicalDC = LexicalDC;418 DeclCtx = MDC;419 }420}421 422bool Decl::isInLocalScopeForInstantiation() const {423 const DeclContext *LDC = getLexicalDeclContext();424 if (!LDC->isDependentContext())425 return false;426 while (true) {427 if (LDC->isFunctionOrMethod())428 return true;429 if (!isa<TagDecl>(LDC))430 return false;431 if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))432 if (CRD->isLambda())433 return true;434 LDC = LDC->getLexicalParent();435 }436 return false;437}438 439bool Decl::isInAnonymousNamespace() const {440 for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {441 if (const auto *ND = dyn_cast<NamespaceDecl>(DC))442 if (ND->isAnonymousNamespace())443 return true;444 }445 446 return false;447}448 449bool Decl::isInStdNamespace() const {450 const DeclContext *DC = getDeclContext();451 return DC && DC->getNonTransparentContext()->isStdNamespace();452}453 454bool Decl::isFileContextDecl() const {455 const auto *DC = dyn_cast<DeclContext>(this);456 return DC && DC->isFileContext();457}458 459bool Decl::isFlexibleArrayMemberLike(460 const ASTContext &Ctx, const Decl *D, QualType Ty,461 LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,462 bool IgnoreTemplateOrMacroSubstitution) {463 // For compatibility with existing code, we treat arrays of length 0 or464 // 1 as flexible array members.465 const auto *CAT = Ctx.getAsConstantArrayType(Ty);466 if (CAT) {467 using FAMKind = LangOptions::StrictFlexArraysLevelKind;468 469 llvm::APInt Size = CAT->getSize();470 if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)471 return false;472 473 // GCC extension, only allowed to represent a FAM.474 if (Size.isZero())475 return true;476 477 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))478 return false;479 480 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))481 return false;482 } else if (!Ctx.getAsIncompleteArrayType(Ty)) {483 return false;484 }485 486 if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D))487 return OID->getNextIvar() == nullptr;488 489 const auto *FD = dyn_cast_if_present<FieldDecl>(D);490 if (!FD)491 return false;492 493 if (CAT) {494 // GCC treats an array memeber of a union as an FAM if the size is one or495 // zero.496 llvm::APInt Size = CAT->getSize();497 if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))498 return true;499 }500 501 // Don't consider sizes resulting from macro expansions or template argument502 // substitution to form C89 tail-padded arrays.503 if (IgnoreTemplateOrMacroSubstitution) {504 TypeSourceInfo *TInfo = FD->getTypeSourceInfo();505 while (TInfo) {506 TypeLoc TL = TInfo->getTypeLoc();507 508 // Look through typedefs.509 if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {510 TInfo = TTL.getDecl()->getTypeSourceInfo();511 continue;512 }513 514 if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) {515 if (const Expr *SizeExpr =516 dyn_cast_if_present<IntegerLiteral>(CTL.getSizeExpr());517 !SizeExpr || SizeExpr->getExprLoc().isMacroID())518 return false;519 }520 521 break;522 }523 }524 525 // Test that the field is the last in the structure.526 RecordDecl::field_iterator FI(527 DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));528 return ++FI == FD->getParent()->field_end();529}530 531TranslationUnitDecl *Decl::getTranslationUnitDecl() {532 if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))533 return TUD;534 535 DeclContext *DC = getDeclContext();536 assert(DC && "This decl is not contained in a translation unit!");537 538 while (!DC->isTranslationUnit()) {539 DC = DC->getParent();540 assert(DC && "This decl is not contained in a translation unit!");541 }542 543 return cast<TranslationUnitDecl>(DC);544}545 546ASTContext &Decl::getASTContext() const {547 return getTranslationUnitDecl()->getASTContext();548}549 550/// Helper to get the language options from the ASTContext.551/// Defined out of line to avoid depending on ASTContext.h.552const LangOptions &Decl::getLangOpts() const {553 return getASTContext().getLangOpts();554}555 556ASTMutationListener *Decl::getASTMutationListener() const {557 return getASTContext().getASTMutationListener();558}559 560unsigned Decl::getMaxAlignment() const {561 if (!hasAttrs())562 return 0;563 564 unsigned Align = 0;565 const AttrVec &V = getAttrs();566 ASTContext &Ctx = getASTContext();567 specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());568 for (; I != E; ++I) {569 if (!I->isAlignmentErrorDependent())570 Align = std::max(Align, I->getAlignment(Ctx));571 }572 return Align;573}574 575bool Decl::isUsed(bool CheckUsedAttr) const {576 const Decl *CanonD = getCanonicalDecl();577 if (CanonD->Used)578 return true;579 580 // Check for used attribute.581 // Ask the most recent decl, since attributes accumulate in the redecl chain.582 if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>())583 return true;584 585 // The information may have not been deserialized yet. Force deserialization586 // to complete the needed information.587 return getMostRecentDecl()->getCanonicalDecl()->Used;588}589 590void Decl::markUsed(ASTContext &C) {591 if (isUsed(false))592 return;593 594 if (C.getASTMutationListener())595 C.getASTMutationListener()->DeclarationMarkedUsed(this);596 597 setIsUsed();598}599 600bool Decl::isReferenced() const {601 if (Referenced)602 return true;603 604 // Check redeclarations.605 for (const auto *I : redecls())606 if (I->Referenced)607 return true;608 609 return false;610}611 612ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {613 const Decl *Definition = nullptr;614 if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {615 Definition = ID->getDefinition();616 } else if (auto *PD = dyn_cast<ObjCProtocolDecl>(this)) {617 Definition = PD->getDefinition();618 } else if (auto *TD = dyn_cast<TagDecl>(this)) {619 Definition = TD->getDefinition();620 }621 if (!Definition)622 Definition = this;623 624 if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())625 return attr;626 if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {627 return dcd->getAttr<ExternalSourceSymbolAttr>();628 }629 630 return nullptr;631}632 633bool Decl::hasDefiningAttr() const {634 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||635 hasAttr<LoaderUninitializedAttr>();636}637 638const Attr *Decl::getDefiningAttr() const {639 if (auto *AA = getAttr<AliasAttr>())640 return AA;641 if (auto *IFA = getAttr<IFuncAttr>())642 return IFA;643 if (auto *NZA = getAttr<LoaderUninitializedAttr>())644 return NZA;645 return nullptr;646}647 648static StringRef getRealizedPlatform(const AvailabilityAttr *A,649 const ASTContext &Context) {650 // Check if this is an App Extension "platform", and if so chop off651 // the suffix for matching with the actual platform.652 StringRef RealizedPlatform = A->getPlatform()->getName();653 if (!Context.getLangOpts().AppExt)654 return RealizedPlatform;655 size_t suffix = RealizedPlatform.rfind("_app_extension");656 if (suffix != StringRef::npos)657 return RealizedPlatform.slice(0, suffix);658 return RealizedPlatform;659}660 661/// Determine the availability of the given declaration based on662/// the target platform.663///664/// When it returns an availability result other than \c AR_Available,665/// if the \p Message parameter is non-NULL, it will be set to a666/// string describing why the entity is unavailable.667///668/// FIXME: Make these strings localizable, since they end up in669/// diagnostics.670static AvailabilityResult CheckAvailability(ASTContext &Context,671 const AvailabilityAttr *A,672 std::string *Message,673 VersionTuple EnclosingVersion) {674 if (EnclosingVersion.empty())675 EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();676 677 if (EnclosingVersion.empty())678 return AR_Available;679 680 StringRef ActualPlatform = A->getPlatform()->getName();681 StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();682 683 // Match the platform name.684 if (getRealizedPlatform(A, Context) != TargetPlatform)685 return AR_Available;686 687 StringRef PrettyPlatformName688 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);689 690 if (PrettyPlatformName.empty())691 PrettyPlatformName = ActualPlatform;692 693 std::string HintMessage;694 if (!A->getMessage().empty()) {695 HintMessage = " - ";696 HintMessage += A->getMessage();697 }698 699 // Make sure that this declaration has not been marked 'unavailable'.700 if (A->getUnavailable()) {701 if (Message) {702 Message->clear();703 llvm::raw_string_ostream Out(*Message);704 Out << "not available on " << PrettyPlatformName705 << HintMessage;706 }707 708 return AR_Unavailable;709 }710 711 // Make sure that this declaration has already been introduced.712 if (!A->getIntroduced().empty() &&713 EnclosingVersion < A->getIntroduced()) {714 IdentifierInfo *IIEnv = A->getEnvironment();715 auto &Triple = Context.getTargetInfo().getTriple();716 StringRef TargetEnv = Triple.getEnvironmentName();717 StringRef EnvName =718 llvm::Triple::getEnvironmentTypeName(Triple.getEnvironment());719 // Matching environment or no environment on attribute.720 if (!IIEnv || (Triple.hasEnvironment() && IIEnv->getName() == TargetEnv)) {721 if (Message) {722 Message->clear();723 llvm::raw_string_ostream Out(*Message);724 VersionTuple VTI(A->getIntroduced());725 Out << "introduced in " << PrettyPlatformName << " " << VTI;726 if (Triple.hasEnvironment())727 Out << " " << EnvName;728 Out << HintMessage;729 }730 }731 // Non-matching environment or no environment on target.732 else {733 if (Message) {734 Message->clear();735 llvm::raw_string_ostream Out(*Message);736 Out << "not available on " << PrettyPlatformName;737 if (Triple.hasEnvironment())738 Out << " " << EnvName;739 Out << HintMessage;740 }741 }742 743 return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced;744 }745 746 // Make sure that this declaration hasn't been obsoleted.747 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {748 if (Message) {749 Message->clear();750 llvm::raw_string_ostream Out(*Message);751 VersionTuple VTO(A->getObsoleted());752 Out << "obsoleted in " << PrettyPlatformName << ' '753 << VTO << HintMessage;754 }755 756 return AR_Unavailable;757 }758 759 // Make sure that this declaration hasn't been deprecated.760 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {761 if (Message) {762 Message->clear();763 llvm::raw_string_ostream Out(*Message);764 VersionTuple VTD(A->getDeprecated());765 Out << "first deprecated in " << PrettyPlatformName << ' '766 << VTD << HintMessage;767 }768 769 return AR_Deprecated;770 }771 772 return AR_Available;773}774 775AvailabilityResult Decl::getAvailability(std::string *Message,776 VersionTuple EnclosingVersion,777 StringRef *RealizedPlatform) const {778 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))779 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,780 RealizedPlatform);781 782 AvailabilityResult Result = AR_Available;783 std::string ResultMessage;784 785 for (const auto *A : attrs()) {786 if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {787 if (Result >= AR_Deprecated)788 continue;789 790 if (Message)791 ResultMessage = std::string(Deprecated->getMessage());792 793 Result = AR_Deprecated;794 continue;795 }796 797 if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {798 if (Message)799 *Message = std::string(Unavailable->getMessage());800 return AR_Unavailable;801 }802 803 if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {804 AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,805 Message, EnclosingVersion);806 807 if (AR == AR_Unavailable) {808 if (RealizedPlatform)809 *RealizedPlatform = Availability->getPlatform()->getName();810 return AR_Unavailable;811 }812 813 if (AR > Result) {814 Result = AR;815 if (Message)816 ResultMessage.swap(*Message);817 }818 continue;819 }820 }821 822 if (Message)823 Message->swap(ResultMessage);824 return Result;825}826 827VersionTuple Decl::getVersionIntroduced() const {828 const ASTContext &Context = getASTContext();829 StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();830 for (const auto *A : attrs()) {831 if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {832 if (getRealizedPlatform(Availability, Context) != TargetPlatform)833 continue;834 if (!Availability->getIntroduced().empty())835 return Availability->getIntroduced();836 }837 }838 return {};839}840 841bool Decl::canBeWeakImported(bool &IsDefinition) const {842 IsDefinition = false;843 844 // Variables, if they aren't definitions.845 if (const auto *Var = dyn_cast<VarDecl>(this)) {846 if (Var->isThisDeclarationADefinition()) {847 IsDefinition = true;848 return false;849 }850 return true;851 }852 // Functions, if they aren't definitions.853 if (const auto *FD = dyn_cast<FunctionDecl>(this)) {854 if (FD->hasBody()) {855 IsDefinition = true;856 return false;857 }858 return true;859 860 }861 // Objective-C classes, if this is the non-fragile runtime.862 if (isa<ObjCInterfaceDecl>(this) &&863 getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {864 return true;865 }866 // Nothing else.867 return false;868}869 870bool Decl::isWeakImported() const {871 bool IsDefinition;872 if (!canBeWeakImported(IsDefinition))873 return false;874 875 for (const auto *A : getMostRecentDecl()->attrs()) {876 if (isa<WeakImportAttr>(A))877 return true;878 879 if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {880 if (CheckAvailability(getASTContext(), Availability, nullptr,881 VersionTuple()) == AR_NotYetIntroduced)882 return true;883 }884 }885 886 return false;887}888 889unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {890 switch (DeclKind) {891 case Function:892 case CXXDeductionGuide:893 case CXXMethod:894 case CXXConstructor:895 case ConstructorUsingShadow:896 case CXXDestructor:897 case CXXConversion:898 case EnumConstant:899 case Var:900 case ImplicitParam:901 case ParmVar:902 case ObjCMethod:903 case ObjCProperty:904 case MSProperty:905 case HLSLBuffer:906 case HLSLRootSignature:907 return IDNS_Ordinary;908 case Label:909 return IDNS_Label;910 911 case Binding:912 case NonTypeTemplateParm:913 case VarTemplate:914 case Concept:915 // These (C++-only) declarations are found by redeclaration lookup for916 // tag types, so we include them in the tag namespace.917 return IDNS_Ordinary | IDNS_Tag;918 919 case ObjCCompatibleAlias:920 case ObjCInterface:921 return IDNS_Ordinary | IDNS_Type;922 923 case Typedef:924 case TypeAlias:925 case TemplateTypeParm:926 case ObjCTypeParam:927 return IDNS_Ordinary | IDNS_Type;928 929 case UnresolvedUsingTypename:930 return IDNS_Ordinary | IDNS_Type | IDNS_Using;931 932 case UsingShadow:933 return 0; // we'll actually overwrite this later934 935 case UnresolvedUsingValue:936 return IDNS_Ordinary | IDNS_Using;937 938 case Using:939 case UsingPack:940 case UsingEnum:941 return IDNS_Using;942 943 case ObjCProtocol:944 return IDNS_ObjCProtocol;945 946 case Field:947 case IndirectField:948 case ObjCAtDefsField:949 case ObjCIvar:950 return IDNS_Member;951 952 case Record:953 case CXXRecord:954 case Enum:955 return IDNS_Tag | IDNS_Type;956 957 case Namespace:958 case NamespaceAlias:959 return IDNS_Namespace;960 961 case FunctionTemplate:962 return IDNS_Ordinary;963 964 case ClassTemplate:965 case TemplateTemplateParm:966 case TypeAliasTemplate:967 return IDNS_Ordinary | IDNS_Tag | IDNS_Type;968 969 case UnresolvedUsingIfExists:970 return IDNS_Type | IDNS_Ordinary;971 972 case OMPDeclareReduction:973 return IDNS_OMPReduction;974 975 case OMPDeclareMapper:976 return IDNS_OMPMapper;977 978 // Never have names.979 case Friend:980 case FriendTemplate:981 case AccessSpec:982 case LinkageSpec:983 case Export:984 case FileScopeAsm:985 case TopLevelStmt:986 case StaticAssert:987 case ObjCPropertyImpl:988 case PragmaComment:989 case PragmaDetectMismatch:990 case Block:991 case Captured:992 case OutlinedFunction:993 case TranslationUnit:994 case ExternCContext:995 case Decomposition:996 case MSGuid:997 case UnnamedGlobalConstant:998 case TemplateParamObject:999 1000 case UsingDirective:1001 case BuiltinTemplate:1002 case ClassTemplateSpecialization:1003 case ClassTemplatePartialSpecialization:1004 case VarTemplateSpecialization:1005 case VarTemplatePartialSpecialization:1006 case ObjCImplementation:1007 case ObjCCategory:1008 case ObjCCategoryImpl:1009 case Import:1010 case OMPThreadPrivate:1011 case OMPGroupPrivate:1012 case OMPAllocate:1013 case OMPRequires:1014 case OMPCapturedExpr:1015 case Empty:1016 case LifetimeExtendedTemporary:1017 case RequiresExprBody:1018 case ImplicitConceptSpecialization:1019 case OpenACCDeclare:1020 case OpenACCRoutine:1021 // Never looked up by name.1022 return 0;1023 }1024 1025 llvm_unreachable("Invalid DeclKind!");1026}1027 1028void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {1029 assert(!HasAttrs && "Decl already contains attrs.");1030 1031 AttrVec &AttrBlank = Ctx.getDeclAttrs(this);1032 assert(AttrBlank.empty() && "HasAttrs was wrong?");1033 1034 AttrBlank = attrs;1035 HasAttrs = true;1036}1037 1038void Decl::dropAttrs() {1039 if (!HasAttrs) return;1040 1041 HasAttrs = false;1042 getASTContext().eraseDeclAttrs(this);1043}1044 1045void Decl::addAttr(Attr *A) {1046 if (!hasAttrs()) {1047 setAttrs(AttrVec(1, A));1048 return;1049 }1050 1051 AttrVec &Attrs = getAttrs();1052 if (!A->isInherited()) {1053 Attrs.push_back(A);1054 return;1055 }1056 1057 // Attribute inheritance is processed after attribute parsing. To keep the1058 // order as in the source code, add inherited attributes before non-inherited1059 // ones.1060 auto I = Attrs.begin(), E = Attrs.end();1061 for (; I != E; ++I) {1062 if (!(*I)->isInherited())1063 break;1064 }1065 Attrs.insert(I, A);1066}1067 1068const AttrVec &Decl::getAttrs() const {1069 assert(HasAttrs && "No attrs to get!");1070 return getASTContext().getDeclAttrs(this);1071}1072 1073Decl *Decl::castFromDeclContext (const DeclContext *D) {1074 Decl::Kind DK = D->getDeclKind();1075 switch (DK) {1076#define DECL(NAME, BASE)1077#define DECL_CONTEXT(NAME) \1078 case Decl::NAME: \1079 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));1080#include "clang/AST/DeclNodes.inc"1081 default:1082 llvm_unreachable("a decl that inherits DeclContext isn't handled");1083 }1084}1085 1086DeclContext *Decl::castToDeclContext(const Decl *D) {1087 Decl::Kind DK = D->getKind();1088 switch(DK) {1089#define DECL(NAME, BASE)1090#define DECL_CONTEXT(NAME) \1091 case Decl::NAME: \1092 return static_cast<NAME##Decl *>(const_cast<Decl *>(D));1093#include "clang/AST/DeclNodes.inc"1094 default:1095 llvm_unreachable("a decl that inherits DeclContext isn't handled");1096 }1097}1098 1099SourceLocation Decl::getBodyRBrace() const {1100 // Special handling of FunctionDecl to avoid de-serializing the body from PCH.1101 // FunctionDecl stores EndRangeLoc for this purpose.1102 if (const auto *FD = dyn_cast<FunctionDecl>(this)) {1103 const FunctionDecl *Definition;1104 if (FD->hasBody(Definition))1105 return Definition->getSourceRange().getEnd();1106 return {};1107 }1108 1109 if (Stmt *Body = getBody())1110 return Body->getSourceRange().getEnd();1111 1112 return {};1113}1114 1115bool Decl::AccessDeclContextCheck() const {1116#ifndef NDEBUG1117 // Suppress this check if any of the following hold:1118 // 1. this is the translation unit (and thus has no parent)1119 // 2. this is a template parameter (and thus doesn't belong to its context)1120 // 3. this is a non-type template parameter1121 // 4. the context is not a record1122 // 5. it's invalid1123 // 6. it's a C++0x static_assert.1124 // 7. it's a block literal declaration1125 // 8. it's a temporary with lifetime extended due to being default value.1126 if (isa<TranslationUnitDecl>(this) || isa<TemplateTypeParmDecl>(this) ||1127 isa<NonTypeTemplateParmDecl>(this) || !getDeclContext() ||1128 !isa<CXXRecordDecl>(getDeclContext()) || isInvalidDecl() ||1129 isa<StaticAssertDecl>(this) || isa<BlockDecl>(this) ||1130 // FIXME: a ParmVarDecl can have ClassTemplateSpecialization1131 // as DeclContext (?).1132 isa<ParmVarDecl>(this) ||1133 // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have1134 // AS_none as access specifier.1135 isa<CXXRecordDecl>(this) || isa<LifetimeExtendedTemporaryDecl>(this))1136 return true;1137 1138 assert(Access != AS_none &&1139 "Access specifier is AS_none inside a record decl");1140#endif1141 return true;1142}1143 1144bool Decl::isInExportDeclContext() const {1145 const DeclContext *DC = getLexicalDeclContext();1146 1147 while (DC && !isa<ExportDecl>(DC))1148 DC = DC->getLexicalParent();1149 1150 return isa_and_nonnull<ExportDecl>(DC);1151}1152 1153bool Decl::isModuleLocal() const {1154 if (isa<NamespaceDecl, TranslationUnitDecl>(this))1155 return false;1156 auto *M = getOwningModule();1157 return M && M->isNamedModule() &&1158 getModuleOwnershipKind() == ModuleOwnershipKind::ReachableWhenImported;1159}1160 1161bool Decl::isInAnotherModuleUnit() const {1162 auto *M = getOwningModule();1163 1164 if (!M)1165 return false;1166 1167 // FIXME or NOTE: maybe we need to be clear about the semantics1168 // of clang header modules. e.g., if this lives in a clang header1169 // module included by the current unit, should we return false1170 // here?1171 //1172 // This is clear for header units as the specification says the1173 // header units live in a synthesised translation unit. So we1174 // can return false here.1175 M = M->getTopLevelModule();1176 if (!M->isNamedModule())1177 return false;1178 1179 return M != getASTContext().getCurrentNamedModule();1180}1181 1182bool Decl::isInCurrentModuleUnit() const {1183 auto *M = getOwningModule();1184 1185 if (!M || !M->isNamedModule())1186 return false;1187 1188 return M == getASTContext().getCurrentNamedModule();1189}1190 1191bool Decl::shouldEmitInExternalSource() const {1192 ExternalASTSource *Source = getASTContext().getExternalSource();1193 if (!Source)1194 return false;1195 1196 return Source->hasExternalDefinitions(this) == ExternalASTSource::EK_Always;1197}1198 1199bool Decl::isFromExplicitGlobalModule() const {1200 return getOwningModule() && getOwningModule()->isExplicitGlobalModule();1201}1202 1203bool Decl::isFromGlobalModule() const {1204 return getOwningModule() && getOwningModule()->isGlobalModule();1205}1206 1207bool Decl::isInNamedModule() const {1208 return getOwningModule() && getOwningModule()->isNamedModule();1209}1210 1211bool Decl::isFromHeaderUnit() const {1212 return getOwningModule() && getOwningModule()->isHeaderUnit();1213}1214 1215static Decl::Kind getKind(const Decl *D) { return D->getKind(); }1216static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }1217 1218int64_t Decl::getID() const {1219 return getASTContext().getAllocator().identifyKnownAlignedObject<Decl>(this);1220}1221 1222const FunctionType *Decl::getFunctionType(bool BlocksToo) const {1223 QualType Ty;1224 if (const auto *D = dyn_cast<ValueDecl>(this))1225 Ty = D->getType();1226 else if (const auto *D = dyn_cast<TypedefNameDecl>(this))1227 Ty = D->getUnderlyingType();1228 else1229 return nullptr;1230 1231 if (Ty.isNull()) {1232 // BindingDecls do not have types during parsing, so return nullptr. This is1233 // the only known case where `Ty` is null.1234 assert(isa<BindingDecl>(this));1235 return nullptr;1236 }1237 1238 if (Ty->isFunctionPointerType())1239 Ty = Ty->castAs<PointerType>()->getPointeeType();1240 else if (Ty->isMemberFunctionPointerType())1241 Ty = Ty->castAs<MemberPointerType>()->getPointeeType();1242 else if (Ty->isFunctionReferenceType())1243 Ty = Ty->castAs<ReferenceType>()->getPointeeType();1244 else if (BlocksToo && Ty->isBlockPointerType())1245 Ty = Ty->castAs<BlockPointerType>()->getPointeeType();1246 1247 return Ty->getAs<FunctionType>();1248}1249 1250bool Decl::isFunctionPointerType() const {1251 QualType Ty;1252 if (const auto *D = dyn_cast<ValueDecl>(this))1253 Ty = D->getType();1254 else if (const auto *D = dyn_cast<TypedefNameDecl>(this))1255 Ty = D->getUnderlyingType();1256 else1257 return false;1258 1259 return Ty.getCanonicalType()->isFunctionPointerType();1260}1261 1262DeclContext *Decl::getNonTransparentDeclContext() {1263 assert(getDeclContext());1264 return getDeclContext()->getNonTransparentContext();1265}1266 1267/// Starting at a given context (a Decl or DeclContext), look for a1268/// code context that is not a closure (a lambda, block, etc.).1269template <class T> static Decl *getNonClosureContext(T *D) {1270 if (getKind(D) == Decl::CXXMethod) {1271 auto *MD = cast<CXXMethodDecl>(D);1272 if (MD->getOverloadedOperator() == OO_Call &&1273 MD->getParent()->isLambda())1274 return getNonClosureContext(MD->getParent()->getParent());1275 return MD;1276 }1277 if (auto *FD = dyn_cast<FunctionDecl>(D))1278 return FD;1279 if (auto *MD = dyn_cast<ObjCMethodDecl>(D))1280 return MD;1281 if (auto *BD = dyn_cast<BlockDecl>(D))1282 return getNonClosureContext(BD->getParent());1283 if (auto *CD = dyn_cast<CapturedDecl>(D))1284 return getNonClosureContext(CD->getParent());1285 if (auto *OFD = dyn_cast<OutlinedFunctionDecl>(D))1286 return getNonClosureContext(OFD->getParent());1287 return nullptr;1288}1289 1290Decl *Decl::getNonClosureContext() {1291 return ::getNonClosureContext(this);1292}1293 1294Decl *DeclContext::getNonClosureAncestor() {1295 return ::getNonClosureContext(this);1296}1297 1298//===----------------------------------------------------------------------===//1299// DeclContext Implementation1300//===----------------------------------------------------------------------===//1301 1302DeclContext::DeclContext(Decl::Kind K) {1303 DeclContextBits.DeclKind = K;1304 setHasExternalLexicalStorage(false);1305 setHasExternalVisibleStorage(false);1306 setNeedToReconcileExternalVisibleStorage(false);1307 setHasLazyLocalLexicalLookups(false);1308 setHasLazyExternalLexicalLookups(false);1309 setUseQualifiedLookup(false);1310}1311 1312bool DeclContext::classof(const Decl *D) {1313 Decl::Kind DK = D->getKind();1314 switch (DK) {1315#define DECL(NAME, BASE)1316#define DECL_CONTEXT(NAME) case Decl::NAME:1317#include "clang/AST/DeclNodes.inc"1318 return true;1319 default:1320 return false;1321 }1322}1323 1324DeclContext::~DeclContext() = default;1325 1326/// Find the parent context of this context that will be1327/// used for unqualified name lookup.1328///1329/// Generally, the parent lookup context is the semantic context. However, for1330/// a friend function the parent lookup context is the lexical context, which1331/// is the class in which the friend is declared.1332DeclContext *DeclContext::getLookupParent() {1333 // FIXME: Find a better way to identify friends.1334 if (isa<FunctionDecl>(this))1335 if (getParent()->getRedeclContext()->isFileContext() &&1336 getLexicalParent()->getRedeclContext()->isRecord())1337 return getLexicalParent();1338 1339 // A lookup within the call operator of a lambda never looks in the lambda1340 // class; instead, skip to the context in which that closure type is1341 // declared.1342 if (isLambdaCallOperator(this))1343 return getParent()->getParent();1344 1345 return getParent();1346}1347 1348const BlockDecl *DeclContext::getInnermostBlockDecl() const {1349 const DeclContext *Ctx = this;1350 1351 do {1352 if (Ctx->isClosure())1353 return cast<BlockDecl>(Ctx);1354 Ctx = Ctx->getParent();1355 } while (Ctx);1356 1357 return nullptr;1358}1359 1360bool DeclContext::isInlineNamespace() const {1361 return isNamespace() &&1362 cast<NamespaceDecl>(this)->isInline();1363}1364 1365bool DeclContext::isStdNamespace() const {1366 if (!isNamespace())1367 return false;1368 1369 const auto *ND = cast<NamespaceDecl>(this);1370 if (ND->isInline()) {1371 return ND->getParent()->isStdNamespace();1372 }1373 1374 if (!getParent()->getRedeclContext()->isTranslationUnit())1375 return false;1376 1377 const IdentifierInfo *II = ND->getIdentifier();1378 return II && II->isStr("std");1379}1380 1381bool DeclContext::isDependentContext() const {1382 if (isFileContext())1383 return false;1384 1385 if (isa<ClassTemplatePartialSpecializationDecl>(this))1386 return true;1387 1388 if (const auto *Record = dyn_cast<CXXRecordDecl>(this)) {1389 if (Record->getDescribedClassTemplate())1390 return true;1391 1392 if (Record->isDependentLambda())1393 return true;1394 if (Record->isNeverDependentLambda())1395 return false;1396 }1397 1398 if (const auto *Function = dyn_cast<FunctionDecl>(this)) {1399 if (Function->getDescribedFunctionTemplate())1400 return true;1401 1402 // Friend function declarations are dependent if their *lexical*1403 // context is dependent.1404 if (cast<Decl>(this)->getFriendObjectKind())1405 return getLexicalParent()->isDependentContext();1406 }1407 1408 // FIXME: A variable template is a dependent context, but is not a1409 // DeclContext. A context within it (such as a lambda-expression)1410 // should be considered dependent.1411 1412 return getParent() && getParent()->isDependentContext();1413}1414 1415bool DeclContext::isTransparentContext() const {1416 if (getDeclKind() == Decl::Enum)1417 return !cast<EnumDecl>(this)->isScoped();1418 1419 return isa<LinkageSpecDecl, ExportDecl, HLSLBufferDecl>(this);1420}1421 1422static bool isLinkageSpecContext(const DeclContext *DC,1423 LinkageSpecLanguageIDs ID) {1424 while (DC->getDeclKind() != Decl::TranslationUnit) {1425 if (DC->getDeclKind() == Decl::LinkageSpec)1426 return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;1427 DC = DC->getLexicalParent();1428 }1429 return false;1430}1431 1432bool DeclContext::isExternCContext() const {1433 return isLinkageSpecContext(this, LinkageSpecLanguageIDs::C);1434}1435 1436const LinkageSpecDecl *DeclContext::getExternCContext() const {1437 const DeclContext *DC = this;1438 while (DC->getDeclKind() != Decl::TranslationUnit) {1439 if (DC->getDeclKind() == Decl::LinkageSpec &&1440 cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecLanguageIDs::C)1441 return cast<LinkageSpecDecl>(DC);1442 DC = DC->getLexicalParent();1443 }1444 return nullptr;1445}1446 1447bool DeclContext::isExternCXXContext() const {1448 return isLinkageSpecContext(this, LinkageSpecLanguageIDs::CXX);1449}1450 1451bool DeclContext::Encloses(const DeclContext *DC) const {1452 if (getPrimaryContext() != this)1453 return getPrimaryContext()->Encloses(DC);1454 1455 for (; DC; DC = DC->getParent())1456 if (!isa<LinkageSpecDecl, ExportDecl>(DC) &&1457 DC->getPrimaryContext() == this)1458 return true;1459 return false;1460}1461 1462bool DeclContext::LexicallyEncloses(const DeclContext *DC) const {1463 if (getPrimaryContext() != this)1464 return getPrimaryContext()->LexicallyEncloses(DC);1465 1466 for (; DC; DC = DC->getLexicalParent())1467 if (!isa<LinkageSpecDecl, ExportDecl>(DC) &&1468 DC->getPrimaryContext() == this)1469 return true;1470 return false;1471}1472 1473DeclContext *DeclContext::getNonTransparentContext() {1474 DeclContext *DC = this;1475 while (DC->isTransparentContext()) {1476 DC = DC->getParent();1477 assert(DC && "All transparent contexts should have a parent!");1478 }1479 return DC;1480}1481 1482DeclContext *DeclContext::getPrimaryContext() {1483 switch (getDeclKind()) {1484 case Decl::ExternCContext:1485 case Decl::LinkageSpec:1486 case Decl::Export:1487 case Decl::TopLevelStmt:1488 case Decl::Block:1489 case Decl::Captured:1490 case Decl::OutlinedFunction:1491 case Decl::OMPDeclareReduction:1492 case Decl::OMPDeclareMapper:1493 case Decl::RequiresExprBody:1494 // There is only one DeclContext for these entities.1495 return this;1496 1497 case Decl::HLSLBuffer:1498 // Each buffer, even with the same name, is a distinct construct.1499 // Multiple buffers with the same name are allowed for backward1500 // compatibility.1501 // As long as buffers have unique resource bindings the names don't matter.1502 // The names get exposed via the CPU-side reflection API which1503 // supports querying bindings, so we cannot remove them.1504 return this;1505 1506 case Decl::TranslationUnit:1507 return static_cast<TranslationUnitDecl *>(this)->getFirstDecl();1508 case Decl::Namespace:1509 return static_cast<NamespaceDecl *>(this)->getFirstDecl();1510 1511 case Decl::ObjCMethod:1512 return this;1513 1514 case Decl::ObjCInterface:1515 if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))1516 if (auto *Def = OID->getDefinition())1517 return Def;1518 return this;1519 1520 case Decl::ObjCProtocol:1521 if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))1522 if (auto *Def = OPD->getDefinition())1523 return Def;1524 return this;1525 1526 case Decl::ObjCCategory:1527 return this;1528 1529 case Decl::ObjCImplementation:1530 case Decl::ObjCCategoryImpl:1531 return this;1532 1533 // If this is a tag type that has a definition or is currently1534 // being defined, that definition is our primary context.1535 case Decl::ClassTemplatePartialSpecialization:1536 case Decl::ClassTemplateSpecialization:1537 case Decl::CXXRecord:1538 return cast<CXXRecordDecl>(this)->getDefinitionOrSelf();1539 case Decl::Record:1540 case Decl::Enum:1541 return cast<TagDecl>(this)->getDefinitionOrSelf();1542 1543 default:1544 assert(getDeclKind() >= Decl::firstFunction &&1545 getDeclKind() <= Decl::lastFunction && "Unknown DeclContext kind");1546 return this;1547 }1548}1549 1550template <typename T>1551static void collectAllContextsImpl(T *Self,1552 SmallVectorImpl<DeclContext *> &Contexts) {1553 for (T *D = Self->getMostRecentDecl(); D; D = D->getPreviousDecl())1554 Contexts.push_back(D);1555 1556 std::reverse(Contexts.begin(), Contexts.end());1557}1558 1559void DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts) {1560 Contexts.clear();1561 1562 Decl::Kind Kind = getDeclKind();1563 1564 if (Kind == Decl::TranslationUnit)1565 collectAllContextsImpl(static_cast<TranslationUnitDecl *>(this), Contexts);1566 else if (Kind == Decl::Namespace)1567 collectAllContextsImpl(static_cast<NamespaceDecl *>(this), Contexts);1568 else1569 Contexts.push_back(this);1570}1571 1572std::pair<Decl *, Decl *>1573DeclContext::BuildDeclChain(ArrayRef<Decl *> Decls,1574 bool FieldsAlreadyLoaded) {1575 // Build up a chain of declarations via the Decl::NextInContextAndBits field.1576 Decl *FirstNewDecl = nullptr;1577 Decl *PrevDecl = nullptr;1578 for (auto *D : Decls) {1579 if (FieldsAlreadyLoaded && isa<FieldDecl>(D))1580 continue;1581 1582 if (PrevDecl)1583 PrevDecl->NextInContextAndBits.setPointer(D);1584 else1585 FirstNewDecl = D;1586 1587 PrevDecl = D;1588 }1589 1590 return std::make_pair(FirstNewDecl, PrevDecl);1591}1592 1593/// We have just acquired external visible storage, and we already have1594/// built a lookup map. For every name in the map, pull in the new names from1595/// the external storage.1596void DeclContext::reconcileExternalVisibleStorage() const {1597 assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);1598 setNeedToReconcileExternalVisibleStorage(false);1599 1600 for (auto &Lookup : *LookupPtr)1601 Lookup.second.setHasExternalDecls();1602}1603 1604/// Load the declarations within this lexical storage from an1605/// external source.1606/// \return \c true if any declarations were added.1607bool1608DeclContext::LoadLexicalDeclsFromExternalStorage() const {1609 ExternalASTSource *Source = getParentASTContext().getExternalSource();1610 assert(hasExternalLexicalStorage() && Source && "No external storage?");1611 1612 // Notify that we have a DeclContext that is initializing.1613 ExternalASTSource::Deserializing ADeclContext(Source);1614 1615 // Load the external declarations, if any.1616 SmallVector<Decl*, 64> Decls;1617 setHasExternalLexicalStorage(false);1618 Source->FindExternalLexicalDecls(this, Decls);1619 1620 if (Decls.empty())1621 return false;1622 1623 // We may have already loaded just the fields of this record, in which case1624 // we need to ignore them.1625 bool FieldsAlreadyLoaded = false;1626 if (const auto *RD = dyn_cast<RecordDecl>(this))1627 FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();1628 1629 // Splice the newly-read declarations into the beginning of the list1630 // of declarations.1631 Decl *ExternalFirst, *ExternalLast;1632 std::tie(ExternalFirst, ExternalLast) =1633 BuildDeclChain(Decls, FieldsAlreadyLoaded);1634 ExternalLast->NextInContextAndBits.setPointer(FirstDecl);1635 FirstDecl = ExternalFirst;1636 if (!LastDecl)1637 LastDecl = ExternalLast;1638 return true;1639}1640 1641DeclContext::lookup_result1642ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,1643 DeclarationName Name) {1644 ASTContext &Context = DC->getParentASTContext();1645 StoredDeclsMap *Map;1646 if (!(Map = DC->LookupPtr))1647 Map = DC->CreateStoredDeclsMap(Context);1648 if (DC->hasNeedToReconcileExternalVisibleStorage())1649 DC->reconcileExternalVisibleStorage();1650 1651 (*Map)[Name].removeExternalDecls();1652 1653 return DeclContext::lookup_result();1654}1655 1656DeclContext::lookup_result1657ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,1658 DeclarationName Name,1659 ArrayRef<NamedDecl*> Decls) {1660 ASTContext &Context = DC->getParentASTContext();1661 StoredDeclsMap *Map;1662 if (!(Map = DC->LookupPtr))1663 Map = DC->CreateStoredDeclsMap(Context);1664 if (DC->hasNeedToReconcileExternalVisibleStorage())1665 DC->reconcileExternalVisibleStorage();1666 1667 StoredDeclsList &List = (*Map)[Name];1668 List.replaceExternalDecls(Decls);1669 return List.getLookupResult();1670}1671 1672DeclContext::decl_iterator DeclContext::decls_begin() const {1673 if (hasExternalLexicalStorage())1674 LoadLexicalDeclsFromExternalStorage();1675 return decl_iterator(FirstDecl);1676}1677 1678bool DeclContext::decls_empty() const {1679 if (hasExternalLexicalStorage())1680 LoadLexicalDeclsFromExternalStorage();1681 1682 return !FirstDecl;1683}1684 1685bool DeclContext::containsDecl(Decl *D) const {1686 return (D->getLexicalDeclContext() == this &&1687 (D->NextInContextAndBits.getPointer() || D == LastDecl));1688}1689 1690bool DeclContext::containsDeclAndLoad(Decl *D) const {1691 if (hasExternalLexicalStorage())1692 LoadLexicalDeclsFromExternalStorage();1693 return containsDecl(D);1694}1695 1696/// shouldBeHidden - Determine whether a declaration which was declared1697/// within its semantic context should be invisible to qualified name lookup.1698static bool shouldBeHidden(NamedDecl *D) {1699 // Skip unnamed declarations.1700 if (!D->getDeclName())1701 return true;1702 1703 // Skip entities that can't be found by name lookup into a particular1704 // context.1705 if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||1706 D->isTemplateParameter())1707 return true;1708 1709 // Skip friends and local extern declarations unless they're the first1710 // declaration of the entity.1711 if ((D->isLocalExternDecl() || D->getFriendObjectKind()) &&1712 D != D->getCanonicalDecl())1713 return true;1714 1715 // Skip template specializations.1716 // FIXME: This feels like a hack. Should DeclarationName support1717 // template-ids, or is there a better way to keep specializations1718 // from being visible?1719 if (isa<ClassTemplateSpecializationDecl>(D))1720 return true;1721 if (auto *FD = dyn_cast<FunctionDecl>(D))1722 if (FD->isFunctionTemplateSpecialization())1723 return true;1724 1725 // Hide destructors that are invalid. There should always be one destructor,1726 // but if it is an invalid decl, another one is created. We need to hide the1727 // invalid one from places that expect exactly one destructor, like the1728 // serialization code.1729 if (isa<CXXDestructorDecl>(D) && D->isInvalidDecl())1730 return true;1731 1732 return false;1733}1734 1735void DeclContext::removeDecl(Decl *D) {1736 assert(D->getLexicalDeclContext() == this &&1737 "decl being removed from non-lexical context");1738 assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&1739 "decl is not in decls list");1740 1741 // Remove D from the decl chain. This is O(n) but hopefully rare.1742 if (D == FirstDecl) {1743 if (D == LastDecl)1744 FirstDecl = LastDecl = nullptr;1745 else1746 FirstDecl = D->NextInContextAndBits.getPointer();1747 } else {1748 for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {1749 assert(I && "decl not found in linked list");1750 if (I->NextInContextAndBits.getPointer() == D) {1751 I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());1752 if (D == LastDecl) LastDecl = I;1753 break;1754 }1755 }1756 }1757 1758 // Mark that D is no longer in the decl chain.1759 D->NextInContextAndBits.setPointer(nullptr);1760 1761 // Remove D from the lookup table if necessary.1762 if (isa<NamedDecl>(D)) {1763 auto *ND = cast<NamedDecl>(D);1764 1765 // Do not try to remove the declaration if that is invisible to qualified1766 // lookup. E.g. template specializations are skipped.1767 if (shouldBeHidden(ND))1768 return;1769 1770 // Remove only decls that have a name1771 if (!ND->getDeclName())1772 return;1773 1774 auto *DC = D->getDeclContext();1775 do {1776 StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr;1777 if (Map) {1778 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());1779 assert(Pos != Map->end() && "no lookup entry for decl");1780 StoredDeclsList &List = Pos->second;1781 List.remove(ND);1782 // Clean up the entry if there are no more decls.1783 if (List.isNull())1784 Map->erase(Pos);1785 }1786 } while (DC->isTransparentContext() && (DC = DC->getParent()));1787 }1788}1789 1790void DeclContext::addHiddenDecl(Decl *D) {1791 assert(D->getLexicalDeclContext() == this &&1792 "Decl inserted into wrong lexical context");1793 assert(!D->getNextDeclInContext() && D != LastDecl &&1794 "Decl already inserted into a DeclContext");1795 1796 if (FirstDecl) {1797 LastDecl->NextInContextAndBits.setPointer(D);1798 LastDecl = D;1799 } else {1800 FirstDecl = LastDecl = D;1801 }1802 1803 // Notify a C++ record declaration that we've added a member, so it can1804 // update its class-specific state.1805 if (auto *Record = dyn_cast<CXXRecordDecl>(this))1806 Record->addedMember(D);1807 1808 // If this is a newly-created (not de-serialized) import declaration, wire1809 // it in to the list of local import declarations.1810 if (!D->isFromASTFile()) {1811 if (auto *Import = dyn_cast<ImportDecl>(D))1812 D->getASTContext().addedLocalImportDecl(Import);1813 }1814}1815 1816void DeclContext::addDecl(Decl *D) {1817 addHiddenDecl(D);1818 1819 if (auto *ND = dyn_cast<NamedDecl>(D))1820 ND->getDeclContext()->getPrimaryContext()->1821 makeDeclVisibleInContextWithFlags(ND, false, true);1822}1823 1824void DeclContext::addDeclInternal(Decl *D) {1825 addHiddenDecl(D);1826 1827 if (auto *ND = dyn_cast<NamedDecl>(D))1828 ND->getDeclContext()->getPrimaryContext()->1829 makeDeclVisibleInContextWithFlags(ND, true, true);1830}1831 1832/// buildLookup - Build the lookup data structure with all of the1833/// declarations in this DeclContext (and any other contexts linked1834/// to it or transparent contexts nested within it) and return it.1835///1836/// Note that the produced map may miss out declarations from an1837/// external source. If it does, those entries will be marked with1838/// the 'hasExternalDecls' flag.1839StoredDeclsMap *DeclContext::buildLookup() {1840 assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");1841 1842 if (!hasLazyLocalLexicalLookups() &&1843 !hasLazyExternalLexicalLookups())1844 return LookupPtr;1845 1846 SmallVector<DeclContext *, 2> Contexts;1847 collectAllContexts(Contexts);1848 1849 if (hasLazyExternalLexicalLookups()) {1850 setHasLazyExternalLexicalLookups(false);1851 for (auto *DC : Contexts) {1852 if (DC->hasExternalLexicalStorage()) {1853 bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();1854 setHasLazyLocalLexicalLookups(1855 hasLazyLocalLexicalLookups() | LoadedDecls );1856 }1857 }1858 1859 if (!hasLazyLocalLexicalLookups())1860 return LookupPtr;1861 }1862 1863 for (auto *DC : Contexts)1864 buildLookupImpl(DC, hasExternalVisibleStorage());1865 1866 // We no longer have any lazy decls.1867 setHasLazyLocalLexicalLookups(false);1868 return LookupPtr;1869}1870 1871/// buildLookupImpl - Build part of the lookup data structure for the1872/// declarations contained within DCtx, which will either be this1873/// DeclContext, a DeclContext linked to it, or a transparent context1874/// nested within it.1875void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) {1876 for (auto *D : DCtx->noload_decls()) {1877 // Insert this declaration into the lookup structure, but only if1878 // it's semantically within its decl context. Any other decls which1879 // should be found in this context are added eagerly.1880 //1881 // If it's from an AST file, don't add it now. It'll get handled by1882 // FindExternalVisibleDeclsByName if needed. Exception: if we're not1883 // in C++, we do not track external visible decls for the TU, so in1884 // that case we need to collect them all here.1885 if (auto *ND = dyn_cast<NamedDecl>(D))1886 if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&1887 (!ND->isFromASTFile() ||1888 (isTranslationUnit() &&1889 !getParentASTContext().getLangOpts().CPlusPlus)))1890 makeDeclVisibleInContextImpl(ND, Internal);1891 1892 // If this declaration is itself a transparent declaration context1893 // or inline namespace, add the members of this declaration of that1894 // context (recursively).1895 if (auto *InnerCtx = dyn_cast<DeclContext>(D))1896 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())1897 buildLookupImpl(InnerCtx, Internal);1898 }1899}1900 1901DeclContext::lookup_result1902DeclContext::lookup(DeclarationName Name) const {1903 // For transparent DeclContext, we should lookup in their enclosing context.1904 if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)1905 return getParent()->lookup(Name);1906 1907 return getPrimaryContext()->lookupImpl(Name, this);1908}1909 1910DeclContext::lookup_result1911DeclContext::lookupImpl(DeclarationName Name,1912 const DeclContext *OriginalLookupDC) const {1913 assert(this == getPrimaryContext() &&1914 "lookupImpl should only be called with primary DC!");1915 assert(getDeclKind() != Decl::LinkageSpec && getDeclKind() != Decl::Export &&1916 "We shouldn't lookup in transparent DC.");1917 1918 // If we have an external source, ensure that any later redeclarations of this1919 // context have been loaded, since they may add names to the result of this1920 // lookup (or add external visible storage).1921 ExternalASTSource *Source = getParentASTContext().getExternalSource();1922 if (Source)1923 (void)cast<Decl>(this)->getMostRecentDecl();1924 1925 if (hasExternalVisibleStorage()) {1926 assert(Source && "external visible storage but no external source?");1927 1928 if (hasNeedToReconcileExternalVisibleStorage())1929 reconcileExternalVisibleStorage();1930 1931 StoredDeclsMap *Map = LookupPtr;1932 1933 if (hasLazyLocalLexicalLookups() ||1934 hasLazyExternalLexicalLookups())1935 // FIXME: Make buildLookup const?1936 Map = const_cast<DeclContext*>(this)->buildLookup();1937 1938 if (!Map)1939 Map = CreateStoredDeclsMap(getParentASTContext());1940 1941 // If we have a lookup result with no external decls, we are done.1942 std::pair<StoredDeclsMap::iterator, bool> R = Map->try_emplace(Name);1943 if (!R.second && !R.first->second.hasExternalDecls())1944 return R.first->second.getLookupResult();1945 1946 if (Source->FindExternalVisibleDeclsByName(this, Name, OriginalLookupDC) ||1947 !R.second) {1948 if (StoredDeclsMap *Map = LookupPtr) {1949 StoredDeclsMap::iterator I = Map->find(Name);1950 if (I != Map->end())1951 return I->second.getLookupResult();1952 }1953 }1954 1955 return {};1956 }1957 1958 StoredDeclsMap *Map = LookupPtr;1959 if (hasLazyLocalLexicalLookups() ||1960 hasLazyExternalLexicalLookups())1961 Map = const_cast<DeclContext*>(this)->buildLookup();1962 1963 if (!Map)1964 return {};1965 1966 StoredDeclsMap::iterator I = Map->find(Name);1967 if (I == Map->end())1968 return {};1969 1970 return I->second.getLookupResult();1971}1972 1973DeclContext::lookup_result1974DeclContext::noload_lookup(DeclarationName Name) {1975 // For transparent DeclContext, we should lookup in their enclosing context.1976 if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)1977 return getParent()->noload_lookup(Name);1978 1979 DeclContext *PrimaryContext = getPrimaryContext();1980 if (PrimaryContext != this)1981 return PrimaryContext->noload_lookup(Name);1982 1983 loadLazyLocalLexicalLookups();1984 StoredDeclsMap *Map = LookupPtr;1985 if (!Map)1986 return {};1987 1988 StoredDeclsMap::iterator I = Map->find(Name);1989 return I != Map->end() ? I->second.getLookupResult()1990 : lookup_result();1991}1992 1993// If we have any lazy lexical declarations not in our lookup map, add them1994// now. Don't import any external declarations, not even if we know we have1995// some missing from the external visible lookups.1996void DeclContext::loadLazyLocalLexicalLookups() {1997 if (hasLazyLocalLexicalLookups()) {1998 SmallVector<DeclContext *, 2> Contexts;1999 collectAllContexts(Contexts);2000 for (auto *Context : Contexts)2001 buildLookupImpl(Context, hasExternalVisibleStorage());2002 setHasLazyLocalLexicalLookups(false);2003 }2004}2005 2006void DeclContext::localUncachedLookup(DeclarationName Name,2007 SmallVectorImpl<NamedDecl *> &Results) {2008 Results.clear();2009 2010 // If there's no external storage, just perform a normal lookup and copy2011 // the results.2012 if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {2013 lookup_result LookupResults = lookup(Name);2014 llvm::append_range(Results, LookupResults);2015 if (!Results.empty())2016 return;2017 }2018 2019 // If we have a lookup table, check there first. Maybe we'll get lucky.2020 // FIXME: Should we be checking these flags on the primary context?2021 if (Name && !hasLazyLocalLexicalLookups() &&2022 !hasLazyExternalLexicalLookups()) {2023 if (StoredDeclsMap *Map = LookupPtr) {2024 StoredDeclsMap::iterator Pos = Map->find(Name);2025 if (Pos != Map->end()) {2026 Results.insert(Results.end(),2027 Pos->second.getLookupResult().begin(),2028 Pos->second.getLookupResult().end());2029 return;2030 }2031 }2032 }2033 2034 // Slow case: grovel through the declarations in our chain looking for2035 // matches.2036 // FIXME: If we have lazy external declarations, this will not find them!2037 // FIXME: Should we CollectAllContexts and walk them all here?2038 for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {2039 if (auto *ND = dyn_cast<NamedDecl>(D))2040 if (ND->getDeclName() == Name)2041 Results.push_back(ND);2042 }2043}2044 2045DeclContext *DeclContext::getRedeclContext() {2046 DeclContext *Ctx = this;2047 2048 // In C, a record type is the redeclaration context for its fields only. If2049 // we arrive at a record context after skipping anything else, we should skip2050 // the record as well. Currently, this means skipping enumerations because2051 // they're the only transparent context that can exist within a struct or2052 // union.2053 bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&2054 !getParentASTContext().getLangOpts().CPlusPlus;2055 2056 // Skip through contexts to get to the redeclaration context. Transparent2057 // contexts are always skipped.2058 while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())2059 Ctx = Ctx->getParent();2060 return Ctx;2061}2062 2063DeclContext *DeclContext::getEnclosingNamespaceContext() {2064 DeclContext *Ctx = this;2065 // Skip through non-namespace, non-translation-unit contexts.2066 while (!Ctx->isFileContext())2067 Ctx = Ctx->getParent();2068 return Ctx->getPrimaryContext();2069}2070 2071RecordDecl *DeclContext::getOuterLexicalRecordContext() {2072 // Loop until we find a non-record context.2073 RecordDecl *OutermostRD = nullptr;2074 DeclContext *DC = this;2075 while (DC->isRecord()) {2076 OutermostRD = cast<RecordDecl>(DC);2077 DC = DC->getLexicalParent();2078 }2079 return OutermostRD;2080}2081 2082bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const {2083 // For non-file contexts, this is equivalent to Equals.2084 if (!isFileContext())2085 return O->Equals(this);2086 2087 do {2088 if (O->Equals(this))2089 return true;2090 2091 const auto *NS = dyn_cast<NamespaceDecl>(O);2092 if (!NS || !NS->isInline())2093 break;2094 O = NS->getParent();2095 } while (O);2096 2097 return false;2098}2099 2100void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {2101 DeclContext *PrimaryDC = this->getPrimaryContext();2102 DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();2103 // If the decl is being added outside of its semantic decl context, we2104 // need to ensure that we eagerly build the lookup information for it.2105 PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);2106}2107 2108void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,2109 bool Recoverable) {2110 assert(this == getPrimaryContext() && "expected a primary DC");2111 2112 if (!isLookupContext()) {2113 if (isTransparentContext())2114 getParent()->getPrimaryContext()2115 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);2116 return;2117 }2118 2119 // Skip declarations which should be invisible to name lookup.2120 if (shouldBeHidden(D))2121 return;2122 2123 // If we already have a lookup data structure, perform the insertion into2124 // it. If we might have externally-stored decls with this name, look them2125 // up and perform the insertion. If this decl was declared outside its2126 // semantic context, buildLookup won't add it, so add it now.2127 //2128 // FIXME: As a performance hack, don't add such decls into the translation2129 // unit unless we're in C++, since qualified lookup into the TU is never2130 // performed.2131 if (LookupPtr || hasExternalVisibleStorage() ||2132 ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&2133 (getParentASTContext().getLangOpts().CPlusPlus ||2134 !isTranslationUnit()))) {2135 // If we have lazily omitted any decls, they might have the same name as2136 // the decl which we are adding, so build a full lookup table before adding2137 // this decl.2138 buildLookup();2139 makeDeclVisibleInContextImpl(D, Internal);2140 } else {2141 setHasLazyLocalLexicalLookups(true);2142 }2143 2144 // If we are a transparent context or inline namespace, insert into our2145 // parent context, too. This operation is recursive.2146 if (isTransparentContext() || isInlineNamespace())2147 getParent()->getPrimaryContext()->2148 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);2149 2150 auto *DCAsDecl = cast<Decl>(this);2151 // Notify that a decl was made visible unless we are a Tag being defined.2152 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))2153 if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())2154 L->AddedVisibleDecl(this, D);2155}2156 2157void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {2158 // Find or create the stored declaration map.2159 StoredDeclsMap *Map = LookupPtr;2160 if (!Map) {2161 ASTContext *C = &getParentASTContext();2162 Map = CreateStoredDeclsMap(*C);2163 }2164 2165 // If there is an external AST source, load any declarations it knows about2166 // with this declaration's name.2167 // If the lookup table contains an entry about this name it means that we2168 // have already checked the external source.2169 if (!Internal)2170 if (ExternalASTSource *Source = getParentASTContext().getExternalSource())2171 if (hasExternalVisibleStorage() && !Map->contains(D->getDeclName()))2172 Source->FindExternalVisibleDeclsByName(this, D->getDeclName(),2173 D->getDeclContext());2174 2175 // Insert this declaration into the map.2176 StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];2177 2178 if (Internal) {2179 // If this is being added as part of loading an external declaration,2180 // this may not be the only external declaration with this name.2181 // In this case, we never try to replace an existing declaration; we'll2182 // handle that when we finalize the list of declarations for this name.2183 DeclNameEntries.setHasExternalDecls();2184 DeclNameEntries.prependDeclNoReplace(D);2185 return;2186 }2187 2188 DeclNameEntries.addOrReplaceDecl(D);2189}2190 2191UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const {2192 return cast<UsingDirectiveDecl>(*I);2193}2194 2195/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within2196/// this context.2197DeclContext::udir_range DeclContext::using_directives() const {2198 // FIXME: Use something more efficient than normal lookup for using2199 // directives. In C++, using directives are looked up more than anything else.2200 lookup_result Result = lookup(UsingDirectiveDecl::getName());2201 return udir_range(Result.begin(), Result.end());2202}2203 2204//===----------------------------------------------------------------------===//2205// Creation and Destruction of StoredDeclsMaps. //2206//===----------------------------------------------------------------------===//2207 2208StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {2209 assert(!LookupPtr && "context already has a decls map");2210 assert(getPrimaryContext() == this &&2211 "creating decls map on non-primary context");2212 2213 StoredDeclsMap *M;2214 bool Dependent = isDependentContext();2215 if (Dependent)2216 M = new DependentStoredDeclsMap();2217 else2218 M = new StoredDeclsMap();2219 M->Previous = C.LastSDM;2220 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);2221 LookupPtr = M;2222 return M;2223}2224 2225void ASTContext::ReleaseDeclContextMaps() {2226 // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap2227 // pointer because the subclass doesn't add anything that needs to2228 // be deleted.2229 StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt());2230 LastSDM.setPointer(nullptr);2231}2232 2233void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) {2234 while (Map) {2235 // Advance the iteration before we invalidate memory.2236 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;2237 2238 if (Dependent)2239 delete static_cast<DependentStoredDeclsMap*>(Map);2240 else2241 delete Map;2242 2243 Map = Next.getPointer();2244 Dependent = Next.getInt();2245 }2246}2247 2248DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,2249 DeclContext *Parent,2250 const PartialDiagnostic &PDiag) {2251 assert(Parent->isDependentContext()2252 && "cannot iterate dependent diagnostics of non-dependent context");2253 Parent = Parent->getPrimaryContext();2254 if (!Parent->LookupPtr)2255 Parent->CreateStoredDeclsMap(C);2256 2257 auto *Map = static_cast<DependentStoredDeclsMap *>(Parent->LookupPtr);2258 2259 // Allocate the copy of the PartialDiagnostic via the ASTContext's2260 // BumpPtrAllocator, rather than the ASTContext itself.2261 DiagnosticStorage *DiagStorage = nullptr;2262 if (PDiag.hasStorage())2263 DiagStorage = new (C) DiagnosticStorage;2264 2265 auto *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);2266 2267 // TODO: Maybe we shouldn't reverse the order during insertion.2268 DD->NextDiagnostic = Map->FirstDiagnostic;2269 Map->FirstDiagnostic = DD;2270 2271 return DD;2272}2273 2274unsigned DeclIDBase::getLocalDeclIndex() const {2275 return ID & llvm::maskTrailingOnes<DeclID>(32);2276}2277