37 #include "llvm/ADT/ArrayRef.h" 38 #include "llvm/ADT/PointerIntPair.h" 39 #include "llvm/ADT/SmallVector.h" 40 #include "llvm/ADT/StringRef.h" 41 #include "llvm/Support/Casting.h" 42 #include "llvm/Support/ErrorHandling.h" 43 #include "llvm/Support/MathExtras.h" 44 #include "llvm/Support/VersionTuple.h" 45 #include "llvm/Support/raw_ostream.h" 53 using namespace clang;
59 #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0; 60 #define ABSTRACT_DECL(DECL) 61 #include "clang/AST/DeclNodes.inc" 67 #define DECL(DERIVED, BASE) \ 68 static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \ 69 "Alignment sufficient after objects prepended to " #DERIVED); 70 #define ABSTRACT_DECL(DECL) 71 #include "clang/AST/DeclNodes.inc" 77 static_assert(
sizeof(
unsigned) * 2 >=
alignof(
Decl),
78 "Decl won't be misaligned");
79 void *Start = Context.
Allocate(Size + Extra + 8);
80 void *
Result = (
char*)Start + 8;
82 unsigned *PrefixPtr = (
unsigned *)Result - 2;
95 assert(!
Parent || &
Parent->getParentASTContext() == &Ctx);
99 if (Ctx.getLangOpts().trackLocalOwningModule() || !
Parent) {
103 llvm::OffsetToAlignment(
sizeof(
Module *),
alignof(
Decl));
104 auto *Buffer =
reinterpret_cast<char *
>(
105 ::operator
new(ExtraAlign +
sizeof(
Module *) + Size + Extra, Ctx));
106 Buffer += ExtraAlign;
109 return new (Buffer)
Module*(ParentModule) + 1;
111 return ::operator
new(Size + Extra, Ctx);
114 Module *Decl::getOwningModuleSlow()
const {
125 default: llvm_unreachable(
"Declaration not in DeclNodes.inc!");
126 #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED; 127 #define ABSTRACT_DECL(DECL) 128 #include "clang/AST/DeclNodes.inc" 133 InvalidDecl = Invalid;
134 assert(!isa<TagDecl>(
this) || !cast<TagDecl>(
this)->isCompleteDefinition());
139 if (!isa<ParmVarDecl>(
this)) {
148 if (
auto *DD = dyn_cast<DecompositionDecl>(
this)) {
149 for (
auto *Binding : DD->bindings()) {
150 Binding->setInvalidDecl();
156 switch (getDeclKind()) {
157 #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; 158 #define ABSTRACT_DECL(DECL) 159 #include "clang/AST/DeclNodes.inc" 161 llvm_unreachable(
"Declaration context not in DeclNodes.inc!");
164 bool Decl::StatisticsEnabled =
false;
166 StatisticsEnabled =
true;
170 llvm::errs() <<
"\n*** Decl Stats:\n";
173 #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s; 174 #define ABSTRACT_DECL(DECL) 175 #include "clang/AST/DeclNodes.inc" 176 llvm::errs() <<
" " << totalDecls <<
" decls total.\n";
179 #define DECL(DERIVED, BASE) \ 180 if (n##DERIVED##s > 0) { \ 181 totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \ 182 llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \ 183 << sizeof(DERIVED##Decl) << " each (" \ 184 << n##DERIVED##s * sizeof(DERIVED##Decl) \ 187 #define ABSTRACT_DECL(DECL) 188 #include "clang/AST/DeclNodes.inc" 190 llvm::errs() <<
"Total bytes = " << totalBytes <<
"\n";
195 #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break; 196 #define ABSTRACT_DECL(DECL) 197 #include "clang/AST/DeclNodes.inc" 202 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(
this))
203 return TTP->isParameterPack();
204 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
this))
205 return NTTP->isParameterPack();
206 if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
this))
207 return TTP->isParameterPack();
212 if (
const auto *Parm = dyn_cast<ParmVarDecl>(
this))
213 return Parm->isParameterPack();
219 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
221 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
222 return FTD->getTemplatedDecl();
227 return isa<TemplateDecl>(
this);
231 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
232 return FD->getDescribedFunctionTemplate();
233 else if (
auto *RD = dyn_cast<CXXRecordDecl>(
this))
234 return RD->getDescribedClassTemplate();
235 else if (
auto *VD = dyn_cast<VarDecl>(
this))
236 return VD->getDescribedVarTemplate();
237 else if (
auto *AD = dyn_cast<TypeAliasDecl>(
this))
238 return AD->getDescribedAliasTemplate();
248 if (
auto *AsDC = dyn_cast<DeclContext>(
this))
249 return AsDC->isDependentContext();
257 DC = DC->getParent())
258 if (DC->isFunctionOrMethod())
271 TheLoc = TheDecl->getLocation();
280 if (
const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
282 DN->printQualifiedName(OS);
306 getMultipleDC()->LexicalDC = DC;
320 "hidden declaration has no owning module");
325 if (SemaDC == LexicalDC) {
328 auto *MDC =
new (Ctx) Decl::MultipleDC();
329 MDC->SemanticDC = SemaDC;
330 MDC->LexicalDC = LexicalDC;
340 if (!isa<TagDecl>(LDC))
349 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC))
350 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())
438 if (isa<TranslationUnitDecl>(
this) || isa<NamespaceDecl>(
this))
442 if (cast<Decl>(DC)->isModulePrivate())
444 if (isa<ExportDecl>(DC))
451 const Decl *Definition =
nullptr;
452 if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(
this)) {
453 Definition =
ID->getDefinition();
454 }
else if (
auto *PD = dyn_cast<ObjCProtocolDecl>(
this)) {
455 Definition = PD->getDefinition();
456 }
else if (
auto *TD = dyn_cast<TagDecl>(
this)) {
457 Definition = TD->getDefinition();
462 if (
auto *attr = Definition->
getAttr<ExternalSourceSymbolAttr>())
465 return dcd->
getAttr<ExternalSourceSymbolAttr>();
472 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
476 if (
auto *AA = getAttr<AliasAttr>())
478 if (
auto *IFA = getAttr<IFuncAttr>())
487 StringRef RealizedPlatform = A->getPlatform()->getName();
489 return RealizedPlatform;
490 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
491 if (suffix != StringRef::npos)
492 return RealizedPlatform.slice(0, suffix);
493 return RealizedPlatform;
506 const AvailabilityAttr *A,
507 std::string *Message,
508 VersionTuple EnclosingVersion) {
509 if (EnclosingVersion.empty())
512 if (EnclosingVersion.empty())
515 StringRef ActualPlatform = A->getPlatform()->getName();
522 StringRef PrettyPlatformName
523 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
525 if (PrettyPlatformName.empty())
526 PrettyPlatformName = ActualPlatform;
528 std::string HintMessage;
529 if (!A->getMessage().empty()) {
531 HintMessage += A->getMessage();
535 if (A->getUnavailable()) {
538 llvm::raw_string_ostream Out(*Message);
539 Out <<
"not available on " << PrettyPlatformName
547 if (!A->getIntroduced().empty() &&
548 EnclosingVersion < A->getIntroduced()) {
551 llvm::raw_string_ostream Out(*Message);
552 VersionTuple VTI(A->getIntroduced());
553 Out <<
"introduced in " << PrettyPlatformName <<
' ' 554 << VTI << HintMessage;
561 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
564 llvm::raw_string_ostream Out(*Message);
565 VersionTuple VTO(A->getObsoleted());
566 Out <<
"obsoleted in " << PrettyPlatformName <<
' ' 567 << VTO << HintMessage;
574 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
577 llvm::raw_string_ostream Out(*Message);
578 VersionTuple VTD(A->getDeprecated());
579 Out <<
"first deprecated in " << PrettyPlatformName <<
' ' 580 << VTD << HintMessage;
590 VersionTuple EnclosingVersion,
591 StringRef *RealizedPlatform)
const {
592 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
593 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
597 std::string ResultMessage;
599 for (
const auto *A :
attrs()) {
600 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
605 ResultMessage = Deprecated->getMessage();
611 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
613 *Message = Unavailable->getMessage();
617 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
619 Message, EnclosingVersion);
622 if (RealizedPlatform)
623 *RealizedPlatform = Availability->getPlatform()->getName();
630 ResultMessage.swap(*Message);
637 Message->swap(ResultMessage);
644 for (
const auto *A :
attrs()) {
645 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
648 if (!Availability->getIntroduced().empty())
649 return Availability->getIntroduced();
656 IsDefinition =
false;
659 if (
const auto *Var = dyn_cast<VarDecl>(
this)) {
660 if (Var->isThisDeclarationADefinition()) {
667 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
675 }
else if (isa<ObjCInterfaceDecl>(
this) &&
690 for (
const auto *A :
attrs()) {
691 if (isa<WeakImportAttr>(A))
694 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
707 case CXXDeductionGuide:
710 case ConstructorUsingShadow:
727 case NonTypeTemplateParm:
733 case ObjCCompatibleAlias:
739 case TemplateTypeParm:
743 case UnresolvedUsingTypename:
749 case UnresolvedUsingValue:
760 case ObjCAtDefsField:
773 case FunctionTemplate:
777 case TemplateTemplateParm:
778 case TypeAliasTemplate:
781 case OMPDeclareReduction:
792 case ObjCPropertyImpl:
794 case PragmaDetectMismatch:
797 case TranslationUnit:
802 case BuiltinTemplate:
803 case ClassTemplateSpecialization:
804 case ClassTemplatePartialSpecialization:
805 case ClassScopeFunctionSpecialization:
806 case VarTemplateSpecialization:
807 case VarTemplatePartialSpecialization:
808 case ObjCImplementation:
810 case ObjCCategoryImpl:
812 case OMPThreadPrivate:
814 case OMPCapturedExpr:
820 llvm_unreachable(
"Invalid DeclKind!");
824 assert(!HasAttrs &&
"Decl already contains attrs.");
827 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
834 if (!HasAttrs)
return;
855 auto I = Attrs.begin(), E = Attrs.end();
856 for (; I != E; ++I) {
857 if (!(*I)->isInherited())
864 assert(HasAttrs &&
"No attrs to get!");
871 #define DECL(NAME, BASE) 872 #define DECL_CONTEXT(NAME) \ 874 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D)); 875 #define DECL_CONTEXT_BASE(NAME) 876 #include "clang/AST/DeclNodes.inc" 878 #define DECL(NAME, BASE) 879 #define DECL_CONTEXT_BASE(NAME) \ 880 if (DK >= first##NAME && DK <= last##NAME) \ 881 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D)); 882 #include "clang/AST/DeclNodes.inc" 883 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
890 #define DECL(NAME, BASE) 891 #define DECL_CONTEXT(NAME) \ 893 return static_cast<NAME##Decl *>(const_cast<Decl *>(D)); 894 #define DECL_CONTEXT_BASE(NAME) 895 #include "clang/AST/DeclNodes.inc" 897 #define DECL(NAME, BASE) 898 #define DECL_CONTEXT_BASE(NAME) \ 899 if (DK >= first##NAME && DK <= last##NAME) \ 900 return static_cast<NAME##Decl *>(const_cast<Decl *>(D)); 901 #include "clang/AST/DeclNodes.inc" 902 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
909 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
911 if (FD->hasBody(Definition))
917 return Body->getSourceRange().getEnd();
922 bool Decl::AccessDeclContextSanity()
const {
932 if (isa<TranslationUnitDecl>(
this) ||
933 isa<TemplateTypeParmDecl>(
this) ||
934 isa<NonTypeTemplateParmDecl>(
this) ||
937 isa<StaticAssertDecl>(
this) ||
938 isa<BlockDecl>(
this) ||
941 isa<ParmVarDecl>(
this) ||
944 isa<CXXRecordDecl>(
this) ||
945 isa<ClassScopeFunctionSpecializationDecl>(
this))
949 "Access specifier is AS_none inside a record decl");
963 if (
const auto *D = dyn_cast<ValueDecl>(
this))
965 else if (
const auto *D = dyn_cast<TypedefNameDecl>(
this))
966 Ty = D->getUnderlyingType();
981 if (
getKind(D) == Decl::CXXMethod) {
982 auto *MD = cast<CXXMethodDecl>(D);
983 if (MD->getOverloadedOperator() == OO_Call &&
984 MD->getParent()->isLambda())
987 }
else if (
auto *FD = dyn_cast<FunctionDecl>(D))
989 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
991 else if (
auto *BD = dyn_cast<BlockDecl>(D))
993 else if (
auto *CD = dyn_cast<CapturedDecl>(D))
1012 DeclContextBits.DeclKind = K;
1013 setHasExternalLexicalStorage(
false);
1014 setHasExternalVisibleStorage(
false);
1015 setNeedToReconcileExternalVisibleStorage(
false);
1016 setHasLazyLocalLexicalLookups(
false);
1017 setHasLazyExternalLexicalLookups(
false);
1018 setUseQualifiedLookup(
false);
1023 #define DECL(NAME, BASE) 1024 #define DECL_CONTEXT(NAME) case Decl::NAME: 1025 #define DECL_CONTEXT_BASE(NAME) 1026 #include "clang/AST/DeclNodes.inc" 1029 #define DECL(NAME, BASE) 1030 #define DECL_CONTEXT_BASE(NAME) \ 1031 if (D->getKind() >= Decl::first##NAME && \ 1032 D->getKind() <= Decl::last##NAME) \ 1034 #include "clang/AST/DeclNodes.inc" 1049 if (isa<FunctionDecl>(
this))
1050 if (getParent()->getRedeclContext()->isFileContext() &&
1051 getLexicalParent()->getRedeclContext()->isRecord())
1052 return getLexicalParent();
1058 return isNamespace() &&
1059 cast<NamespaceDecl>(
this)->isInline();
1066 const auto *ND = cast<NamespaceDecl>(
this);
1067 if (ND->isInline()) {
1068 return ND->getParent()->isStdNamespace();
1071 if (!getParent()->getRedeclContext()->isTranslationUnit())
1075 return II && II->
isStr(
"std");
1079 if (isFileContext())
1082 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
1085 if (
const auto *Record = dyn_cast<CXXRecordDecl>(
this)) {
1086 if (Record->getDescribedClassTemplate())
1089 if (Record->isDependentLambda())
1093 if (
const auto *Function = dyn_cast<FunctionDecl>(
this)) {
1094 if (Function->getDescribedFunctionTemplate())
1099 if (cast<Decl>(
this)->getFriendObjectKind())
1100 return getLexicalParent()->isDependentContext();
1107 return getParent() && getParent()->isDependentContext();
1111 if (getDeclKind() == Decl::Enum)
1112 return !cast<EnumDecl>(
this)->isScoped();
1113 else if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
1121 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1123 return cast<LinkageSpecDecl>(DC)->getLanguage() ==
ID;
1135 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1138 return cast<LinkageSpecDecl>(DC);
1149 if (getPrimaryContext() !=
this)
1150 return getPrimaryContext()->Encloses(DC);
1159 switch (getDeclKind()) {
1160 case Decl::TranslationUnit:
1161 case Decl::ExternCContext:
1162 case Decl::LinkageSpec:
1165 case Decl::Captured:
1166 case Decl::OMPDeclareReduction:
1170 case Decl::Namespace:
1172 return static_cast<NamespaceDecl *
>(
this)->getOriginalNamespace();
1174 case Decl::ObjCMethod:
1177 case Decl::ObjCInterface:
1178 if (
auto *Def = cast<ObjCInterfaceDecl>(
this)->getDefinition())
1182 case Decl::ObjCProtocol:
1183 if (
auto *Def = cast<ObjCProtocolDecl>(
this)->getDefinition())
1187 case Decl::ObjCCategory:
1190 case Decl::ObjCImplementation:
1191 case Decl::ObjCCategoryImpl:
1195 if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
1198 auto *Tag = cast<TagDecl>(
this);
1203 if (
const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
1205 TagDecl *PossiblePartialDef = TagTy->getDecl();
1207 return PossiblePartialDef;
1209 assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1215 assert(getDeclKind() >= Decl::firstFunction &&
1216 getDeclKind() <= Decl::lastFunction &&
1217 "Unknown DeclContext kind");
1226 if (getDeclKind() != Decl::Namespace) {
1227 Contexts.push_back(
this);
1234 Contexts.push_back(N);
1236 std::reverse(Contexts.begin(), Contexts.end());
1239 std::pair<Decl *, Decl *>
1241 bool FieldsAlreadyLoaded) {
1243 Decl *FirstNewDecl =
nullptr;
1244 Decl *PrevDecl =
nullptr;
1245 for (
auto *D : Decls) {
1246 if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1257 return std::make_pair(FirstNewDecl, PrevDecl);
1263 void DeclContext::reconcileExternalVisibleStorage()
const {
1264 assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1265 setNeedToReconcileExternalVisibleStorage(
false);
1267 for (
auto &Lookup : *LookupPtr)
1268 Lookup.second.setHasExternalDecls();
1275 DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1277 assert(hasExternalLexicalStorage() && Source &&
"No external storage?");
1284 setHasExternalLexicalStorage(
false);
1292 bool FieldsAlreadyLoaded =
false;
1293 if (
const auto *RD = dyn_cast<RecordDecl>(
this))
1294 FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1298 Decl *ExternalFirst, *ExternalLast;
1299 std::tie(ExternalFirst, ExternalLast) =
1300 BuildDeclChain(Decls, FieldsAlreadyLoaded);
1302 FirstDecl = ExternalFirst;
1304 LastDecl = ExternalLast;
1313 if (!(Map = DC->LookupPtr))
1314 Map = DC->CreateStoredDeclsMap(Context);
1315 if (DC->hasNeedToReconcileExternalVisibleStorage())
1316 DC->reconcileExternalVisibleStorage();
1318 (*Map)[Name].removeExternalDecls();
1329 if (!(Map = DC->LookupPtr))
1330 Map = DC->CreateStoredDeclsMap(Context);
1331 if (DC->hasNeedToReconcileExternalVisibleStorage())
1332 DC->reconcileExternalVisibleStorage();
1345 for (
unsigned I = 0, N = Decls.size(); I != N; ++I)
1348 Skip.push_back(Decls.size());
1351 unsigned SkipPos = 0;
1352 for (
unsigned I = 0, N = Decls.size(); I != N; ++I) {
1353 if (I == Skip[SkipPos])
1360 for (
auto *D : Decls) {
1372 if (hasExternalLexicalStorage())
1373 LoadLexicalDeclsFromExternalStorage();
1378 if (hasExternalLexicalStorage())
1379 LoadLexicalDeclsFromExternalStorage();
1390 if (hasExternalLexicalStorage())
1391 LoadLexicalDeclsFromExternalStorage();
1392 return containsDecl(D);
1418 if (isa<ClassTemplateSpecializationDecl>(D))
1420 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1421 if (FD->isFunctionTemplateSpecialization())
1429 "decl being removed from non-lexical context");
1431 "decl is not in decls list");
1434 if (D == FirstDecl) {
1436 FirstDecl = LastDecl =
nullptr;
1441 assert(I &&
"decl not found in linked list");
1442 if (I->NextInContextAndBits.getPointer() == D) {
1444 if (D == LastDecl) LastDecl = I;
1454 if (isa<NamedDecl>(D)) {
1455 auto *ND = cast<NamedDecl>(D);
1463 if (!ND->getDeclName())
1470 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1471 assert(Pos != Map->end() &&
"no lookup entry for decl");
1474 if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND)
1475 Pos->second.remove(ND);
1477 }
while (DC->isTransparentContext() && (DC = DC->getParent()));
1483 "Decl inserted into wrong lexical context");
1485 "Decl already inserted into a DeclContext");
1488 LastDecl->NextInContextAndBits.setPointer(D);
1491 FirstDecl = LastDecl = D;
1496 if (
auto *Record = dyn_cast<CXXRecordDecl>(
this))
1497 Record->addedMember(D);
1502 if (
auto *Import = dyn_cast<ImportDecl>(D))
1510 if (
auto *ND = dyn_cast<NamedDecl>(D))
1511 ND->getDeclContext()->getPrimaryContext()->
1512 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1518 if (
auto *ND = dyn_cast<NamedDecl>(D))
1519 ND->getDeclContext()->getPrimaryContext()->
1520 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1531 assert(
this == getPrimaryContext() &&
"buildLookup called on non-primary DC");
1533 if (!hasLazyLocalLexicalLookups() &&
1534 !hasLazyExternalLexicalLookups())
1538 collectAllContexts(Contexts);
1540 if (hasLazyExternalLexicalLookups()) {
1541 setHasLazyExternalLexicalLookups(
false);
1542 for (
auto *DC : Contexts) {
1543 if (DC->hasExternalLexicalStorage()) {
1544 bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1545 setHasLazyLocalLexicalLookups(
1546 hasLazyLocalLexicalLookups() | LoadedDecls );
1550 if (!hasLazyLocalLexicalLookups())
1554 for (
auto *DC : Contexts)
1555 buildLookupImpl(DC, hasExternalVisibleStorage());
1558 setHasLazyLocalLexicalLookups(
false);
1566 void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1576 if (
auto *ND = dyn_cast<NamedDecl>(D))
1578 (!ND->isFromASTFile() ||
1579 (isTranslationUnit() &&
1580 !getParentASTContext().getLangOpts().CPlusPlus)))
1581 makeDeclVisibleInContextImpl(ND, Internal);
1586 if (
auto *InnerCtx = dyn_cast<DeclContext>(D))
1587 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1588 buildLookupImpl(InnerCtx, Internal);
1592 NamedDecl *
const DeclContextLookupResult::SingleElementDummyList =
nullptr;
1596 assert(getDeclKind() != Decl::LinkageSpec &&
1597 getDeclKind() != Decl::Export &&
1598 "should not perform lookups into transparent contexts");
1600 const DeclContext *PrimaryContext = getPrimaryContext();
1601 if (PrimaryContext !=
this)
1602 return PrimaryContext->
lookup(Name);
1609 (void)cast<Decl>(
this)->getMostRecentDecl();
1611 if (hasExternalVisibleStorage()) {
1612 assert(Source &&
"external visible storage but no external source?");
1614 if (hasNeedToReconcileExternalVisibleStorage())
1615 reconcileExternalVisibleStorage();
1619 if (hasLazyLocalLexicalLookups() ||
1620 hasLazyExternalLexicalLookups())
1622 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1625 Map = CreateStoredDeclsMap(getParentASTContext());
1628 std::pair<StoredDeclsMap::iterator, bool> R =
1630 if (!R.second && !R.first->second.hasExternalDecls())
1631 return R.first->second.getLookupResult();
1635 StoredDeclsMap::iterator I = Map->find(Name);
1636 if (I != Map->end())
1637 return I->second.getLookupResult();
1645 if (hasLazyLocalLexicalLookups() ||
1646 hasLazyExternalLexicalLookups())
1647 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1652 StoredDeclsMap::iterator I = Map->find(Name);
1653 if (I == Map->end())
1656 return I->second.getLookupResult();
1661 assert(getDeclKind() != Decl::LinkageSpec &&
1662 getDeclKind() != Decl::Export &&
1663 "should not perform lookups into transparent contexts");
1665 DeclContext *PrimaryContext = getPrimaryContext();
1666 if (PrimaryContext !=
this)
1669 loadLazyLocalLexicalLookups();
1674 StoredDeclsMap::iterator I = Map->find(Name);
1675 return I != Map->end() ? I->second.getLookupResult()
1682 void DeclContext::loadLazyLocalLexicalLookups() {
1683 if (hasLazyLocalLexicalLookups()) {
1685 collectAllContexts(Contexts);
1686 for (
auto *Context : Contexts)
1687 buildLookupImpl(Context, hasExternalVisibleStorage());
1688 setHasLazyLocalLexicalLookups(
false);
1698 if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
1700 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1706 if (Name && !hasLazyLocalLexicalLookups() &&
1707 !hasLazyExternalLexicalLookups()) {
1709 StoredDeclsMap::iterator Pos = Map->find(Name);
1710 if (Pos != Map->end()) {
1711 Results.insert(Results.end(),
1712 Pos->second.getLookupResult().begin(),
1713 Pos->second.getLookupResult().end());
1724 if (
auto *ND = dyn_cast<NamedDecl>(D))
1725 if (ND->getDeclName() == Name)
1726 Results.push_back(ND);
1738 bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
1761 OutermostRD = cast<RecordDecl>(DC);
1769 if (!isFileContext())
1777 if (!NS || !NS->isInline())
1786 DeclContext *PrimaryDC = this->getPrimaryContext();
1790 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1793 void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1795 assert(
this == getPrimaryContext() &&
"expected a primary DC");
1797 if (!isLookupContext()) {
1798 if (isTransparentContext())
1799 getParent()->getPrimaryContext()
1800 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1816 if (LookupPtr || hasExternalVisibleStorage() ||
1818 (getParentASTContext().getLangOpts().CPlusPlus ||
1819 !isTranslationUnit()))) {
1824 makeDeclVisibleInContextImpl(D, Internal);
1826 setHasLazyLocalLexicalLookups(
true);
1831 if (isTransparentContext() || isInlineNamespace())
1832 getParent()->getPrimaryContext()->
1833 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1835 auto *DCAsDecl = cast<Decl>(
this);
1837 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1839 L->AddedVisibleDecl(
this, D);
1842 void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1847 Map = CreateStoredDeclsMap(*C);
1856 if (hasExternalVisibleStorage() &&
1858 Source->FindExternalVisibleDeclsByName(
this, D->
getDeclName());
1873 if (DeclNameEntries.
isNull()) {
1889 return cast<UsingDirectiveDecl>(*I);
1906 assert(!LookupPtr &&
"context already has a decls map");
1907 assert(getPrimaryContext() ==
this &&
1908 "creating decls map on non-primary context");
1911 bool Dependent = isDependentContext();
1916 M->Previous = C.LastSDM;
1917 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1922 void ASTContext::ReleaseDeclContextMaps() {
1932 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1939 Map = Next.getPointer();
1940 Dependent = Next.getInt();
1948 &&
"cannot iterate dependent diagnostics of non-dependent context");
1950 if (!Parent->LookupPtr)
1951 Parent->CreateStoredDeclsMap(C);
1964 DD->NextDiagnostic = Map->FirstDiagnostic;
1965 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.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
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.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
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.
bool isExported() const
Whether this declaration is exported (by virtue of being lexically within an ExportDecl or by being a...
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.
const Attr * getDefiningAttr() const
Return this declaration's defining attribute if it has one.
Defines the clang::LangOptions interface.
static unsigned getIdentifierNamespaceForKind(Kind DK)
bool containsDecl(Decl *D) const
Checks whether a declaration is in this context.
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.
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)
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.
__DEVICE__ int max(int __a, int __b)
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()
bool isModulePrivate() const
Whether this declaration was marked as being private to the module in which it was defined...
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
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.