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 *), llvm::Align(
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 *Var = dyn_cast<VarDecl>(
this))
213 return Var->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())
363 if (
auto *TUD = dyn_cast<TranslationUnitDecl>(
this))
367 assert(DC &&
"This decl is not contained in a translation unit!");
371 assert(DC &&
"This decl is not contained in a translation unit!");
374 return cast<TranslationUnitDecl>(DC);
394 Align =
std::max(Align, I->getAlignment(Ctx));
428 for (
const auto *I :
redecls())
436 const Decl *Definition =
nullptr;
437 if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(
this)) {
438 Definition =
ID->getDefinition();
439 }
else if (
auto *PD = dyn_cast<ObjCProtocolDecl>(
this)) {
440 Definition = PD->getDefinition();
441 }
else if (
auto *TD = dyn_cast<TagDecl>(
this)) {
442 Definition = TD->getDefinition();
447 if (
auto *attr = Definition->
getAttr<ExternalSourceSymbolAttr>())
450 return dcd->
getAttr<ExternalSourceSymbolAttr>();
457 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
461 if (
auto *AA = getAttr<AliasAttr>())
463 if (
auto *IFA = getAttr<IFuncAttr>())
472 StringRef RealizedPlatform = A->getPlatform()->getName();
474 return RealizedPlatform;
475 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
476 if (suffix != StringRef::npos)
477 return RealizedPlatform.slice(0, suffix);
478 return RealizedPlatform;
491 const AvailabilityAttr *A,
492 std::string *Message,
493 VersionTuple EnclosingVersion) {
494 if (EnclosingVersion.empty())
497 if (EnclosingVersion.empty())
500 StringRef ActualPlatform = A->getPlatform()->getName();
507 StringRef PrettyPlatformName
508 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
510 if (PrettyPlatformName.empty())
511 PrettyPlatformName = ActualPlatform;
513 std::string HintMessage;
514 if (!A->getMessage().empty()) {
516 HintMessage += A->getMessage();
520 if (A->getUnavailable()) {
523 llvm::raw_string_ostream Out(*Message);
524 Out <<
"not available on " << PrettyPlatformName
532 if (!A->getIntroduced().empty() &&
533 EnclosingVersion < A->getIntroduced()) {
536 llvm::raw_string_ostream Out(*Message);
537 VersionTuple VTI(A->getIntroduced());
538 Out <<
"introduced in " << PrettyPlatformName <<
' ' 539 << VTI << HintMessage;
546 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
549 llvm::raw_string_ostream Out(*Message);
550 VersionTuple VTO(A->getObsoleted());
551 Out <<
"obsoleted in " << PrettyPlatformName <<
' ' 552 << VTO << HintMessage;
559 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
562 llvm::raw_string_ostream Out(*Message);
563 VersionTuple VTD(A->getDeprecated());
564 Out <<
"first deprecated in " << PrettyPlatformName <<
' ' 565 << VTD << HintMessage;
575 VersionTuple EnclosingVersion,
576 StringRef *RealizedPlatform)
const {
577 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
578 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
582 std::string ResultMessage;
584 for (
const auto *A :
attrs()) {
585 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
590 ResultMessage = Deprecated->getMessage();
596 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
598 *Message = Unavailable->getMessage();
602 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
604 Message, EnclosingVersion);
607 if (RealizedPlatform)
608 *RealizedPlatform = Availability->getPlatform()->getName();
615 ResultMessage.swap(*Message);
622 Message->swap(ResultMessage);
629 for (
const auto *A :
attrs()) {
630 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
633 if (!Availability->getIntroduced().empty())
634 return Availability->getIntroduced();
641 IsDefinition =
false;
644 if (
const auto *Var = dyn_cast<VarDecl>(
this)) {
645 if (Var->isThisDeclarationADefinition()) {
652 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
660 }
else if (isa<ObjCInterfaceDecl>(
this) &&
675 for (
const auto *A :
attrs()) {
676 if (isa<WeakImportAttr>(A))
679 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
692 case CXXDeductionGuide:
695 case ConstructorUsingShadow:
712 case NonTypeTemplateParm:
719 case ObjCCompatibleAlias:
725 case TemplateTypeParm:
729 case UnresolvedUsingTypename:
735 case UnresolvedUsingValue:
746 case ObjCAtDefsField:
759 case FunctionTemplate:
763 case TemplateTemplateParm:
764 case TypeAliasTemplate:
767 case OMPDeclareReduction:
770 case OMPDeclareMapper:
781 case ObjCPropertyImpl:
783 case PragmaDetectMismatch:
786 case TranslationUnit:
791 case BuiltinTemplate:
792 case ClassTemplateSpecialization:
793 case ClassTemplatePartialSpecialization:
794 case ClassScopeFunctionSpecialization:
795 case VarTemplateSpecialization:
796 case VarTemplatePartialSpecialization:
797 case ObjCImplementation:
799 case ObjCCategoryImpl:
801 case OMPThreadPrivate:
804 case OMPCapturedExpr:
806 case LifetimeExtendedTemporary:
807 case RequiresExprBody:
812 llvm_unreachable(
"Invalid DeclKind!");
816 assert(!HasAttrs &&
"Decl already contains attrs.");
819 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
826 if (!HasAttrs)
return;
847 auto I = Attrs.begin(), E = Attrs.end();
848 for (; I != E; ++I) {
849 if (!(*I)->isInherited())
856 assert(HasAttrs &&
"No attrs to get!");
863 #define DECL(NAME, BASE) 864 #define DECL_CONTEXT(NAME) \ 866 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D)); 867 #define DECL_CONTEXT_BASE(NAME) 868 #include "clang/AST/DeclNodes.inc" 870 #define DECL(NAME, BASE) 871 #define DECL_CONTEXT_BASE(NAME) \ 872 if (DK >= first##NAME && DK <= last##NAME) \ 873 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D)); 874 #include "clang/AST/DeclNodes.inc" 875 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
882 #define DECL(NAME, BASE) 883 #define DECL_CONTEXT(NAME) \ 885 return static_cast<NAME##Decl *>(const_cast<Decl *>(D)); 886 #define DECL_CONTEXT_BASE(NAME) 887 #include "clang/AST/DeclNodes.inc" 889 #define DECL(NAME, BASE) 890 #define DECL_CONTEXT_BASE(NAME) \ 891 if (DK >= first##NAME && DK <= last##NAME) \ 892 return static_cast<NAME##Decl *>(const_cast<Decl *>(D)); 893 #include "clang/AST/DeclNodes.inc" 894 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
901 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
903 if (FD->hasBody(Definition))
909 return Body->getSourceRange().getEnd();
914 bool Decl::AccessDeclContextSanity()
const {
924 if (isa<TranslationUnitDecl>(
this) ||
925 isa<TemplateTypeParmDecl>(
this) ||
926 isa<NonTypeTemplateParmDecl>(
this) ||
930 isa<StaticAssertDecl>(
this) ||
931 isa<BlockDecl>(
this) ||
934 isa<ParmVarDecl>(
this) ||
937 isa<CXXRecordDecl>(
this) ||
938 isa<ClassScopeFunctionSpecializationDecl>(
this))
942 "Access specifier is AS_none inside a record decl");
956 if (
const auto *D = dyn_cast<ValueDecl>(
this))
958 else if (
const auto *D = dyn_cast<TypedefNameDecl>(
this))
959 Ty = D->getUnderlyingType();
976 if (
getKind(D) == Decl::CXXMethod) {
977 auto *MD = cast<CXXMethodDecl>(D);
978 if (MD->getOverloadedOperator() == OO_Call &&
979 MD->getParent()->isLambda())
982 }
else if (
auto *FD = dyn_cast<FunctionDecl>(D))
984 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
986 else if (
auto *BD = dyn_cast<BlockDecl>(D))
988 else if (
auto *CD = dyn_cast<CapturedDecl>(D))
1007 DeclContextBits.DeclKind = K;
1008 setHasExternalLexicalStorage(
false);
1009 setHasExternalVisibleStorage(
false);
1010 setNeedToReconcileExternalVisibleStorage(
false);
1011 setHasLazyLocalLexicalLookups(
false);
1012 setHasLazyExternalLexicalLookups(
false);
1013 setUseQualifiedLookup(
false);
1018 #define DECL(NAME, BASE) 1019 #define DECL_CONTEXT(NAME) case Decl::NAME: 1020 #define DECL_CONTEXT_BASE(NAME) 1021 #include "clang/AST/DeclNodes.inc" 1024 #define DECL(NAME, BASE) 1025 #define DECL_CONTEXT_BASE(NAME) \ 1026 if (D->getKind() >= Decl::first##NAME && \ 1027 D->getKind() <= Decl::last##NAME) \ 1029 #include "clang/AST/DeclNodes.inc" 1044 if (isa<FunctionDecl>(
this))
1045 if (getParent()->getRedeclContext()->isFileContext() &&
1046 getLexicalParent()->getRedeclContext()->isRecord())
1047 return getLexicalParent();
1053 return getParent()->getParent();
1063 return cast<BlockDecl>(Ctx);
1071 return isNamespace() &&
1072 cast<NamespaceDecl>(
this)->isInline();
1079 const auto *ND = cast<NamespaceDecl>(
this);
1080 if (ND->isInline()) {
1081 return ND->getParent()->isStdNamespace();
1084 if (!getParent()->getRedeclContext()->isTranslationUnit())
1088 return II && II->
isStr(
"std");
1092 if (isFileContext())
1095 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
1098 if (
const auto *Record = dyn_cast<CXXRecordDecl>(
this)) {
1099 if (Record->getDescribedClassTemplate())
1102 if (Record->isDependentLambda())
1106 if (
const auto *Function = dyn_cast<FunctionDecl>(
this)) {
1107 if (Function->getDescribedFunctionTemplate())
1112 if (cast<Decl>(
this)->getFriendObjectKind())
1113 return getLexicalParent()->isDependentContext();
1120 return getParent() && getParent()->isDependentContext();
1124 if (getDeclKind() == Decl::Enum)
1125 return !cast<EnumDecl>(
this)->isScoped();
1126 else if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
1134 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1136 return cast<LinkageSpecDecl>(DC)->getLanguage() ==
ID;
1148 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1151 return cast<LinkageSpecDecl>(DC);
1162 if (getPrimaryContext() !=
this)
1163 return getPrimaryContext()->Encloses(DC);
1172 switch (getDeclKind()) {
1173 case Decl::TranslationUnit:
1174 case Decl::ExternCContext:
1175 case Decl::LinkageSpec:
1178 case Decl::Captured:
1179 case Decl::OMPDeclareReduction:
1180 case Decl::OMPDeclareMapper:
1181 case Decl::RequiresExprBody:
1185 case Decl::Namespace:
1187 return static_cast<NamespaceDecl *
>(
this)->getOriginalNamespace();
1189 case Decl::ObjCMethod:
1192 case Decl::ObjCInterface:
1193 if (
auto *OID = dyn_cast<ObjCInterfaceDecl>(
this))
1194 if (
auto *Def = OID->getDefinition())
1198 case Decl::ObjCProtocol:
1199 if (
auto *OPD = dyn_cast<ObjCProtocolDecl>(
this))
1200 if (
auto *Def = OPD->getDefinition())
1204 case Decl::ObjCCategory:
1207 case Decl::ObjCImplementation:
1208 case Decl::ObjCCategoryImpl:
1212 if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
1215 auto *Tag = cast<TagDecl>(
this);
1220 if (
const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
1222 TagDecl *PossiblePartialDef = TagTy->getDecl();
1224 return PossiblePartialDef;
1226 assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1232 assert(getDeclKind() >= Decl::firstFunction &&
1233 getDeclKind() <= Decl::lastFunction &&
1234 "Unknown DeclContext kind");
1243 if (getDeclKind() != Decl::Namespace) {
1244 Contexts.push_back(
this);
1251 Contexts.push_back(N);
1253 std::reverse(Contexts.begin(), Contexts.end());
1256 std::pair<Decl *, Decl *>
1258 bool FieldsAlreadyLoaded) {
1260 Decl *FirstNewDecl =
nullptr;
1261 Decl *PrevDecl =
nullptr;
1262 for (
auto *D : Decls) {
1263 if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1274 return std::make_pair(FirstNewDecl, PrevDecl);
1280 void DeclContext::reconcileExternalVisibleStorage()
const {
1281 assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1282 setNeedToReconcileExternalVisibleStorage(
false);
1284 for (
auto &Lookup : *LookupPtr)
1285 Lookup.second.setHasExternalDecls();
1292 DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1294 assert(hasExternalLexicalStorage() && Source &&
"No external storage?");
1301 setHasExternalLexicalStorage(
false);
1309 bool FieldsAlreadyLoaded =
false;
1310 if (
const auto *RD = dyn_cast<RecordDecl>(
this))
1311 FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1315 Decl *ExternalFirst, *ExternalLast;
1316 std::tie(ExternalFirst, ExternalLast) =
1317 BuildDeclChain(Decls, FieldsAlreadyLoaded);
1319 FirstDecl = ExternalFirst;
1321 LastDecl = ExternalLast;
1330 if (!(Map = DC->LookupPtr))
1331 Map = DC->CreateStoredDeclsMap(Context);
1332 if (DC->hasNeedToReconcileExternalVisibleStorage())
1333 DC->reconcileExternalVisibleStorage();
1335 (*Map)[Name].removeExternalDecls();
1346 if (!(Map = DC->LookupPtr))
1347 Map = DC->CreateStoredDeclsMap(Context);
1348 if (DC->hasNeedToReconcileExternalVisibleStorage())
1349 DC->reconcileExternalVisibleStorage();
1362 for (
unsigned I = 0, N = Decls.size(); I != N; ++I)
1365 Skip.push_back(Decls.size());
1368 unsigned SkipPos = 0;
1369 for (
unsigned I = 0, N = Decls.size(); I != N; ++I) {
1370 if (I == Skip[SkipPos])
1377 for (
auto *D : Decls) {
1389 if (hasExternalLexicalStorage())
1390 LoadLexicalDeclsFromExternalStorage();
1395 if (hasExternalLexicalStorage())
1396 LoadLexicalDeclsFromExternalStorage();
1407 if (hasExternalLexicalStorage())
1408 LoadLexicalDeclsFromExternalStorage();
1409 return containsDecl(D);
1435 if (isa<ClassTemplateSpecializationDecl>(D))
1437 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1438 if (FD->isFunctionTemplateSpecialization())
1446 "decl being removed from non-lexical context");
1448 "decl is not in decls list");
1451 if (D == FirstDecl) {
1453 FirstDecl = LastDecl =
nullptr;
1458 assert(I &&
"decl not found in linked list");
1459 if (I->NextInContextAndBits.getPointer() == D) {
1461 if (D == LastDecl) LastDecl = I;
1471 if (isa<NamedDecl>(D)) {
1472 auto *ND = cast<NamedDecl>(D);
1480 if (!ND->getDeclName())
1487 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1488 assert(Pos != Map->end() &&
"no lookup entry for decl");
1491 if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND)
1492 Pos->second.remove(ND);
1494 }
while (DC->isTransparentContext() && (DC = DC->getParent()));
1500 "Decl inserted into wrong lexical context");
1502 "Decl already inserted into a DeclContext");
1505 LastDecl->NextInContextAndBits.setPointer(D);
1508 FirstDecl = LastDecl = D;
1513 if (
auto *Record = dyn_cast<CXXRecordDecl>(
this))
1514 Record->addedMember(D);
1519 if (
auto *Import = dyn_cast<ImportDecl>(D))
1527 if (
auto *ND = dyn_cast<NamedDecl>(D))
1528 ND->getDeclContext()->getPrimaryContext()->
1529 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1535 if (
auto *ND = dyn_cast<NamedDecl>(D))
1536 ND->getDeclContext()->getPrimaryContext()->
1537 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1548 assert(
this == getPrimaryContext() &&
"buildLookup called on non-primary DC");
1550 if (!hasLazyLocalLexicalLookups() &&
1551 !hasLazyExternalLexicalLookups())
1555 collectAllContexts(Contexts);
1557 if (hasLazyExternalLexicalLookups()) {
1558 setHasLazyExternalLexicalLookups(
false);
1559 for (
auto *DC : Contexts) {
1560 if (DC->hasExternalLexicalStorage()) {
1561 bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1562 setHasLazyLocalLexicalLookups(
1563 hasLazyLocalLexicalLookups() | LoadedDecls );
1567 if (!hasLazyLocalLexicalLookups())
1571 for (
auto *DC : Contexts)
1572 buildLookupImpl(DC, hasExternalVisibleStorage());
1575 setHasLazyLocalLexicalLookups(
false);
1583 void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1593 if (
auto *ND = dyn_cast<NamedDecl>(D))
1595 (!ND->isFromASTFile() ||
1596 (isTranslationUnit() &&
1597 !getParentASTContext().getLangOpts().CPlusPlus)))
1598 makeDeclVisibleInContextImpl(ND, Internal);
1603 if (
auto *InnerCtx = dyn_cast<DeclContext>(D))
1604 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1605 buildLookupImpl(InnerCtx, Internal);
1609 NamedDecl *
const DeclContextLookupResult::SingleElementDummyList =
nullptr;
1613 assert(getDeclKind() != Decl::LinkageSpec &&
1614 getDeclKind() != Decl::Export &&
1615 "should not perform lookups into transparent contexts");
1617 const DeclContext *PrimaryContext = getPrimaryContext();
1618 if (PrimaryContext !=
this)
1619 return PrimaryContext->
lookup(Name);
1626 (void)cast<Decl>(
this)->getMostRecentDecl();
1628 if (hasExternalVisibleStorage()) {
1629 assert(Source &&
"external visible storage but no external source?");
1631 if (hasNeedToReconcileExternalVisibleStorage())
1632 reconcileExternalVisibleStorage();
1636 if (hasLazyLocalLexicalLookups() ||
1637 hasLazyExternalLexicalLookups())
1639 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1642 Map = CreateStoredDeclsMap(getParentASTContext());
1645 std::pair<StoredDeclsMap::iterator, bool> R =
1647 if (!R.second && !R.first->second.hasExternalDecls())
1648 return R.first->second.getLookupResult();
1652 StoredDeclsMap::iterator I = Map->find(Name);
1653 if (I != Map->end())
1654 return I->second.getLookupResult();
1662 if (hasLazyLocalLexicalLookups() ||
1663 hasLazyExternalLexicalLookups())
1664 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1669 StoredDeclsMap::iterator I = Map->find(Name);
1670 if (I == Map->end())
1673 return I->second.getLookupResult();
1678 assert(getDeclKind() != Decl::LinkageSpec &&
1679 getDeclKind() != Decl::Export &&
1680 "should not perform lookups into transparent contexts");
1682 DeclContext *PrimaryContext = getPrimaryContext();
1683 if (PrimaryContext !=
this)
1686 loadLazyLocalLexicalLookups();
1691 StoredDeclsMap::iterator I = Map->find(Name);
1692 return I != Map->end() ? I->second.getLookupResult()
1699 void DeclContext::loadLazyLocalLexicalLookups() {
1700 if (hasLazyLocalLexicalLookups()) {
1702 collectAllContexts(Contexts);
1703 for (
auto *Context : Contexts)
1704 buildLookupImpl(Context, hasExternalVisibleStorage());
1705 setHasLazyLocalLexicalLookups(
false);
1715 if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
1717 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1723 if (Name && !hasLazyLocalLexicalLookups() &&
1724 !hasLazyExternalLexicalLookups()) {
1726 StoredDeclsMap::iterator Pos = Map->find(Name);
1727 if (Pos != Map->end()) {
1728 Results.insert(Results.end(),
1729 Pos->second.getLookupResult().begin(),
1730 Pos->second.getLookupResult().end());
1741 if (
auto *ND = dyn_cast<NamedDecl>(D))
1742 if (ND->getDeclName() == Name)
1743 Results.push_back(ND);
1755 bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
1778 OutermostRD = cast<RecordDecl>(DC);
1786 if (!isFileContext())
1794 if (!NS || !NS->isInline())
1803 DeclContext *PrimaryDC = this->getPrimaryContext();
1807 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1810 void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1812 assert(
this == getPrimaryContext() &&
"expected a primary DC");
1814 if (!isLookupContext()) {
1815 if (isTransparentContext())
1816 getParent()->getPrimaryContext()
1817 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1833 if (LookupPtr || hasExternalVisibleStorage() ||
1835 (getParentASTContext().getLangOpts().CPlusPlus ||
1836 !isTranslationUnit()))) {
1841 makeDeclVisibleInContextImpl(D, Internal);
1843 setHasLazyLocalLexicalLookups(
true);
1848 if (isTransparentContext() || isInlineNamespace())
1849 getParent()->getPrimaryContext()->
1850 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1852 auto *DCAsDecl = cast<Decl>(
this);
1854 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1856 L->AddedVisibleDecl(
this, D);
1859 void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1864 Map = CreateStoredDeclsMap(*C);
1873 if (hasExternalVisibleStorage() &&
1875 Source->FindExternalVisibleDeclsByName(
this, D->
getDeclName());
1890 if (DeclNameEntries.
isNull()) {
1906 return cast<UsingDirectiveDecl>(*I);
1923 assert(!LookupPtr &&
"context already has a decls map");
1924 assert(getPrimaryContext() ==
this &&
1925 "creating decls map on non-primary context");
1928 bool Dependent = isDependentContext();
1933 M->Previous = C.LastSDM;
1934 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1939 void ASTContext::ReleaseDeclContextMaps() {
1949 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1956 Map = Next.getPointer();
1957 Dependent = Next.getInt();
1965 &&
"cannot iterate dependent diagnostics of non-dependent context");
1967 if (!Parent->LookupPtr)
1968 Parent->CreateStoredDeclsMap(C);
1981 DD->NextDiagnostic = Map->FirstDiagnostic;
1982 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 ...
This file provides some common utility functions for processing Lambda related AST Constructs...
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)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
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.
const T * castAs() const
Member-template castAs<specific type>.
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.