36 #include "llvm/ADT/ArrayRef.h" 37 #include "llvm/ADT/PointerIntPair.h" 38 #include "llvm/ADT/SmallVector.h" 39 #include "llvm/ADT/StringRef.h" 40 #include "llvm/Support/Casting.h" 41 #include "llvm/Support/ErrorHandling.h" 42 #include "llvm/Support/MathExtras.h" 43 #include "llvm/Support/VersionTuple.h" 44 #include "llvm/Support/raw_ostream.h" 52 using namespace clang;
58 #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0; 59 #define ABSTRACT_DECL(DECL) 60 #include "clang/AST/DeclNodes.inc" 66 #define DECL(DERIVED, BASE) \ 67 static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \ 68 "Alignment sufficient after objects prepended to " #DERIVED); 69 #define ABSTRACT_DECL(DECL) 70 #include "clang/AST/DeclNodes.inc" 76 static_assert(
sizeof(
unsigned) * 2 >=
alignof(
Decl),
77 "Decl won't be misaligned");
78 void *Start = Context.
Allocate(Size + Extra + 8);
79 void *
Result = (
char*)Start + 8;
81 unsigned *PrefixPtr = (
unsigned *)Result - 2;
94 assert(!
Parent || &
Parent->getParentASTContext() == &Ctx);
98 if (Ctx.getLangOpts().trackLocalOwningModule() || !
Parent) {
102 llvm::OffsetToAlignment(
sizeof(
Module *),
alignof(
Decl));
103 auto *Buffer =
reinterpret_cast<char *
>(
104 ::operator
new(ExtraAlign +
sizeof(
Module *) + Size + Extra, Ctx));
105 Buffer += ExtraAlign;
108 return new (Buffer)
Module*(ParentModule) + 1;
110 return ::operator
new(Size + Extra, Ctx);
113 Module *Decl::getOwningModuleSlow()
const {
124 default: llvm_unreachable(
"Declaration not in DeclNodes.inc!");
125 #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED; 126 #define ABSTRACT_DECL(DECL) 127 #include "clang/AST/DeclNodes.inc" 132 InvalidDecl = Invalid;
133 assert(!isa<TagDecl>(
this) || !cast<TagDecl>(
this)->isCompleteDefinition());
138 if (!isa<ParmVarDecl>(
this)) {
147 if (
auto *DD = dyn_cast<DecompositionDecl>(
this)) {
148 for (
auto *Binding : DD->bindings()) {
149 Binding->setInvalidDecl();
155 switch (getDeclKind()) {
156 #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; 157 #define ABSTRACT_DECL(DECL) 158 #include "clang/AST/DeclNodes.inc" 160 llvm_unreachable(
"Declaration context not in DeclNodes.inc!");
163 bool Decl::StatisticsEnabled =
false;
165 StatisticsEnabled =
true;
169 llvm::errs() <<
"\n*** Decl Stats:\n";
172 #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s; 173 #define ABSTRACT_DECL(DECL) 174 #include "clang/AST/DeclNodes.inc" 175 llvm::errs() <<
" " << totalDecls <<
" decls total.\n";
178 #define DECL(DERIVED, BASE) \ 179 if (n##DERIVED##s > 0) { \ 180 totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \ 181 llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \ 182 << sizeof(DERIVED##Decl) << " each (" \ 183 << n##DERIVED##s * sizeof(DERIVED##Decl) \ 186 #define ABSTRACT_DECL(DECL) 187 #include "clang/AST/DeclNodes.inc" 189 llvm::errs() <<
"Total bytes = " << totalBytes <<
"\n";
194 #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break; 195 #define ABSTRACT_DECL(DECL) 196 #include "clang/AST/DeclNodes.inc" 201 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(
this))
202 return TTP->isParameterPack();
203 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
this))
204 return NTTP->isParameterPack();
205 if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
this))
206 return TTP->isParameterPack();
211 if (
const auto *Var = dyn_cast<VarDecl>(
this))
212 return Var->isParameterPack();
218 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
220 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
221 return FTD->getTemplatedDecl();
226 return isa<TemplateDecl>(
this);
230 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
231 return FD->getDescribedFunctionTemplate();
232 else if (
auto *RD = dyn_cast<CXXRecordDecl>(
this))
233 return RD->getDescribedClassTemplate();
234 else if (
auto *VD = dyn_cast<VarDecl>(
this))
235 return VD->getDescribedVarTemplate();
236 else if (
auto *AD = dyn_cast<TypeAliasDecl>(
this))
237 return AD->getDescribedAliasTemplate();
247 if (
auto *AsDC = dyn_cast<DeclContext>(
this))
248 return AsDC->isDependentContext();
256 DC = DC->getParent())
257 if (DC->isFunctionOrMethod())
270 TheLoc = TheDecl->getLocation();
279 if (
const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
281 DN->printQualifiedName(OS);
305 getMultipleDC()->LexicalDC = DC;
319 "hidden declaration has no owning module");
324 if (SemaDC == LexicalDC) {
327 auto *MDC =
new (Ctx) Decl::MultipleDC();
328 MDC->SemanticDC = SemaDC;
329 MDC->LexicalDC = LexicalDC;
339 if (!isa<TagDecl>(LDC))
348 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC))
349 if (ND->isAnonymousNamespace())
362 if (
auto *TUD = dyn_cast<TranslationUnitDecl>(
this))
366 assert(DC &&
"This decl is not contained in a translation unit!");
370 assert(DC &&
"This decl is not contained in a translation unit!");
373 return cast<TranslationUnitDecl>(DC);
393 Align =
std::max(Align, I->getAlignment(Ctx));
427 for (
const auto *I :
redecls())
435 const Decl *Definition =
nullptr;
436 if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(
this)) {
437 Definition =
ID->getDefinition();
438 }
else if (
auto *PD = dyn_cast<ObjCProtocolDecl>(
this)) {
439 Definition = PD->getDefinition();
440 }
else if (
auto *TD = dyn_cast<TagDecl>(
this)) {
441 Definition = TD->getDefinition();
446 if (
auto *attr = Definition->
getAttr<ExternalSourceSymbolAttr>())
449 return dcd->
getAttr<ExternalSourceSymbolAttr>();
456 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
460 if (
auto *AA = getAttr<AliasAttr>())
462 if (
auto *IFA = getAttr<IFuncAttr>())
471 StringRef RealizedPlatform = A->getPlatform()->getName();
473 return RealizedPlatform;
474 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
475 if (suffix != StringRef::npos)
476 return RealizedPlatform.slice(0, suffix);
477 return RealizedPlatform;
490 const AvailabilityAttr *A,
491 std::string *Message,
492 VersionTuple EnclosingVersion) {
493 if (EnclosingVersion.empty())
496 if (EnclosingVersion.empty())
499 StringRef ActualPlatform = A->getPlatform()->getName();
506 StringRef PrettyPlatformName
507 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
509 if (PrettyPlatformName.empty())
510 PrettyPlatformName = ActualPlatform;
512 std::string HintMessage;
513 if (!A->getMessage().empty()) {
515 HintMessage += A->getMessage();
519 if (A->getUnavailable()) {
522 llvm::raw_string_ostream Out(*Message);
523 Out <<
"not available on " << PrettyPlatformName
531 if (!A->getIntroduced().empty() &&
532 EnclosingVersion < A->getIntroduced()) {
535 llvm::raw_string_ostream Out(*Message);
536 VersionTuple VTI(A->getIntroduced());
537 Out <<
"introduced in " << PrettyPlatformName <<
' ' 538 << VTI << HintMessage;
545 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
548 llvm::raw_string_ostream Out(*Message);
549 VersionTuple VTO(A->getObsoleted());
550 Out <<
"obsoleted in " << PrettyPlatformName <<
' ' 551 << VTO << HintMessage;
558 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
561 llvm::raw_string_ostream Out(*Message);
562 VersionTuple VTD(A->getDeprecated());
563 Out <<
"first deprecated in " << PrettyPlatformName <<
' ' 564 << VTD << HintMessage;
574 VersionTuple EnclosingVersion,
575 StringRef *RealizedPlatform)
const {
576 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
577 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
581 std::string ResultMessage;
583 for (
const auto *A :
attrs()) {
584 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
589 ResultMessage = Deprecated->getMessage();
595 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
597 *Message = Unavailable->getMessage();
601 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
603 Message, EnclosingVersion);
606 if (RealizedPlatform)
607 *RealizedPlatform = Availability->getPlatform()->getName();
614 ResultMessage.swap(*Message);
621 Message->swap(ResultMessage);
628 for (
const auto *A :
attrs()) {
629 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
632 if (!Availability->getIntroduced().empty())
633 return Availability->getIntroduced();
640 IsDefinition =
false;
643 if (
const auto *Var = dyn_cast<VarDecl>(
this)) {
644 if (Var->isThisDeclarationADefinition()) {
651 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
659 }
else if (isa<ObjCInterfaceDecl>(
this) &&
674 for (
const auto *A :
attrs()) {
675 if (isa<WeakImportAttr>(A))
678 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
691 case CXXDeductionGuide:
694 case ConstructorUsingShadow:
711 case NonTypeTemplateParm:
718 case ObjCCompatibleAlias:
724 case TemplateTypeParm:
728 case UnresolvedUsingTypename:
734 case UnresolvedUsingValue:
745 case ObjCAtDefsField:
758 case FunctionTemplate:
762 case TemplateTemplateParm:
763 case TypeAliasTemplate:
766 case OMPDeclareReduction:
769 case OMPDeclareMapper:
780 case ObjCPropertyImpl:
782 case PragmaDetectMismatch:
785 case TranslationUnit:
790 case BuiltinTemplate:
791 case ClassTemplateSpecialization:
792 case ClassTemplatePartialSpecialization:
793 case ClassScopeFunctionSpecialization:
794 case VarTemplateSpecialization:
795 case VarTemplatePartialSpecialization:
796 case ObjCImplementation:
798 case ObjCCategoryImpl:
800 case OMPThreadPrivate:
803 case OMPCapturedExpr:
809 llvm_unreachable(
"Invalid DeclKind!");
813 assert(!HasAttrs &&
"Decl already contains attrs.");
816 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
823 if (!HasAttrs)
return;
844 auto I = Attrs.begin(), E = Attrs.end();
845 for (; I != E; ++I) {
846 if (!(*I)->isInherited())
853 assert(HasAttrs &&
"No attrs to get!");
860 #define DECL(NAME, BASE) 861 #define DECL_CONTEXT(NAME) \ 863 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D)); 864 #define DECL_CONTEXT_BASE(NAME) 865 #include "clang/AST/DeclNodes.inc" 867 #define DECL(NAME, BASE) 868 #define DECL_CONTEXT_BASE(NAME) \ 869 if (DK >= first##NAME && DK <= last##NAME) \ 870 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D)); 871 #include "clang/AST/DeclNodes.inc" 872 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
879 #define DECL(NAME, BASE) 880 #define DECL_CONTEXT(NAME) \ 882 return static_cast<NAME##Decl *>(const_cast<Decl *>(D)); 883 #define DECL_CONTEXT_BASE(NAME) 884 #include "clang/AST/DeclNodes.inc" 886 #define DECL(NAME, BASE) 887 #define DECL_CONTEXT_BASE(NAME) \ 888 if (DK >= first##NAME && DK <= last##NAME) \ 889 return static_cast<NAME##Decl *>(const_cast<Decl *>(D)); 890 #include "clang/AST/DeclNodes.inc" 891 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
898 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
900 if (FD->hasBody(Definition))
906 return Body->getSourceRange().getEnd();
911 bool Decl::AccessDeclContextSanity()
const {
921 if (isa<TranslationUnitDecl>(
this) ||
922 isa<TemplateTypeParmDecl>(
this) ||
923 isa<NonTypeTemplateParmDecl>(
this) ||
927 isa<StaticAssertDecl>(
this) ||
928 isa<BlockDecl>(
this) ||
931 isa<ParmVarDecl>(
this) ||
934 isa<CXXRecordDecl>(
this) ||
935 isa<ClassScopeFunctionSpecializationDecl>(
this))
939 "Access specifier is AS_none inside a record decl");
953 if (
const auto *D = dyn_cast<ValueDecl>(
this))
955 else if (
const auto *D = dyn_cast<TypedefNameDecl>(
this))
956 Ty = D->getUnderlyingType();
973 if (
getKind(D) == Decl::CXXMethod) {
974 auto *MD = cast<CXXMethodDecl>(D);
975 if (MD->getOverloadedOperator() == OO_Call &&
976 MD->getParent()->isLambda())
979 }
else if (
auto *FD = dyn_cast<FunctionDecl>(D))
981 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
983 else if (
auto *BD = dyn_cast<BlockDecl>(D))
985 else if (
auto *CD = dyn_cast<CapturedDecl>(D))
1004 DeclContextBits.DeclKind = K;
1005 setHasExternalLexicalStorage(
false);
1006 setHasExternalVisibleStorage(
false);
1007 setNeedToReconcileExternalVisibleStorage(
false);
1008 setHasLazyLocalLexicalLookups(
false);
1009 setHasLazyExternalLexicalLookups(
false);
1010 setUseQualifiedLookup(
false);
1015 #define DECL(NAME, BASE) 1016 #define DECL_CONTEXT(NAME) case Decl::NAME: 1017 #define DECL_CONTEXT_BASE(NAME) 1018 #include "clang/AST/DeclNodes.inc" 1021 #define DECL(NAME, BASE) 1022 #define DECL_CONTEXT_BASE(NAME) \ 1023 if (D->getKind() >= Decl::first##NAME && \ 1024 D->getKind() <= Decl::last##NAME) \ 1026 #include "clang/AST/DeclNodes.inc" 1041 if (isa<FunctionDecl>(
this))
1042 if (getParent()->getRedeclContext()->isFileContext() &&
1043 getLexicalParent()->getRedeclContext()->isRecord())
1044 return getLexicalParent();
1054 return cast<BlockDecl>(Ctx);
1062 return isNamespace() &&
1063 cast<NamespaceDecl>(
this)->isInline();
1070 const auto *ND = cast<NamespaceDecl>(
this);
1071 if (ND->isInline()) {
1072 return ND->getParent()->isStdNamespace();
1075 if (!getParent()->getRedeclContext()->isTranslationUnit())
1079 return II && II->
isStr(
"std");
1083 if (isFileContext())
1086 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
1089 if (
const auto *Record = dyn_cast<CXXRecordDecl>(
this)) {
1090 if (Record->getDescribedClassTemplate())
1093 if (Record->isDependentLambda())
1097 if (
const auto *Function = dyn_cast<FunctionDecl>(
this)) {
1098 if (Function->getDescribedFunctionTemplate())
1103 if (cast<Decl>(
this)->getFriendObjectKind())
1104 return getLexicalParent()->isDependentContext();
1111 return getParent() && getParent()->isDependentContext();
1115 if (getDeclKind() == Decl::Enum)
1116 return !cast<EnumDecl>(
this)->isScoped();
1117 else if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
1125 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1127 return cast<LinkageSpecDecl>(DC)->getLanguage() ==
ID;
1139 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1142 return cast<LinkageSpecDecl>(DC);
1153 if (getPrimaryContext() !=
this)
1154 return getPrimaryContext()->Encloses(DC);
1163 switch (getDeclKind()) {
1164 case Decl::TranslationUnit:
1165 case Decl::ExternCContext:
1166 case Decl::LinkageSpec:
1169 case Decl::Captured:
1170 case Decl::OMPDeclareReduction:
1171 case Decl::OMPDeclareMapper:
1175 case Decl::Namespace:
1177 return static_cast<NamespaceDecl *
>(
this)->getOriginalNamespace();
1179 case Decl::ObjCMethod:
1182 case Decl::ObjCInterface:
1183 if (
auto *OID = dyn_cast<ObjCInterfaceDecl>(
this))
1184 if (
auto *Def = OID->getDefinition())
1188 case Decl::ObjCProtocol:
1189 if (
auto *OPD = dyn_cast<ObjCProtocolDecl>(
this))
1190 if (
auto *Def = OPD->getDefinition())
1194 case Decl::ObjCCategory:
1197 case Decl::ObjCImplementation:
1198 case Decl::ObjCCategoryImpl:
1202 if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
1205 auto *Tag = cast<TagDecl>(
this);
1210 if (
const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
1212 TagDecl *PossiblePartialDef = TagTy->getDecl();
1214 return PossiblePartialDef;
1216 assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1222 assert(getDeclKind() >= Decl::firstFunction &&
1223 getDeclKind() <= Decl::lastFunction &&
1224 "Unknown DeclContext kind");
1233 if (getDeclKind() != Decl::Namespace) {
1234 Contexts.push_back(
this);
1241 Contexts.push_back(N);
1243 std::reverse(Contexts.begin(), Contexts.end());
1246 std::pair<Decl *, Decl *>
1248 bool FieldsAlreadyLoaded) {
1250 Decl *FirstNewDecl =
nullptr;
1251 Decl *PrevDecl =
nullptr;
1252 for (
auto *D : Decls) {
1253 if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1264 return std::make_pair(FirstNewDecl, PrevDecl);
1270 void DeclContext::reconcileExternalVisibleStorage()
const {
1271 assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1272 setNeedToReconcileExternalVisibleStorage(
false);
1274 for (
auto &Lookup : *LookupPtr)
1275 Lookup.second.setHasExternalDecls();
1282 DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1284 assert(hasExternalLexicalStorage() && Source &&
"No external storage?");
1291 setHasExternalLexicalStorage(
false);
1299 bool FieldsAlreadyLoaded =
false;
1300 if (
const auto *RD = dyn_cast<RecordDecl>(
this))
1301 FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1305 Decl *ExternalFirst, *ExternalLast;
1306 std::tie(ExternalFirst, ExternalLast) =
1307 BuildDeclChain(Decls, FieldsAlreadyLoaded);
1309 FirstDecl = ExternalFirst;
1311 LastDecl = ExternalLast;
1320 if (!(Map = DC->LookupPtr))
1321 Map = DC->CreateStoredDeclsMap(Context);
1322 if (DC->hasNeedToReconcileExternalVisibleStorage())
1323 DC->reconcileExternalVisibleStorage();
1325 (*Map)[Name].removeExternalDecls();
1336 if (!(Map = DC->LookupPtr))
1337 Map = DC->CreateStoredDeclsMap(Context);
1338 if (DC->hasNeedToReconcileExternalVisibleStorage())
1339 DC->reconcileExternalVisibleStorage();
1352 for (
unsigned I = 0, N = Decls.size(); I != N; ++I)
1355 Skip.push_back(Decls.size());
1358 unsigned SkipPos = 0;
1359 for (
unsigned I = 0, N = Decls.size(); I != N; ++I) {
1360 if (I == Skip[SkipPos])
1367 for (
auto *D : Decls) {
1379 if (hasExternalLexicalStorage())
1380 LoadLexicalDeclsFromExternalStorage();
1385 if (hasExternalLexicalStorage())
1386 LoadLexicalDeclsFromExternalStorage();
1397 if (hasExternalLexicalStorage())
1398 LoadLexicalDeclsFromExternalStorage();
1399 return containsDecl(D);
1425 if (isa<ClassTemplateSpecializationDecl>(D))
1427 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1428 if (FD->isFunctionTemplateSpecialization())
1436 "decl being removed from non-lexical context");
1438 "decl is not in decls list");
1441 if (D == FirstDecl) {
1443 FirstDecl = LastDecl =
nullptr;
1448 assert(I &&
"decl not found in linked list");
1449 if (I->NextInContextAndBits.getPointer() == D) {
1451 if (D == LastDecl) LastDecl = I;
1461 if (isa<NamedDecl>(D)) {
1462 auto *ND = cast<NamedDecl>(D);
1470 if (!ND->getDeclName())
1477 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1478 assert(Pos != Map->end() &&
"no lookup entry for decl");
1481 if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND)
1482 Pos->second.remove(ND);
1484 }
while (DC->isTransparentContext() && (DC = DC->getParent()));
1490 "Decl inserted into wrong lexical context");
1492 "Decl already inserted into a DeclContext");
1495 LastDecl->NextInContextAndBits.setPointer(D);
1498 FirstDecl = LastDecl = D;
1503 if (
auto *Record = dyn_cast<CXXRecordDecl>(
this))
1504 Record->addedMember(D);
1509 if (
auto *Import = dyn_cast<ImportDecl>(D))
1517 if (
auto *ND = dyn_cast<NamedDecl>(D))
1518 ND->getDeclContext()->getPrimaryContext()->
1519 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1525 if (
auto *ND = dyn_cast<NamedDecl>(D))
1526 ND->getDeclContext()->getPrimaryContext()->
1527 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1538 assert(
this == getPrimaryContext() &&
"buildLookup called on non-primary DC");
1540 if (!hasLazyLocalLexicalLookups() &&
1541 !hasLazyExternalLexicalLookups())
1545 collectAllContexts(Contexts);
1547 if (hasLazyExternalLexicalLookups()) {
1548 setHasLazyExternalLexicalLookups(
false);
1549 for (
auto *DC : Contexts) {
1550 if (DC->hasExternalLexicalStorage()) {
1551 bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1552 setHasLazyLocalLexicalLookups(
1553 hasLazyLocalLexicalLookups() | LoadedDecls );
1557 if (!hasLazyLocalLexicalLookups())
1561 for (
auto *DC : Contexts)
1562 buildLookupImpl(DC, hasExternalVisibleStorage());
1565 setHasLazyLocalLexicalLookups(
false);
1573 void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1583 if (
auto *ND = dyn_cast<NamedDecl>(D))
1585 (!ND->isFromASTFile() ||
1586 (isTranslationUnit() &&
1587 !getParentASTContext().getLangOpts().CPlusPlus)))
1588 makeDeclVisibleInContextImpl(ND, Internal);
1593 if (
auto *InnerCtx = dyn_cast<DeclContext>(D))
1594 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1595 buildLookupImpl(InnerCtx, Internal);
1599 NamedDecl *
const DeclContextLookupResult::SingleElementDummyList =
nullptr;
1603 assert(getDeclKind() != Decl::LinkageSpec &&
1604 getDeclKind() != Decl::Export &&
1605 "should not perform lookups into transparent contexts");
1607 const DeclContext *PrimaryContext = getPrimaryContext();
1608 if (PrimaryContext !=
this)
1609 return PrimaryContext->
lookup(Name);
1616 (void)cast<Decl>(
this)->getMostRecentDecl();
1618 if (hasExternalVisibleStorage()) {
1619 assert(Source &&
"external visible storage but no external source?");
1621 if (hasNeedToReconcileExternalVisibleStorage())
1622 reconcileExternalVisibleStorage();
1626 if (hasLazyLocalLexicalLookups() ||
1627 hasLazyExternalLexicalLookups())
1629 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1632 Map = CreateStoredDeclsMap(getParentASTContext());
1635 std::pair<StoredDeclsMap::iterator, bool> R =
1637 if (!R.second && !R.first->second.hasExternalDecls())
1638 return R.first->second.getLookupResult();
1642 StoredDeclsMap::iterator I = Map->find(Name);
1643 if (I != Map->end())
1644 return I->second.getLookupResult();
1652 if (hasLazyLocalLexicalLookups() ||
1653 hasLazyExternalLexicalLookups())
1654 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1659 StoredDeclsMap::iterator I = Map->find(Name);
1660 if (I == Map->end())
1663 return I->second.getLookupResult();
1668 assert(getDeclKind() != Decl::LinkageSpec &&
1669 getDeclKind() != Decl::Export &&
1670 "should not perform lookups into transparent contexts");
1672 DeclContext *PrimaryContext = getPrimaryContext();
1673 if (PrimaryContext !=
this)
1676 loadLazyLocalLexicalLookups();
1681 StoredDeclsMap::iterator I = Map->find(Name);
1682 return I != Map->end() ? I->second.getLookupResult()
1689 void DeclContext::loadLazyLocalLexicalLookups() {
1690 if (hasLazyLocalLexicalLookups()) {
1692 collectAllContexts(Contexts);
1693 for (
auto *Context : Contexts)
1694 buildLookupImpl(Context, hasExternalVisibleStorage());
1695 setHasLazyLocalLexicalLookups(
false);
1705 if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
1707 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1713 if (Name && !hasLazyLocalLexicalLookups() &&
1714 !hasLazyExternalLexicalLookups()) {
1716 StoredDeclsMap::iterator Pos = Map->find(Name);
1717 if (Pos != Map->end()) {
1718 Results.insert(Results.end(),
1719 Pos->second.getLookupResult().begin(),
1720 Pos->second.getLookupResult().end());
1731 if (
auto *ND = dyn_cast<NamedDecl>(D))
1732 if (ND->getDeclName() == Name)
1733 Results.push_back(ND);
1745 bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
1768 OutermostRD = cast<RecordDecl>(DC);
1776 if (!isFileContext())
1784 if (!NS || !NS->isInline())
1793 DeclContext *PrimaryDC = this->getPrimaryContext();
1797 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1800 void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1802 assert(
this == getPrimaryContext() &&
"expected a primary DC");
1804 if (!isLookupContext()) {
1805 if (isTransparentContext())
1806 getParent()->getPrimaryContext()
1807 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1823 if (LookupPtr || hasExternalVisibleStorage() ||
1825 (getParentASTContext().getLangOpts().CPlusPlus ||
1826 !isTranslationUnit()))) {
1831 makeDeclVisibleInContextImpl(D, Internal);
1833 setHasLazyLocalLexicalLookups(
true);
1838 if (isTransparentContext() || isInlineNamespace())
1839 getParent()->getPrimaryContext()->
1840 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1842 auto *DCAsDecl = cast<Decl>(
this);
1844 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1846 L->AddedVisibleDecl(
this, D);
1849 void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1854 Map = CreateStoredDeclsMap(*C);
1863 if (hasExternalVisibleStorage() &&
1865 Source->FindExternalVisibleDeclsByName(
this, D->
getDeclName());
1880 if (DeclNameEntries.
isNull()) {
1896 return cast<UsingDirectiveDecl>(*I);
1913 assert(!LookupPtr &&
"context already has a decls map");
1914 assert(getPrimaryContext() ==
this &&
1915 "creating decls map on non-primary context");
1918 bool Dependent = isDependentContext();
1923 M->Previous = C.LastSDM;
1924 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1929 void ASTContext::ReleaseDeclContextMaps() {
1939 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1946 Map = Next.getPointer();
1947 Dependent = Next.getInt();
1955 &&
"cannot iterate dependent diagnostics of non-dependent context");
1957 if (!Parent->LookupPtr)
1958 Parent->CreateStoredDeclsMap(C);
1971 DD->NextDiagnostic = Map->FirstDiagnostic;
1972 Map->FirstDiagnostic = DD;
static StringRef getRealizedPlatform(const AvailabilityAttr *A, const ASTContext &Context)
Defines the clang::ASTContext interface.
Represents a function declaration or definition.
void setHasExternalDecls()
AttrVec & getDeclAttrs(const Decl *D)
Retrieve the attributes for the given declaration.
void localUncachedLookup(DeclarationName Name, SmallVectorImpl< NamedDecl *> &Results)
A simplistic name lookup mechanism that performs name lookup into this declaration context without co...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled...
static DeclContext * castToDeclContext(const Decl *)
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
static bool shouldBeHidden(NamedDecl *D)
shouldBeHidden - Determine whether a declaration which was declared within its semantic context shoul...
A (possibly-)qualified type.
bool isBlockPointerType() const
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
const char * getDeclKindName() const
llvm::PointerIntPair< Decl *, 2, ModuleOwnershipKind > NextInContextAndBits
The next declaration within the same lexical DeclContext.
void AddSubsequentDecl(NamedDecl *D)
AddSubsequentDecl - This is called on the second and later decl when it is not a redeclaration to mer...
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...
RAII class for safely pairing a StartedDeserializing call with FinishedDeserializing.
static Decl * castFromDeclContext(const DeclContext *)
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
void setAttrs(const AttrVec &Attrs)
static bool isLinkageSpecContext(const DeclContext *DC, LinkageSpecDecl::LanguageIDs ID)
Stmt - This represents one statement.
FunctionType - C99 6.7.5.3 - Function Declarators.
C Language Family Type Representation.
const char * getDeclKindName() const
Decl - This represents one declaration (or definition), e.g.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Defines the C++ template declaration subclasses.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration, or NULL if there is no previous declaration.
Defines types useful for describing an Objective-C runtime.
Represent a C++ namespace.
const TargetInfo & getTargetInfo() const
unsigned getIdentifierNamespace() const
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...
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
unsigned Access
Access - Used by C++ decls for the access specifier.
bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer)
HandleRedeclaration - If this is a redeclaration of an existing decl, replace the old one with D and ...
bool hasOwningModule() const
Is this declaration owned by some module?
ASTMutationListener * getASTMutationListener() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasLocalOwningModuleStorage() const
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isInvalidDecl() const
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
bool isParameterPack() const
Whether this declaration is a parameter pack.
void removeDecl(Decl *D)
Removes a declaration from this context.
bool hasWeakClassImport() const
Does this runtime support weakly importing classes?
Types, declared with 'struct foo', typedefs, etc.
bool isLexicallyWithinFunctionOrMethod() const
Returns true if this declaration lexically is inside a function.
Represents a struct/union/class.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
One of these records is kept for each identifier that is lexed.
bool isInAnonymousNamespace() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl *> Decls)
QualType getPointeeType() const
void print(raw_ostream &OS, const SourceManager &SM) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
The results of name lookup within a DeclContext.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
__DEVICE__ int max(int __a, int __b)
Describes a module or submodule.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)
Update an out-of-date identifier.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
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...
Namespaces, declared with 'namespace foo {}'.
bool isReferenced() const
Whether any declaration of this entity was referenced.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
ModuleOwnershipKind getModuleOwnershipKind() const
Get the kind of module ownership for this declaration.
StoredDeclsMap * buildLookup()
Ensure the lookup structure is fully-built and return it.
static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name)
ASTContext & getASTContext() const
void eraseDeclAttrs(const Decl *D)
Erase the attributes corresponding to the given declaration.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
Labels, declared with 'x:' and referenced with 'goto x'.
void setLocalOwningModule(Module *M)
Represents a linkage specification.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
void addDeclInternal(Decl *D)
Add the declaration D into this context, but suppress searches for external declarations with the sam...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
AvailabilityResult
Captures the result of checking the availability of a declaration.
Decl * getNextDeclInContext()
bool canBeWeakImported(bool &IsDefinition) const
Determines whether this symbol can be weak-imported, e.g., whether it would be well-formed to add the...
udir_range using_directives() const
Returns iterator range [First, Last) of UsingDirectiveDecls stored within this context.
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
llvm::iterator_range< udir_iterator > udir_range
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible. ...
void removeExternalDecls()
Remove any declarations which were imported from an external AST source.
bool isInlineNamespace() const
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
const Attr * getDefiningAttr() const
Return this declaration's defining attribute if it has one.
Defines the clang::LangOptions interface.
QualType getPointeeType() const
static unsigned getIdentifierNamespaceForKind(Kind DK)
bool containsDecl(Decl *D) const
Checks whether a declaration is in this context.
bool isFunctionReferenceType() const
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
This declaration is an OpenMP user defined reduction construction.
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...
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
bool isLocalExternDecl()
Determine whether this is a block-scope declaration with linkage.
bool isFileContext() const
DeclContext * getDeclContext()
lookup_result noload_lookup(DeclarationName Name)
Find the declarations with the given name that are visible within this context; don't attempt to retr...
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
bool isTemplateParameter() const
isTemplateParameter - Determines whether this declaration is a template parameter.
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack...
bool containsDeclAndLoad(Decl *D) const
Checks whether a declaration is in this context.
This declaration is an OpenMP user defined mapper.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool isFunctionOrMethod() const
clang::ObjCRuntime ObjCRuntime
This declaration has an owning module, and is visible when that module is imported.
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl, 0 if there are none.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
void collectAllContexts(SmallVectorImpl< DeclContext *> &Contexts)
Collects all of the declaration contexts that are semantically connected to this declaration context...
SourceLocation getEnd() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
The result type of a method or function.
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so...
virtual void DeclarationMarkedUsed(const Decl *D)
A declaration is marked used which was not previously marked used.
Abstract interface for external sources of AST nodes.
bool isTemplateDecl() const
returns true if this declaration is a template
Decl::Kind getDeclKind() const
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
DeclContext::lookup_result getLookupResult()
getLookupResult - Return an array of all the decls that this list represents.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
VersionTuple getVersionIntroduced() const
Retrieve the version of the target platform in which this declaration was introduced.
Encodes a location in the source.
Members, declared with object declarations within tag definitions.
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
decl_iterator decls_begin() const
Represents the declaration of a struct/union/class/enum.
ASTContext & getASTContext() const LLVM_READONLY
bool isStdNamespace() const
This file defines OpenMP nodes for declarative directives.
void print(raw_ostream &OS) const override
DeclContext(Decl::Kind K)
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
UsingDirectiveDecl * operator*() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
An array of decls optimized for the common case of only containing one entry.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
void * Allocate(size_t Size, unsigned Align=8) const
decl_iterator - Iterates through the declarations stored within this context.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Dataflow Directional Tag Classes.
void updateOutOfDate(IdentifierInfo &II) const
Update a potentially out-of-date declaration.
bool isValid() const
Return true if this is a valid SourceLocation object.
virtual Module * getModule(unsigned ID)
Retrieve the module that corresponds to the given module ID.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
The base class of all kinds of template declarations (e.g., class, function, etc.).
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
The name of a declaration.
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks, lambdas, etc.
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
llvm::BumpPtrAllocator & getAllocator() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
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)
void setIsUsed()
Set whether the declaration is used, in the sense of odr-use.
LanguageIDs
Represents the language in a linkage specification.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
void setOnlyValue(NamedDecl *ND)
Base for LValueReferenceType and RValueReferenceType.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
const LinkageSpecDecl * getExternCContext() const
Retrieve the nearest enclosing C linkage specification context.
void addDecl(Decl *D)
Add the declaration D into this context.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Defines the clang::SourceLocation class and associated facilities.
DeclContextLookupResult lookup_result
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
static std::pair< Decl *, Decl * > BuildDeclChain(ArrayRef< Decl *> Decls, bool FieldsAlreadyLoaded)
Build up a chain of declarations.
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
static bool classof(const Decl *D)
Defines the clang::TargetInfo interface.
ASTContext & getParentASTContext() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Kind
Lists the kind of concrete classes of Decl.
The top declaration context.
static void DestroyAll(StoredDeclsMap *Map, bool Dependent)
NamedDecl * getMostRecentDecl()
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
bool trackLocalOwningModule() const
Do we need to track the owning module for a local declaration?
static void EnableStatistics()
void setLexicalDeclContext(DeclContext *DC)
This represents a decl that may have a name.
bool isTranslationUnit() const
void setAccess(AccessSpecifier AS)
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration...
Represents C++ using-directive.
bool hasDefiningAttr() const
Return true if this declaration has an attribute which acts as definition of the entity, such as 'alias' or 'ifunc'.
bool isFunctionPointerType() const
void addedLocalImportDecl(ImportDecl *Import)
Notify the AST context that a new import declaration has been parsed or implicitly created within thi...
bool isInStdNamespace() const
TranslationUnitDecl * getTranslationUnitDecl()
const LangOptions & getLangOpts() const
const BlockDecl * getInnermostBlockDecl() const
Return this DeclContext if it is a BlockDecl.
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isTemplated() const
Determine whether this declaration is a templated entity (whether it is.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
Attr - This represents one attribute.
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. ...
bool isBeingDefined() const
Return true if this decl is currently being defined.
This declaration is a using declaration.
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context, meaning that the members declared in this context are semantically declared in the nearest enclosing non-transparent (opaque) context but are lexically declared in this context.