38#include "llvm/ADT/ArrayRef.h"
39#include "llvm/ADT/PointerIntPair.h"
40#include "llvm/ADT/SmallVector.h"
41#include "llvm/ADT/StringRef.h"
42#include "llvm/Support/Casting.h"
43#include "llvm/Support/ErrorHandling.h"
44#include "llvm/Support/MathExtras.h"
45#include "llvm/Support/VersionTuple.h"
46#include "llvm/Support/raw_ostream.h"
60#define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
61#define ABSTRACT_DECL(DECL)
62#include "clang/AST/DeclNodes.inc"
68#define DECL(DERIVED, BASE) \
69 static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \
70 "Alignment sufficient after objects prepended to " #DERIVED);
71#define ABSTRACT_DECL(DECL)
72#include "clang/AST/DeclNodes.inc"
74void *Decl::operator
new(std::size_t Size,
const ASTContext &Context,
75 unsigned ID, std::size_t Extra) {
79 "Decl won't be misaligned");
80 void *Start = Context.
Allocate(Size + Extra + 8);
81 void *
Result = (
char*)Start + 8;
83 unsigned *PrefixPtr = (
unsigned *)
Result - 2;
94void *Decl::operator
new(std::size_t Size,
const ASTContext &Ctx,
96 assert(!
Parent || &
Parent->getParentASTContext() == &Ctx);
100 if (Ctx.getLangOpts().trackLocalOwningModule() || !
Parent) {
104 llvm::offsetToAlignment(
sizeof(
Module *), llvm::Align(
alignof(
Decl)));
105 auto *Buffer =
reinterpret_cast<char *
>(
106 ::operator
new(ExtraAlign +
sizeof(
Module *) + Size + Extra, Ctx));
107 Buffer += ExtraAlign;
109 Parent ? cast<Decl>(
Parent)->getOwningModule() :
nullptr;
110 return new (Buffer)
Module*(ParentModule) + 1;
112 return ::operator
new(Size + Extra, Ctx);
115Module *Decl::getOwningModuleSlow()
const {
126 default: llvm_unreachable(
"Declaration not in DeclNodes.inc!");
127#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
128#define ABSTRACT_DECL(DECL)
129#include "clang/AST/DeclNodes.inc"
135 assert(!isa<TagDecl>(
this) || !cast<TagDecl>(
this)->isCompleteDefinition());
140 if (!isa<ParmVarDecl>(
this)) {
149 if (
auto *DD = dyn_cast<DecompositionDecl>(
this)) {
150 for (
auto *Binding : DD->bindings()) {
151 Binding->setInvalidDecl();
158#define DECL(DERIVED, BASE) case Decl::DERIVED: return true;
159#define ABSTRACT_DECL(DECL)
160#include "clang/AST/DeclNodes.inc"
167#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
168#define ABSTRACT_DECL(DECL)
169#include "clang/AST/DeclNodes.inc"
171 llvm_unreachable(
"Declaration context not in DeclNodes.inc!");
174bool Decl::StatisticsEnabled =
false;
176 StatisticsEnabled =
true;
180 llvm::errs() <<
"\n*** Decl Stats:\n";
183#define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
184#define ABSTRACT_DECL(DECL)
185#include "clang/AST/DeclNodes.inc"
186 llvm::errs() <<
" " << totalDecls <<
" decls total.\n";
189#define DECL(DERIVED, BASE) \
190 if (n##DERIVED##s > 0) { \
191 totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \
192 llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \
193 << sizeof(DERIVED##Decl) << " each (" \
194 << n##DERIVED##s * sizeof(DERIVED##Decl) \
197#define ABSTRACT_DECL(DECL)
198#include "clang/AST/DeclNodes.inc"
200 llvm::errs() <<
"Total bytes = " << totalBytes <<
"\n";
205#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
206#define ABSTRACT_DECL(DECL)
207#include "clang/AST/DeclNodes.inc"
212 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(
this))
213 return TTP->isParameterPack();
214 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
this))
215 return NTTP->isParameterPack();
216 if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
this))
217 return TTP->isParameterPack();
222 if (
const auto *Var = dyn_cast<VarDecl>(
this))
223 return Var->isParameterPack();
229 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
231 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
232 return FTD->getTemplatedDecl();
237 return isa<TemplateDecl>(
this);
241 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
242 return FD->getDescribedFunctionTemplate();
243 if (
auto *RD = dyn_cast<CXXRecordDecl>(
this))
244 return RD->getDescribedClassTemplate();
245 if (
auto *VD = dyn_cast<VarDecl>(
this))
246 return VD->getDescribedVarTemplate();
247 if (
auto *AD = dyn_cast<TypeAliasDecl>(
this))
248 return AD->getDescribedAliasTemplate();
255 return TD->getTemplateParameters();
256 if (
auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(
this))
257 return CTPSD->getTemplateParameters();
258 if (
auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(
this))
259 return VTPSD->getTemplateParameters();
267 if (
auto *AsDC = dyn_cast<DeclContext>(
this))
268 return AsDC->isDependentContext();
276 if (
auto *DC = dyn_cast<DeclContext>(
this))
277 if (DC->isFileContext())
281 return TPL->getDepth() + 1;
286 auto *RD = dyn_cast<CXXRecordDecl>(
this);
287 if (RD && RD->isDependentLambda())
288 if (
Decl *Context = RD->getLambdaContextDecl())
289 return Context->getTemplateDepth();
293 return cast<Decl>(DC)->getTemplateDepth();
300 if (DC->isFunctionOrMethod())
316 TheLoc.
print(OS, SM);
322 if (
const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
324 DN->printQualifiedName(OS);
348 getMultipleDC()->LexicalDC = DC;
362 "hidden declaration has no owning module");
367 if (SemaDC == LexicalDC) {
370 auto *MDC =
new (Ctx) Decl::MultipleDC();
371 MDC->SemanticDC = SemaDC;
372 MDC->LexicalDC = LexicalDC;
384 if (!isa<TagDecl>(LDC))
386 if (
const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))
396 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC))
397 if (ND->isAnonymousNamespace())
410 const auto *DC = dyn_cast<DeclContext>(
this);
411 return DC && DC->isFileContext();
415 if (
auto *TUD = dyn_cast<TranslationUnitDecl>(
this))
419 assert(DC &&
"This decl is not contained in a translation unit!");
423 assert(DC &&
"This decl is not contained in a translation unit!");
426 return cast<TranslationUnitDecl>(DC);
451 for (; I != E; ++I) {
452 if (!I->isAlignmentErrorDependent())
453 Align = std::max(Align, I->getAlignment(Ctx));
477 if (
C.getASTMutationListener())
478 C.getASTMutationListener()->DeclarationMarkedUsed(
this);
488 for (
const auto *I :
redecls())
497 if (
auto *ID = dyn_cast<ObjCInterfaceDecl>(
this)) {
499 }
else if (
auto *PD = dyn_cast<ObjCProtocolDecl>(
this)) {
501 }
else if (
auto *TD = dyn_cast<TagDecl>(
this)) {
510 return dcd->getAttr<ExternalSourceSymbolAttr>();
517 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
518 hasAttr<LoaderUninitializedAttr>();
522 if (
auto *AA = getAttr<AliasAttr>())
524 if (
auto *IFA = getAttr<IFuncAttr>())
526 if (
auto *NZA = getAttr<LoaderUninitializedAttr>())
535 StringRef RealizedPlatform = A->getPlatform()->getName();
537 return RealizedPlatform;
538 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
539 if (suffix != StringRef::npos)
540 return RealizedPlatform.slice(0, suffix);
541 return RealizedPlatform;
554 const AvailabilityAttr *A,
555 std::string *Message,
556 VersionTuple EnclosingVersion) {
557 if (EnclosingVersion.empty())
560 if (EnclosingVersion.empty())
563 StringRef ActualPlatform = A->getPlatform()->getName();
570 StringRef PrettyPlatformName
571 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
573 if (PrettyPlatformName.empty())
574 PrettyPlatformName = ActualPlatform;
576 std::string HintMessage;
577 if (!A->getMessage().empty()) {
579 HintMessage += A->getMessage();
583 if (A->getUnavailable()) {
586 llvm::raw_string_ostream Out(*Message);
587 Out <<
"not available on " << PrettyPlatformName
595 if (!A->getIntroduced().empty() &&
596 EnclosingVersion < A->getIntroduced()) {
599 llvm::raw_string_ostream Out(*Message);
600 VersionTuple VTI(A->getIntroduced());
601 Out <<
"introduced in " << PrettyPlatformName <<
' '
602 << VTI << HintMessage;
609 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
612 llvm::raw_string_ostream Out(*Message);
613 VersionTuple VTO(A->getObsoleted());
614 Out <<
"obsoleted in " << PrettyPlatformName <<
' '
615 << VTO << HintMessage;
622 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
625 llvm::raw_string_ostream Out(*Message);
626 VersionTuple VTD(A->getDeprecated());
627 Out <<
"first deprecated in " << PrettyPlatformName <<
' '
628 << VTD << HintMessage;
638 VersionTuple EnclosingVersion,
639 StringRef *RealizedPlatform)
const {
640 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
641 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
645 std::string ResultMessage;
647 for (
const auto *A :
attrs()) {
648 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
653 ResultMessage = std::string(Deprecated->getMessage());
659 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
661 *Message = std::string(Unavailable->getMessage());
665 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
667 Message, EnclosingVersion);
670 if (RealizedPlatform)
671 *RealizedPlatform = Availability->getPlatform()->getName();
678 ResultMessage.swap(*Message);
685 Message->swap(ResultMessage);
692 for (
const auto *A :
attrs()) {
693 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
696 if (!Availability->getIntroduced().empty())
697 return Availability->getIntroduced();
704 IsDefinition =
false;
707 if (
const auto *Var = dyn_cast<VarDecl>(
this)) {
708 if (Var->isThisDeclarationADefinition()) {
715 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
724 if (isa<ObjCInterfaceDecl>(
this) &&
738 if (isa<WeakImportAttr>(A))
741 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
754 case CXXDeductionGuide:
757 case ConstructorUsingShadow:
775 case NonTypeTemplateParm:
782 case ObjCCompatibleAlias:
788 case TemplateTypeParm:
792 case UnresolvedUsingTypename:
798 case UnresolvedUsingValue:
810 case ObjCAtDefsField:
823 case FunctionTemplate:
827 case TemplateTemplateParm:
828 case TypeAliasTemplate:
831 case UnresolvedUsingIfExists:
834 case OMPDeclareReduction:
837 case OMPDeclareMapper:
849 case ObjCPropertyImpl:
851 case PragmaDetectMismatch:
854 case TranslationUnit:
858 case UnnamedGlobalConstant:
859 case TemplateParamObject:
862 case BuiltinTemplate:
863 case ClassTemplateSpecialization:
864 case ClassTemplatePartialSpecialization:
865 case ClassScopeFunctionSpecialization:
866 case VarTemplateSpecialization:
867 case VarTemplatePartialSpecialization:
868 case ObjCImplementation:
870 case ObjCCategoryImpl:
872 case OMPThreadPrivate:
875 case OMPCapturedExpr:
877 case LifetimeExtendedTemporary:
878 case RequiresExprBody:
879 case ImplicitConceptSpecialization:
884 llvm_unreachable(
"Invalid DeclKind!");
888 assert(!HasAttrs &&
"Decl already contains attrs.");
891 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
898 if (!HasAttrs)
return;
919 auto I = Attrs.begin(), E = Attrs.end();
920 for (; I != E; ++I) {
921 if (!(*I)->isInherited())
928 assert(HasAttrs &&
"No attrs to get!");
935#define DECL(NAME, BASE)
936#define DECL_CONTEXT(NAME) \
938 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
939#define DECL_CONTEXT_BASE(NAME)
940#include "clang/AST/DeclNodes.inc"
942#define DECL(NAME, BASE)
943#define DECL_CONTEXT_BASE(NAME) \
944 if (DK >= first##NAME && DK <= last##NAME) \
945 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
946#include "clang/AST/DeclNodes.inc"
947 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
954#define DECL(NAME, BASE)
955#define DECL_CONTEXT(NAME) \
957 return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
958#define DECL_CONTEXT_BASE(NAME)
959#include "clang/AST/DeclNodes.inc"
961#define DECL(NAME, BASE)
962#define DECL_CONTEXT_BASE(NAME) \
963 if (DK >= first##NAME && DK <= last##NAME) \
964 return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
965#include "clang/AST/DeclNodes.inc"
966 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
973 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
981 return Body->getSourceRange().getEnd();
986bool Decl::AccessDeclContextCheck()
const {
997 if (isa<TranslationUnitDecl>(
this) || isa<TemplateTypeParmDecl>(
this) ||
1000 isa<StaticAssertDecl>(
this) || isa<BlockDecl>(
this) ||
1003 isa<ParmVarDecl>(
this) ||
1006 isa<CXXRecordDecl>(
this) ||
1007 isa<ClassScopeFunctionSpecializationDecl>(
this) ||
1008 isa<LifetimeExtendedTemporaryDecl>(
this))
1012 "Access specifier is AS_none inside a record decl");
1020 while (DC && !isa<ExportDecl>(DC))
1023 return DC && isa<ExportDecl>(DC);
1032 M = M->getTopLevelModule();
1036 if (M->isHeaderLikeModule())
1041 if (M->isGlobalModule())
1044 assert(M->isModulePurview() &&
"New module kind?");
1057 if (
const auto *D = dyn_cast<ValueDecl>(
this))
1059 else if (
const auto *D = dyn_cast<TypedefNameDecl>(
this))
1060 Ty = D->getUnderlyingType();
1076 if (
const auto *D = dyn_cast<ValueDecl>(
this))
1078 else if (
const auto *D = dyn_cast<TypedefNameDecl>(
this))
1079 Ty = D->getUnderlyingType();
1094 if (
getKind(D) == Decl::CXXMethod) {
1095 auto *MD = cast<CXXMethodDecl>(D);
1096 if (MD->getOverloadedOperator() == OO_Call &&
1097 MD->getParent()->isLambda())
1101 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1103 if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
1105 if (
auto *BD = dyn_cast<BlockDecl>(D))
1107 if (
auto *CD = dyn_cast<CapturedDecl>(D))
1113 return ::getNonClosureContext(
this);
1117 return ::getNonClosureContext(
this);
1128 setNeedToReconcileExternalVisibleStorage(
false);
1129 setHasLazyLocalLexicalLookups(
false);
1130 setHasLazyExternalLexicalLookups(
false);
1136#define DECL(NAME, BASE)
1137#define DECL_CONTEXT(NAME) case Decl::NAME:
1138#define DECL_CONTEXT_BASE(NAME)
1139#include "clang/AST/DeclNodes.inc"
1142#define DECL(NAME, BASE)
1143#define DECL_CONTEXT_BASE(NAME) \
1144 if (D->getKind() >= Decl::first##NAME && \
1145 D->getKind() <= Decl::last##NAME) \
1147#include "clang/AST/DeclNodes.inc"
1162 if (isa<FunctionDecl>(
this))
1181 return cast<BlockDecl>(Ctx);
1190 cast<NamespaceDecl>(
this)->isInline();
1197 const auto *ND = cast<NamespaceDecl>(
this);
1198 if (ND->isInline()) {
1199 return ND->getParent()->isStdNamespace();
1206 return II && II->
isStr(
"std");
1213 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
1216 if (
const auto *Record = dyn_cast<CXXRecordDecl>(
this)) {
1217 if (Record->getDescribedClassTemplate())
1220 if (Record->isDependentLambda())
1222 if (Record->isNeverDependentLambda())
1226 if (
const auto *Function = dyn_cast<FunctionDecl>(
this)) {
1227 if (Function->getDescribedFunctionTemplate())
1232 if (cast<Decl>(
this)->getFriendObjectKind())
1245 return !cast<EnumDecl>(
this)->isScoped();
1247 return isa<LinkageSpecDecl, ExportDecl, HLSLBufferDecl>(
this);
1252 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1254 return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
1266 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1269 return cast<LinkageSpecDecl>(DC);
1284 if (!isa<LinkageSpecDecl>(DC) && !isa<ExportDecl>(DC) &&
1294 assert(DC &&
"All transparent contexts should have a parent!");
1301 case Decl::ExternCContext:
1302 case Decl::LinkageSpec:
1305 case Decl::Captured:
1306 case Decl::OMPDeclareReduction:
1307 case Decl::OMPDeclareMapper:
1308 case Decl::RequiresExprBody:
1312 case Decl::HLSLBuffer:
1321 case Decl::TranslationUnit:
1323 case Decl::Namespace:
1325 return static_cast<NamespaceDecl *
>(
this)->getOriginalNamespace();
1327 case Decl::ObjCMethod:
1330 case Decl::ObjCInterface:
1331 if (
auto *OID = dyn_cast<ObjCInterfaceDecl>(
this))
1332 if (
auto *Def = OID->getDefinition())
1336 case Decl::ObjCProtocol:
1337 if (
auto *OPD = dyn_cast<ObjCProtocolDecl>(
this))
1338 if (
auto *Def = OPD->getDefinition())
1342 case Decl::ObjCCategory:
1345 case Decl::ObjCImplementation:
1346 case Decl::ObjCCategoryImpl:
1353 auto *Tag = cast<TagDecl>(
this);
1358 if (
const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
1360 TagDecl *PossiblePartialDef = TagTy->getDecl();
1362 return PossiblePartialDef;
1364 assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1372 "Unknown DeclContext kind");
1377template <
typename T>
1379 for (T *D = Self->getMostRecentDecl(); D; D = D->getPreviousDecl())
1380 Contexts.push_back(D);
1382 std::reverse(Contexts.begin(), Contexts.end());
1390 if (Kind == Decl::TranslationUnit)
1392 else if (Kind == Decl::Namespace)
1395 Contexts.push_back(
this);
1398std::pair<Decl *, Decl *>
1400 bool FieldsAlreadyLoaded) {
1402 Decl *FirstNewDecl =
nullptr;
1403 Decl *PrevDecl =
nullptr;
1404 for (
auto *D : Decls) {
1405 if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1416 return std::make_pair(FirstNewDecl, PrevDecl);
1422void DeclContext::reconcileExternalVisibleStorage()
const {
1423 assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1424 setNeedToReconcileExternalVisibleStorage(
false);
1426 for (
auto &Lookup : *LookupPtr)
1427 Lookup.second.setHasExternalDecls();
1434DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1451 bool FieldsAlreadyLoaded =
false;
1452 if (
const auto *RD = dyn_cast<RecordDecl>(
this))
1453 FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1457 Decl *ExternalFirst, *ExternalLast;
1458 std::tie(ExternalFirst, ExternalLast) =
1472 if (!(Map = DC->LookupPtr))
1473 Map = DC->CreateStoredDeclsMap(Context);
1474 if (DC->hasNeedToReconcileExternalVisibleStorage())
1475 DC->reconcileExternalVisibleStorage();
1477 (*Map)[Name].removeExternalDecls();
1488 if (!(Map = DC->LookupPtr))
1489 Map = DC->CreateStoredDeclsMap(Context);
1490 if (DC->hasNeedToReconcileExternalVisibleStorage())
1491 DC->reconcileExternalVisibleStorage();
1494 List.replaceExternalDecls(Decls);
1495 return List.getLookupResult();
1500 LoadLexicalDeclsFromExternalStorage();
1506 LoadLexicalDeclsFromExternalStorage();
1518 LoadLexicalDeclsFromExternalStorage();
1545 if (isa<ClassTemplateSpecializationDecl>(D))
1547 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1548 if (FD->isFunctionTemplateSpecialization())
1563 "decl being removed from non-lexical context");
1565 "decl is not in decls list");
1575 assert(I &&
"decl not found in linked list");
1576 if (I->NextInContextAndBits.getPointer() == D) {
1588 if (isa<NamedDecl>(D)) {
1589 auto *ND = cast<NamedDecl>(D);
1597 if (!ND->getDeclName())
1604 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1605 assert(Pos != Map->end() &&
"no lookup entry for decl");
1612 }
while (DC->isTransparentContext() && (DC = DC->getParent()));
1618 "Decl inserted into wrong lexical context");
1620 "Decl already inserted into a DeclContext");
1631 if (
auto *Record = dyn_cast<CXXRecordDecl>(
this))
1632 Record->addedMember(D);
1637 if (
auto *Import = dyn_cast<ImportDecl>(D))
1645 if (
auto *ND = dyn_cast<NamedDecl>(D))
1646 ND->getDeclContext()->getPrimaryContext()->
1647 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1653 if (
auto *ND = dyn_cast<NamedDecl>(D))
1654 ND->getDeclContext()->getPrimaryContext()->
1655 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1668 if (!hasLazyLocalLexicalLookups() &&
1669 !hasLazyExternalLexicalLookups())
1675 if (hasLazyExternalLexicalLookups()) {
1676 setHasLazyExternalLexicalLookups(
false);
1677 for (
auto *DC : Contexts) {
1678 if (DC->hasExternalLexicalStorage()) {
1679 bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1680 setHasLazyLocalLexicalLookups(
1681 hasLazyLocalLexicalLookups() | LoadedDecls );
1685 if (!hasLazyLocalLexicalLookups())
1689 for (
auto *DC : Contexts)
1693 setHasLazyLocalLexicalLookups(
false);
1701void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1711 if (
auto *ND = dyn_cast<NamedDecl>(D))
1713 (!ND->isFromASTFile() ||
1716 makeDeclVisibleInContextImpl(ND, Internal);
1721 if (
auto *InnerCtx = dyn_cast<DeclContext>(D))
1722 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1723 buildLookupImpl(InnerCtx, Internal);
1734 if (PrimaryContext !=
this)
1735 return PrimaryContext->
lookup(Name);
1742 (void)cast<Decl>(
this)->getMostRecentDecl();
1745 assert(Source &&
"external visible storage but no external source?");
1747 if (hasNeedToReconcileExternalVisibleStorage())
1748 reconcileExternalVisibleStorage();
1752 if (hasLazyLocalLexicalLookups() ||
1753 hasLazyExternalLexicalLookups())
1761 std::pair<StoredDeclsMap::iterator, bool> R =
1763 if (!R.second && !R.first->second.hasExternalDecls())
1764 return R.first->second.getLookupResult();
1768 StoredDeclsMap::iterator I = Map->find(Name);
1769 if (I != Map->end())
1770 return I->second.getLookupResult();
1778 if (hasLazyLocalLexicalLookups() ||
1779 hasLazyExternalLexicalLookups())
1785 StoredDeclsMap::iterator I = Map->find(Name);
1786 if (I == Map->end())
1789 return I->second.getLookupResult();
1796 "should not perform lookups into transparent contexts");
1799 if (PrimaryContext !=
this)
1802 loadLazyLocalLexicalLookups();
1807 StoredDeclsMap::iterator I = Map->find(Name);
1808 return I != Map->end() ? I->second.getLookupResult()
1815void DeclContext::loadLazyLocalLexicalLookups() {
1816 if (hasLazyLocalLexicalLookups()) {
1819 for (
auto *Context : Contexts)
1821 setHasLazyLocalLexicalLookups(
false);
1833 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1834 if (!Results.empty())
1840 if (Name && !hasLazyLocalLexicalLookups() &&
1841 !hasLazyExternalLexicalLookups()) {
1843 StoredDeclsMap::iterator Pos = Map->find(Name);
1844 if (Pos != Map->end()) {
1845 Results.insert(Results.end(),
1846 Pos->second.getLookupResult().begin(),
1847 Pos->second.getLookupResult().end());
1858 if (
auto *ND = dyn_cast<NamedDecl>(D))
1859 if (ND->getDeclName() == Name)
1860 Results.push_back(ND);
1872 bool SkipRecords =
getDeclKind() == Decl::Kind::Enum &&
1895 OutermostRD = cast<RecordDecl>(DC);
1910 const auto *NS = dyn_cast<NamespaceDecl>(O);
1911 if (!NS || !NS->isInline())
1924 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1927void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1934 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1958 makeDeclVisibleInContextImpl(D, Internal);
1960 setHasLazyLocalLexicalLookups(
true);
1967 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1969 auto *DCAsDecl = cast<Decl>(
this);
1971 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1973 L->AddedVisibleDecl(
this, D);
1976void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1981 Map = CreateStoredDeclsMap(*
C);
2011 return cast<UsingDirectiveDecl>(*I);
2028 assert(!LookupPtr &&
"context already has a decls map");
2030 "creating decls map on non-primary context");
2038 M->Previous =
C.LastSDM;
2039 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
2044void ASTContext::ReleaseDeclContextMaps() {
2049 LastSDM.setPointer(
nullptr);
2055 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
2062 Map = Next.getPointer();
2063 Dependent = Next.getInt();
2070 assert(
Parent->isDependentContext()
2071 &&
"cannot iterate dependent diagnostics of non-dependent context");
2074 Parent->CreateStoredDeclsMap(
C);
2087 DD->NextDiagnostic = Map->FirstDiagnostic;
2088 Map->FirstDiagnostic = DD;
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool shouldBeHidden(NamedDecl *D)
shouldBeHidden - Determine whether a declaration which was declared within its semantic context shoul...
static bool isLinkageSpecContext(const DeclContext *DC, LinkageSpecDecl::LanguageIDs ID)
static Decl::Kind getKind(const Decl *D)
static Decl * getNonClosureContext(T *D)
Starting at a given context (a Decl or DeclContext), look for a code context that is not a closure (a...
static AvailabilityResult CheckAvailability(ASTContext &Context, const AvailabilityAttr *A, std::string *Message, VersionTuple EnclosingVersion)
Determine the availability of the given declaration based on the target platform.
void collectAllContextsImpl(T *Self, SmallVectorImpl< DeclContext * > &Contexts)
static StringRef getRealizedPlatform(const AvailabilityAttr *A, const ASTContext &Context)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::Module class, which describes a module in the source code.
Defines types useful for describing an Objective-C runtime.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
Defines the clang::SourceLocation class and associated facilities.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any.
const LangOptions & getLangOpts() const
llvm::BumpPtrAllocator & getAllocator() const
void eraseDeclAttrs(const Decl *D)
Erase the attributes corresponding to the given declaration.
void addedLocalImportDecl(ImportDecl *Import)
Notify the AST context that a new import declaration has been parsed or implicitly created within thi...
void * Allocate(size_t Size, unsigned Align=8) const
const TargetInfo & getTargetInfo() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Module * getCurrentNamedModule() const
Get module under construction, nullptr if this is not a C++20 module.
AttrVec & getDeclAttrs(const Decl *D)
Retrieve the attributes for the given declaration.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Attr - This represents one attribute.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
The results of name lookup within a DeclContext.
decl_iterator - Iterates through the declarations stored within this context.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
udir_range using_directives() const
Returns iterator range [First, Last) of UsingDirectiveDecls stored within this context.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isFileContext() const
void setHasExternalVisibleStorage(bool ES=true) const
State whether this DeclContext has external storage for declarations visible in this context.
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
DeclContextLookupResult lookup_result
static std::pair< Decl *, Decl * > BuildDeclChain(ArrayRef< Decl * > Decls, bool FieldsAlreadyLoaded)
Build up a chain of declarations.
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
ASTContext & getParentASTContext() const
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool InEnclosingNamespaceSetOf(const DeclContext *NS) const
Test if this context is part of the enclosing namespace set of the context NS, as defined in C++0x [n...
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isLookupContext() const
Test whether the context supports looking up names.
const BlockDecl * getInnermostBlockDecl() const
Return this DeclContext if it is a BlockDecl.
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
const char * getDeclKindName() const
bool isTranslationUnit() const
void collectAllContexts(SmallVectorImpl< DeclContext * > &Contexts)
Collects all of the declaration contexts that are semantically connected to this declaration context.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
llvm::iterator_range< udir_iterator > udir_range
Decl * FirstDecl
FirstDecl - The first declaration stored within this declaration context.
DeclContext(Decl::Kind K)
void addDeclInternal(Decl *D)
Add the declaration D into this context, but suppress searches for external declarations with the sam...
bool containsDeclAndLoad(Decl *D) const
Checks whether a declaration is in this context.
void removeDecl(Decl *D)
Removes a declaration from this context.
void addDecl(Decl *D)
Add the declaration D into this context.
StoredDeclsMap * buildLookup()
Ensure the lookup structure is fully-built and return it.
bool hasValidDeclKind() const
bool isStdNamespace() const
lookup_result noload_lookup(DeclarationName Name)
Find the declarations with the given name that are visible within this context; don't attempt to retr...
static bool classof(const Decl *D)
bool containsDecl(Decl *D) const
Checks whether a declaration is in this context.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
void setUseQualifiedLookup(bool use=true) const
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Decl * LastDecl
LastDecl - The last declaration stored within this declaration context.
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
friend class DependentDiagnostic
For CreateStoredDeclsMap.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
bool isInlineNamespace() const
DeclContextBitfields DeclContextBits
bool isFunctionOrMethod() const
void setHasExternalLexicalStorage(bool ES=true) const
State whether this DeclContext has external storage for declarations lexically in this context.
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
const LinkageSpecDecl * getExternCContext() const
Retrieve the nearest enclosing C linkage specification context.
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
void localUncachedLookup(DeclarationName Name, SmallVectorImpl< NamedDecl * > &Results)
A simplistic name lookup mechanism that performs name lookup into this declaration context without co...
Decl::Kind getDeclKind() const
DeclContext * getNonTransparentContext()
decl_iterator decls_begin() const
Decl - This represents one declaration (or definition), e.g.
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
bool isInStdNamespace() const
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
bool isTemplateDecl() const
returns true if this declaration is a template
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
ASTContext & getASTContext() const LLVM_READONLY
void setAttrs(const AttrVec &Attrs)
bool hasLocalOwningModuleStorage() const
bool isFunctionPointerType() const
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
ModuleOwnershipKind getModuleOwnershipKind() const
Get the kind of module ownership for this declaration.
bool isParameterPack() const
Whether this declaration is a parameter pack.
ASTMutationListener * getASTMutationListener() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Kind
Lists the kind of concrete classes of Decl.
static unsigned getIdentifierNamespaceForKind(Kind DK)
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
bool isFileContextDecl() const
static Decl * castFromDeclContext(const DeclContext *)
Decl * getNextDeclInContext()
bool isTemplated() const
Determine whether this declaration is a templated entity (whether it is.
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
bool isReferenced() const
Whether any declaration of this entity was referenced.
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInAnotherModuleUnit() const
Whether this declaration comes from another module unit.
llvm::PointerIntPair< Decl *, 3, ModuleOwnershipKind > NextInContextAndBits
The next declaration within the same lexical DeclContext.
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
unsigned getTemplateDepth() const
Determine the number of levels of template parameter surrounding this declaration.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool canBeWeakImported(bool &IsDefinition) const
Determines whether this symbol can be weak-imported, e.g., whether it would be well-formed to add the...
static DeclContext * castToDeclContext(const Decl *)
const TemplateParameterList * getDescribedTemplateParams() const
If this is a declaration that describes some template or partial specialization, this returns the cor...
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
bool isInLocalScopeForInstantiation() const
Determine whether a substitution into this declaration would occur as part of a substitution into a d...
const Attr * getDefiningAttr() const
Return this declaration's defining attribute if it has one.
bool isTemplateParameter() const
isTemplateParameter - Determines whether this declaration is a template parameter.
DeclContext * getNonTransparentDeclContext()
Return the non transparent context.
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
bool isInvalidDecl() const
unsigned getIdentifierNamespace() const
bool hasDefiningAttr() const
Return true if this declaration has an attribute which acts as definition of the entity,...
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
void setAccess(AccessSpecifier AS)
SourceLocation getLocation() const
const char * getDeclKindName() const
@ IDNS_Ordinary
Ordinary names.
@ IDNS_Type
Types, declared with 'struct foo', typedefs, etc.
@ IDNS_OMPReduction
This declaration is an OpenMP user defined reduction construction.
@ IDNS_Label
Labels, declared with 'x:' and referenced with 'goto x'.
@ IDNS_Member
Members, declared with object declarations within tag definitions.
@ IDNS_OMPMapper
This declaration is an OpenMP user defined mapper.
@ IDNS_ObjCProtocol
Objective C @protocol.
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
@ IDNS_Using
This declaration is a using declaration.
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
void setLocalOwningModule(Module *M)
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
void setIsUsed()
Set whether the declaration is used, in the sense of odr-use.
unsigned Access
Access - Used by C++ decls for the access specifier.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
bool isInAnonymousNamespace() const
static void EnableStatistics()
TranslationUnitDecl * getTranslationUnitDecl()
VersionTuple getVersionIntroduced() const
Retrieve the version of the target platform in which this declaration was introduced.
bool hasOwningModule() const
Is this declaration owned by some module?
void updateOutOfDate(IdentifierInfo &II) const
Update a potentially out-of-date declaration.
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
@ VisibleWhenImported
This declaration has an owning module, and is visible when that module is imported.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
void setLexicalDeclContext(DeclContext *DC)
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
The name of a declaration.
A dependently-generated diagnostic.
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
RAII class for safely pairing a StartedDeserializing call with FinishedDeserializing.
Abstract interface for external sources of AST nodes.
static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl * > Decls)
static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name)
virtual Module * getModule(unsigned ID)
Retrieve the module that corresponds to the given module ID.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)
Update an out-of-date identifier.
virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name)
Find all declarations with the given name in the given context, and add them to the context by callin...
virtual void FindExternalLexicalDecls(const DeclContext *DC, llvm::function_ref< bool(Decl::Kind)> IsKindWeWant, SmallVectorImpl< Decl * > &Result)
Finds all declarations lexically contained within the given DeclContext, after applying an optional f...
Represents a function declaration or definition.
FunctionType - C99 6.7.5.3 - Function Declarators.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool trackLocalOwningModule() const
Do we need to track the owning module for a local declaration?
Represents a linkage specification.
LanguageIDs
Represents the language in a linkage specification.
Describes a module or submodule.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represent a C++ namespace.
The basic abstraction for the target Objective-C runtime.
bool hasWeakClassImport() const
Does this runtime support weakly importing classes?
PointerType - C99 6.7.5.1 - Pointer Declarators.
void print(raw_ostream &OS) const override
A (possibly-)qualified type.
QualType getCanonicalType() const
Represents a struct/union/class.
Base for LValueReferenceType and RValueReferenceType.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
Stmt - This represents one statement.
An array of decls optimized for the common case of only containing one entry.
void setHasExternalDecls()
void addOrReplaceDecl(NamedDecl *D)
If this is a redeclaration of an existing decl, replace the old one with D.
void prependDeclNoReplace(NamedDecl *D)
Add a declaration to the list without checking if it replaces anything.
static void DestroyAll(StoredDeclsMap *Map, bool Dependent)
Represents the declaration of a struct/union/class/enum.
bool isBeingDefined() const
Return true if this decl is currently being defined.
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Stores a list of template parameters for a TemplateDecl and its derived classes.
The top declaration context.
ASTContext & getASTContext() const
bool isBlockPointerType() const
bool isFunctionReferenceType() const
bool isFunctionPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
const T * getAs() const
Member-template getAs<specific type>'.
Represents C++ using-directive.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
@ C
Languages that the frontend can parse and compile.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AvailabilityResult
Captures the result of checking the availability of a declaration.
UsingDirectiveDecl * operator*() const