Go to the documentation of this file.
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;
108 Parent ? cast<Decl>(
Parent)->getOwningModule() :
nullptr;
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();
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 if (
auto *RD = dyn_cast<CXXRecordDecl>(
this))
234 return RD->getDescribedClassTemplate();
235 if (
auto *VD = dyn_cast<VarDecl>(
this))
236 return VD->getDescribedVarTemplate();
237 if (
auto *AD = dyn_cast<TypeAliasDecl>(
this))
238 return AD->getDescribedAliasTemplate();
245 return TD->getTemplateParameters();
246 if (
auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(
this))
247 return CTPSD->getTemplateParameters();
248 if (
auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(
this))
249 return VTPSD->getTemplateParameters();
258 if (
auto *AsDC = dyn_cast<DeclContext>(
this))
259 return AsDC->isDependentContext();
266 if (
auto *DC = dyn_cast<DeclContext>(
this))
267 if (DC->isFileContext())
271 return TPL->getDepth() + 1;
276 auto *RD = dyn_cast<CXXRecordDecl>(
this);
277 if (RD && RD->isDependentLambda())
278 if (
Decl *Context = RD->getLambdaContextDecl())
279 return Context->getTemplateDepth();
283 return cast<Decl>(DC)->getTemplateDepth();
289 DC = DC->getParent())
290 if (DC->isFunctionOrMethod())
306 TheLoc.
print(OS, SM);
312 if (
const auto *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
314 DN->printQualifiedName(OS);
338 getMultipleDC()->LexicalDC = DC;
352 "hidden declaration has no owning module");
357 if (SemaDC == LexicalDC) {
360 auto *MDC =
new (Ctx) Decl::MultipleDC();
361 MDC->SemanticDC = SemaDC;
362 MDC->LexicalDC = LexicalDC;
374 if (!isa<TagDecl>(LDC))
376 if (
const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))
386 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC))
387 if (ND->isAnonymousNamespace())
400 if (
auto *TUD = dyn_cast<TranslationUnitDecl>(
this))
404 assert(DC &&
"This decl is not contained in a translation unit!");
408 assert(DC &&
"This decl is not contained in a translation unit!");
411 return cast<TranslationUnitDecl>(DC);
436 for (; I != E; ++I) {
437 if (!I->isAlignmentErrorDependent())
438 Align =
std::max(Align, I->getAlignment(Ctx));
462 if (C.getASTMutationListener())
463 C.getASTMutationListener()->DeclarationMarkedUsed(
this);
473 for (
const auto *I :
redecls())
481 const Decl *Definition =
nullptr;
482 if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(
this)) {
483 Definition =
ID->getDefinition();
484 }
else if (
auto *PD = dyn_cast<ObjCProtocolDecl>(
this)) {
485 Definition = PD->getDefinition();
486 }
else if (
auto *TD = dyn_cast<TagDecl>(
this)) {
487 Definition = TD->getDefinition();
492 if (
auto *
attr = Definition->getAttr<ExternalSourceSymbolAttr>())
495 return dcd->getAttr<ExternalSourceSymbolAttr>();
502 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
503 hasAttr<LoaderUninitializedAttr>();
507 if (
auto *AA = getAttr<AliasAttr>())
509 if (
auto *IFA = getAttr<IFuncAttr>())
511 if (
auto *NZA = getAttr<LoaderUninitializedAttr>())
520 StringRef RealizedPlatform = A->getPlatform()->getName();
522 return RealizedPlatform;
523 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
524 if (suffix != StringRef::npos)
525 return RealizedPlatform.slice(0, suffix);
526 return RealizedPlatform;
539 const AvailabilityAttr *A,
541 VersionTuple EnclosingVersion) {
542 if (EnclosingVersion.empty())
545 if (EnclosingVersion.empty())
548 StringRef ActualPlatform = A->getPlatform()->getName();
555 StringRef PrettyPlatformName
556 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
558 if (PrettyPlatformName.empty())
559 PrettyPlatformName = ActualPlatform;
562 if (!A->getMessage().empty()) {
564 HintMessage += A->getMessage();
568 if (A->getUnavailable()) {
571 llvm::raw_string_ostream Out(*Message);
572 Out <<
"not available on " << PrettyPlatformName
580 if (!A->getIntroduced().empty() &&
581 EnclosingVersion < A->getIntroduced()) {
584 llvm::raw_string_ostream Out(*Message);
585 VersionTuple VTI(A->getIntroduced());
586 Out <<
"introduced in " << PrettyPlatformName <<
' '
587 << VTI << HintMessage;
594 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
597 llvm::raw_string_ostream Out(*Message);
598 VersionTuple VTO(A->getObsoleted());
599 Out <<
"obsoleted in " << PrettyPlatformName <<
' '
600 << VTO << HintMessage;
607 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
610 llvm::raw_string_ostream Out(*Message);
611 VersionTuple VTD(A->getDeprecated());
612 Out <<
"first deprecated in " << PrettyPlatformName <<
' '
613 << VTD << HintMessage;
623 VersionTuple EnclosingVersion,
624 StringRef *RealizedPlatform)
const {
625 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
626 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
632 for (
const auto *A :
attrs()) {
633 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
638 ResultMessage =
std::string(Deprecated->getMessage());
644 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
650 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
652 Message, EnclosingVersion);
655 if (RealizedPlatform)
656 *RealizedPlatform = Availability->getPlatform()->getName();
663 ResultMessage.swap(*Message);
670 Message->swap(ResultMessage);
677 for (
const auto *A :
attrs()) {
678 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
681 if (!Availability->getIntroduced().empty())
682 return Availability->getIntroduced();
689 IsDefinition =
false;
692 if (
const auto *Var = dyn_cast<VarDecl>(
this)) {
693 if (Var->isThisDeclarationADefinition()) {
700 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
709 if (isa<ObjCInterfaceDecl>(
this) &&
723 if (isa<WeakImportAttr>(A))
726 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
739 case CXXDeductionGuide:
742 case ConstructorUsingShadow:
759 case NonTypeTemplateParm:
766 case ObjCCompatibleAlias:
772 case TemplateTypeParm:
776 case UnresolvedUsingTypename:
782 case UnresolvedUsingValue:
794 case ObjCAtDefsField:
807 case FunctionTemplate:
811 case TemplateTemplateParm:
812 case TypeAliasTemplate:
815 case UnresolvedUsingIfExists:
818 case OMPDeclareReduction:
821 case OMPDeclareMapper:
832 case ObjCPropertyImpl:
834 case PragmaDetectMismatch:
837 case TranslationUnit:
841 case UnnamedGlobalConstant:
842 case TemplateParamObject:
845 case BuiltinTemplate:
846 case ClassTemplateSpecialization:
847 case ClassTemplatePartialSpecialization:
848 case ClassScopeFunctionSpecialization:
849 case VarTemplateSpecialization:
850 case VarTemplatePartialSpecialization:
851 case ObjCImplementation:
853 case ObjCCategoryImpl:
855 case OMPThreadPrivate:
858 case OMPCapturedExpr:
860 case LifetimeExtendedTemporary:
861 case RequiresExprBody:
866 llvm_unreachable(
"Invalid DeclKind!");
870 assert(!HasAttrs &&
"Decl already contains attrs.");
873 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
880 if (!HasAttrs)
return;
901 auto I = Attrs.begin(), E = Attrs.end();
902 for (; I != E; ++I) {
903 if (!(*I)->isInherited())
910 assert(HasAttrs &&
"No attrs to get!");
917 #define DECL(NAME, BASE)
918 #define DECL_CONTEXT(NAME) \
920 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
921 #define DECL_CONTEXT_BASE(NAME)
922 #include "clang/AST/DeclNodes.inc"
924 #define DECL(NAME, BASE)
925 #define DECL_CONTEXT_BASE(NAME) \
926 if (DK >= first##NAME && DK <= last##NAME) \
927 return static_cast<NAME##Decl *>(const_cast<DeclContext *>(D));
928 #include "clang/AST/DeclNodes.inc"
929 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
936 #define DECL(NAME, BASE)
937 #define DECL_CONTEXT(NAME) \
939 return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
940 #define DECL_CONTEXT_BASE(NAME)
941 #include "clang/AST/DeclNodes.inc"
943 #define DECL(NAME, BASE)
944 #define DECL_CONTEXT_BASE(NAME) \
945 if (DK >= first##NAME && DK <= last##NAME) \
946 return static_cast<NAME##Decl *>(const_cast<Decl *>(D));
947 #include "clang/AST/DeclNodes.inc"
948 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
955 if (
const auto *FD = dyn_cast<FunctionDecl>(
this)) {
957 if (FD->hasBody(Definition))
958 return Definition->getSourceRange().getEnd();
963 return Body->getSourceRange().getEnd();
968 bool Decl::AccessDeclContextCheck()
const {
979 if (isa<TranslationUnitDecl>(
this) || isa<TemplateTypeParmDecl>(
this) ||
982 isa<StaticAssertDecl>(
this) || isa<BlockDecl>(
this) ||
985 isa<ParmVarDecl>(
this) ||
988 isa<CXXRecordDecl>(
this) ||
989 isa<ClassScopeFunctionSpecializationDecl>(
this) ||
990 isa<LifetimeExtendedTemporaryDecl>(
this))
994 "Access specifier is AS_none inside a record decl");
1002 while (DC && !isa<ExportDecl>(DC))
1005 return DC && isa<ExportDecl>(DC);
1017 if (
const auto *D = dyn_cast<ValueDecl>(
this))
1019 else if (
const auto *D = dyn_cast<TypedefNameDecl>(
this))
1020 Ty = D->getUnderlyingType();
1037 if (
getKind(D) == Decl::CXXMethod) {
1038 auto *MD = cast<CXXMethodDecl>(D);
1039 if (MD->getOverloadedOperator() == OO_Call &&
1040 MD->getParent()->isLambda())
1044 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1046 if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
1048 if (
auto *BD = dyn_cast<BlockDecl>(D))
1050 if (
auto *CD = dyn_cast<CapturedDecl>(D))
1071 setNeedToReconcileExternalVisibleStorage(
false);
1072 setHasLazyLocalLexicalLookups(
false);
1073 setHasLazyExternalLexicalLookups(
false);
1079 #define DECL(NAME, BASE)
1080 #define DECL_CONTEXT(NAME) case Decl::NAME:
1081 #define DECL_CONTEXT_BASE(NAME)
1082 #include "clang/AST/DeclNodes.inc"
1085 #define DECL(NAME, BASE)
1086 #define DECL_CONTEXT_BASE(NAME) \
1087 if (D->getKind() >= Decl::first##NAME && \
1088 D->getKind() <= Decl::last##NAME) \
1090 #include "clang/AST/DeclNodes.inc"
1105 if (isa<FunctionDecl>(
this))
1124 return cast<BlockDecl>(Ctx);
1133 cast<NamespaceDecl>(
this)->isInline();
1140 const auto *ND = cast<NamespaceDecl>(
this);
1141 if (ND->isInline()) {
1142 return ND->getParent()->isStdNamespace();
1149 return II && II->
isStr(
"std");
1156 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
1159 if (
const auto *Record = dyn_cast<CXXRecordDecl>(
this)) {
1160 if (Record->getDescribedClassTemplate())
1163 if (Record->isDependentLambda())
1165 if (Record->isNeverDependentLambda())
1169 if (
const auto *Function = dyn_cast<FunctionDecl>(
this)) {
1170 if (Function->getDescribedFunctionTemplate())
1175 if (cast<Decl>(
this)->getFriendObjectKind())
1188 return !cast<EnumDecl>(
this)->isScoped();
1195 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1197 return cast<LinkageSpecDecl>(DC)->getLanguage() ==
ID;
1209 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1212 return cast<LinkageSpecDecl>(DC);
1227 if (!isa<LinkageSpecDecl>(DC) && !isa<ExportDecl>(DC) &&
1237 assert(DC &&
"All transparent contexts should have a parent!");
1244 case Decl::ExternCContext:
1245 case Decl::LinkageSpec:
1248 case Decl::Captured:
1249 case Decl::OMPDeclareReduction:
1250 case Decl::OMPDeclareMapper:
1251 case Decl::RequiresExprBody:
1255 case Decl::TranslationUnit:
1257 case Decl::Namespace:
1259 return static_cast<NamespaceDecl *
>(
this)->getOriginalNamespace();
1261 case Decl::ObjCMethod:
1264 case Decl::ObjCInterface:
1265 if (
auto *OID = dyn_cast<ObjCInterfaceDecl>(
this))
1266 if (
auto *Def = OID->getDefinition())
1270 case Decl::ObjCProtocol:
1271 if (
auto *OPD = dyn_cast<ObjCProtocolDecl>(
this))
1272 if (
auto *Def = OPD->getDefinition())
1276 case Decl::ObjCCategory:
1279 case Decl::ObjCImplementation:
1280 case Decl::ObjCCategoryImpl:
1287 auto *Tag = cast<TagDecl>(
this);
1292 if (
const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
1294 TagDecl *PossiblePartialDef = TagTy->getDecl();
1296 return PossiblePartialDef;
1298 assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
1306 "Unknown DeclContext kind");
1311 template <
typename T>
1313 for (T *D = Self->getMostRecentDecl(); D; D = D->getPreviousDecl())
1314 Contexts.push_back(D);
1316 std::reverse(Contexts.begin(), Contexts.end());
1324 if (
Kind == Decl::TranslationUnit)
1326 else if (
Kind == Decl::Namespace)
1329 Contexts.push_back(
this);
1332 std::pair<Decl *, Decl *>
1334 bool FieldsAlreadyLoaded) {
1336 Decl *FirstNewDecl =
nullptr;
1337 Decl *PrevDecl =
nullptr;
1338 for (
auto *D : Decls) {
1339 if (FieldsAlreadyLoaded && isa<FieldDecl>(D))
1350 return std::make_pair(FirstNewDecl, PrevDecl);
1356 void DeclContext::reconcileExternalVisibleStorage()
const {
1357 assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr);
1358 setNeedToReconcileExternalVisibleStorage(
false);
1360 for (
auto &Lookup : *LookupPtr)
1361 Lookup.second.setHasExternalDecls();
1368 DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1385 bool FieldsAlreadyLoaded =
false;
1386 if (
const auto *RD = dyn_cast<RecordDecl>(
this))
1387 FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
1391 Decl *ExternalFirst, *ExternalLast;
1392 std::tie(ExternalFirst, ExternalLast) =
1406 if (!(Map = DC->LookupPtr))
1407 Map = DC->CreateStoredDeclsMap(Context);
1408 if (DC->hasNeedToReconcileExternalVisibleStorage())
1409 DC->reconcileExternalVisibleStorage();
1411 (*Map)[Name].removeExternalDecls();
1422 if (!(Map = DC->LookupPtr))
1423 Map = DC->CreateStoredDeclsMap(Context);
1424 if (DC->hasNeedToReconcileExternalVisibleStorage())
1425 DC->reconcileExternalVisibleStorage();
1428 List.replaceExternalDecls(Decls);
1429 return List.getLookupResult();
1434 LoadLexicalDeclsFromExternalStorage();
1440 LoadLexicalDeclsFromExternalStorage();
1452 LoadLexicalDeclsFromExternalStorage();
1479 if (isa<ClassTemplateSpecializationDecl>(D))
1481 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1482 if (FD->isFunctionTemplateSpecialization())
1497 "decl being removed from non-lexical context");
1499 "decl is not in decls list");
1509 assert(I &&
"decl not found in linked list");
1510 if (I->NextInContextAndBits.getPointer() == D) {
1522 if (isa<NamedDecl>(D)) {
1523 auto *ND = cast<NamedDecl>(D);
1531 if (!ND->getDeclName())
1538 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
1539 assert(Pos != Map->end() &&
"no lookup entry for decl");
1546 }
while (DC->isTransparentContext() && (DC = DC->getParent()));
1552 "Decl inserted into wrong lexical context");
1554 "Decl already inserted into a DeclContext");
1565 if (
auto *Record = dyn_cast<CXXRecordDecl>(
this))
1566 Record->addedMember(D);
1571 if (
auto *Import = dyn_cast<ImportDecl>(D))
1579 if (
auto *ND = dyn_cast<NamedDecl>(D))
1580 ND->getDeclContext()->getPrimaryContext()->
1581 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1587 if (
auto *ND = dyn_cast<NamedDecl>(D))
1588 ND->getDeclContext()->getPrimaryContext()->
1589 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1602 if (!hasLazyLocalLexicalLookups() &&
1603 !hasLazyExternalLexicalLookups())
1609 if (hasLazyExternalLexicalLookups()) {
1610 setHasLazyExternalLexicalLookups(
false);
1611 for (
auto *DC : Contexts) {
1612 if (DC->hasExternalLexicalStorage()) {
1613 bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage();
1614 setHasLazyLocalLexicalLookups(
1615 hasLazyLocalLexicalLookups() | LoadedDecls );
1619 if (!hasLazyLocalLexicalLookups())
1623 for (
auto *DC : Contexts)
1627 setHasLazyLocalLexicalLookups(
false);
1635 void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1645 if (
auto *ND = dyn_cast<NamedDecl>(D))
1647 (!ND->isFromASTFile() ||
1650 makeDeclVisibleInContextImpl(ND, Internal);
1655 if (
auto *InnerCtx = dyn_cast<DeclContext>(D))
1656 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1657 buildLookupImpl(InnerCtx, Internal);
1668 if (PrimaryContext !=
this)
1669 return PrimaryContext->
lookup(Name);
1676 (void)cast<Decl>(
this)->getMostRecentDecl();
1679 assert(Source &&
"external visible storage but no external source?");
1681 if (hasNeedToReconcileExternalVisibleStorage())
1682 reconcileExternalVisibleStorage();
1686 if (hasLazyLocalLexicalLookups() ||
1687 hasLazyExternalLexicalLookups())
1695 std::pair<StoredDeclsMap::iterator, bool> R =
1697 if (!R.second && !R.first->second.hasExternalDecls())
1698 return R.first->second.getLookupResult();
1702 StoredDeclsMap::iterator I = Map->find(Name);
1703 if (I != Map->end())
1704 return I->second.getLookupResult();
1712 if (hasLazyLocalLexicalLookups() ||
1713 hasLazyExternalLexicalLookups())
1719 StoredDeclsMap::iterator I = Map->find(Name);
1720 if (I == Map->end())
1723 return I->second.getLookupResult();
1730 "should not perform lookups into transparent contexts");
1733 if (PrimaryContext !=
this)
1736 loadLazyLocalLexicalLookups();
1741 StoredDeclsMap::iterator I = Map->find(Name);
1742 return I != Map->end() ? I->second.getLookupResult()
1749 void DeclContext::loadLazyLocalLexicalLookups() {
1750 if (hasLazyLocalLexicalLookups()) {
1753 for (
auto *Context : Contexts)
1755 setHasLazyLocalLexicalLookups(
false);
1767 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1773 if (Name && !hasLazyLocalLexicalLookups() &&
1774 !hasLazyExternalLexicalLookups()) {
1776 StoredDeclsMap::iterator Pos = Map->find(Name);
1777 if (Pos != Map->end()) {
1778 Results.insert(Results.end(),
1779 Pos->second.getLookupResult().begin(),
1780 Pos->second.getLookupResult().end());
1791 if (
auto *ND = dyn_cast<NamedDecl>(D))
1792 if (ND->getDeclName() == Name)
1793 Results.push_back(ND);
1805 bool SkipRecords =
getDeclKind() == Decl::Kind::Enum &&
1828 OutermostRD = cast<RecordDecl>(DC);
1843 const auto *NS = dyn_cast<NamespaceDecl>(O);
1844 if (!NS || !NS->isInline())
1857 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1860 void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1867 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1891 makeDeclVisibleInContextImpl(D, Internal);
1893 setHasLazyLocalLexicalLookups(
true);
1900 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1902 auto *DCAsDecl = cast<Decl>(
this);
1904 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1906 L->AddedVisibleDecl(
this, D);
1909 void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1914 Map = CreateStoredDeclsMap(*C);
1944 return cast<UsingDirectiveDecl>(*I);
1953 return udir_range(Result.begin(), Result.end());
1961 assert(!LookupPtr &&
"context already has a decls map");
1963 "creating decls map on non-primary context");
1971 M->Previous = C.LastSDM;
1972 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1977 void ASTContext::ReleaseDeclContextMaps() {
1982 LastSDM.setPointer(
nullptr);
1988 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1995 Map = Next.getPointer();
1996 Dependent = Next.getInt();
2003 assert(
Parent->isDependentContext()
2004 &&
"cannot iterate dependent diagnostics of non-dependent context");
2007 Parent->CreateStoredDeclsMap(C);
2020 DD->NextDiagnostic = Map->FirstDiagnostic;
2021 Map->FirstDiagnostic = DD;
void setLexicalDeclContext(DeclContext *DC)
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
void localUncachedLookup(DeclarationName Name, SmallVectorImpl< NamedDecl * > &Results)
A simplistic name lookup mechanism that performs name lookup into this declaration context without co...
__DEVICE__ int max(int __a, int __b)
ASTContext & getASTContext() const LLVM_READONLY
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
void removeDecl(Decl *D)
Removes a declaration from this context.
@ IDNS_Type
Types, declared with 'struct foo', typedefs, etc.
ASTContext & getParentASTContext() const
bool isBlockPointerType() const
const LinkageSpecDecl * getExternCContext() const
Retrieve the nearest enclosing C linkage specification context.
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Represents a linkage specification.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
bool isTemplateDecl() const
returns true if this declaration is a template
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
bool isTemplateParameter() const
isTemplateParameter - Determines whether this declaration is a template parameter.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
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...
Represents C++ using-directive.
ASTMutationListener * getASTMutationListener() const
Encodes a location in the source.
This represents a decl that may have a name.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
A (possibly-)qualified type.
void addDeclInternal(Decl *D)
Add the declaration D into this context, but suppress searches for external declarations with the sam...
@ IDNS_Using
This declaration is a using declaration.
static void DestroyAll(StoredDeclsMap *Map, bool Dependent)
Decl * getNextDeclInContext()
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
void setHasExternalDecls()
void eraseDeclAttrs(const Decl *D)
Erase the attributes corresponding to the given declaration.
unsigned getIdentifierNamespace() const
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
void setHasExternalLexicalStorage(bool ES=true) const
State whether this DeclContext has external storage for declarations lexically in this context.
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
void setIsUsed()
Set whether the declaration is used, in the sense of odr-use.
bool isInlineNamespace() const
udir_range using_directives() const
Returns iterator range [First, Last) of UsingDirectiveDecls stored within this context.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
static bool classof(const Decl *D)
FunctionType - C99 6.7.5.3 - Function Declarators.
bool hasWeakClassImport() const
Does this runtime support weakly importing classes?
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
The name of a declaration.
bool isReferenced() const
Whether any declaration of this entity was referenced.
bool isLocalExternDecl()
Determine whether this is a block-scope declaration with linkage.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
ModuleOwnershipKind getModuleOwnershipKind() const
Get the kind of module ownership for this declaration.
DeclContext * getNonTransparentContext()
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
virtual Module * getModule(unsigned ID)
Retrieve the module that corresponds to the given module ID.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
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...
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...
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
void * Allocate(size_t Size, unsigned Align=8) const
static std::pair< Decl *, Decl * > BuildDeclChain(ArrayRef< Decl * > Decls, bool FieldsAlreadyLoaded)
Build up a chain of declarations.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
bool setUseQualifiedLookup(bool use=true) const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
The top declaration context.
void print(raw_ostream &OS, const SourceManager &SM) const
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
Kind
Lists the kind of concrete classes of Decl.
static unsigned getIdentifierNamespaceForKind(Kind DK)
Decl * FirstDecl
FirstDecl - The first declaration stored within this declaration context.
Describes a module or submodule.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
@ VisibleWhenImported
This declaration has an owning module, and is visible when that module is imported.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
void setAccess(AccessSpecifier AS)
llvm::PointerIntPair< Decl *, 2, ModuleOwnershipKind > NextInContextAndBits
The next declaration within the same lexical DeclContext.
Decl::Kind getDeclKind() const
bool isInStdNamespace() const
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
bool isFunctionPointerType() const
void setAttrs(const AttrVec &Attrs)
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
void setHasExternalVisibleStorage(bool ES=true) const
State whether this DeclContext has external storage for declarations visible in this context.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool shouldBeHidden(NamedDecl *D)
shouldBeHidden - Determine whether a declaration which was declared within its semantic context shoul...
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
An array of decls optimized for the common case of only containing one entry.
bool isLookupContext() const
Test whether the context supports looking up names.
const Attr * getDefiningAttr() const
Return this declaration's defining attribute if it has one.
const T * getAs() const
Member-template getAs<specific type>'.
void updateOutOfDate(IdentifierInfo &II) const
Update a potentially out-of-date declaration.
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
bool isInvalidDecl() const
static StringRef getRealizedPlatform(const AvailabilityAttr *A, const ASTContext &Context)
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
AttrVec & getDeclAttrs(const Decl *D)
Retrieve the attributes for the given declaration.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
bool containsDecl(Decl *D) const
Checks whether a declaration is in this context.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
static void EnableStatistics()
decl_iterator - Iterates through the declarations stored within this context.
bool isTranslationUnit() const
bool isStdNamespace() const
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
static bool isLinkageSpecContext(const DeclContext *DC, LinkageSpecDecl::LanguageIDs ID)
friend class DependentDiagnostic
For CreateStoredDeclsMap.
bool containsDeclAndLoad(Decl *D) const
Checks whether a declaration is in this context.
Represents the declaration of a struct/union/class/enum.
Stores a list of template parameters for a TemplateDecl and its derived classes.
LanguageIDs
Represents the language in a linkage specification.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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.
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
static Decl::Kind getKind(const Decl *D)
static DeclContext * castToDeclContext(const Decl *)
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
@ IDNS_Member
Members, declared with object declarations within tag definitions.
bool canBeWeakImported(bool &IsDefinition) const
Determines whether this symbol can be weak-imported, e.g., whether it would be well-formed to add the...
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)
Update an out-of-date identifier.
@ IDNS_OMPMapper
This declaration is an OpenMP user defined mapper.
@ IDNS_Ordinary
Ordinary names.
bool hasDefiningAttr() const
Return true if this declaration has an attribute which acts as definition of the entity,...
static Decl * castFromDeclContext(const DeclContext *)
TranslationUnitDecl * getTranslationUnitDecl()
const T * castAs() const
Member-template castAs<specific type>.
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
DeclContext(Decl::Kind K)
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
DeclContextBitfields DeclContextBits
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
const char * getDeclKindName() const
@ IDNS_Label
Labels, declared with 'x:' and referenced with 'goto x'.
bool isBeingDefined() const
Return true if this decl is currently being defined.
UsingDirectiveDecl * operator*() const
void addDecl(Decl *D)
Add the declaration D into this context.
unsigned Access
Access - Used by C++ decls for the access specifier.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
@ IDNS_OMPReduction
This declaration is an OpenMP user defined reduction construction.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Decl - This represents one declaration (or definition), e.g.
bool isTemplated() const
Determine whether this declaration is a templated entity (whether it is.
unsigned getTemplateDepth() const
Determine the number of levels of template parameter surrounding this declaration.
@ IDNS_ObjCProtocol
Objective C @protocol.
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
DeclContextLookupResult lookup_result
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
bool isFileContext() const
lookup_result noload_lookup(DeclarationName Name)
Find the declarations with the given name that are visible within this context; don't attempt to retr...
One of these records is kept for each identifier that is lexed.
The basic abstraction for the target Objective-C runtime.
const TargetInfo & getTargetInfo() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const BlockDecl * getInnermostBlockDecl() const
Return this DeclContext if it is a BlockDecl.
void collectAllContexts(SmallVectorImpl< DeclContext * > &Contexts)
Collects all of the declaration contexts that are semantically connected to this declaration context.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
bool hasOwningModule() const
Is this declaration owned by some module?
static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name)
ASTContext & getASTContext() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
void print(raw_ostream &OS) const override
A dependently-generated diagnostic.
bool isParameterPack() const
Whether this declaration is a parameter pack.
void addedLocalImportDecl(ImportDecl *Import)
Notify the AST context that a new import declaration has been parsed or implicitly created within thi...
void prependDeclNoReplace(NamedDecl *D)
Add a declaration to the list without checking if it replaces anything.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
StoredDeclsMap * buildLookup()
Ensure the lookup structure is fully-built and return it.
Stmt - This represents one statement.
AvailabilityResult
Captures the result of checking the availability of a declaration.
bool isValid() const
Return true if this is a valid SourceLocation object.
Attr - This represents one attribute.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
llvm::iterator_range< udir_iterator > udir_range
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool trackLocalOwningModule() const
Do we need to track the owning module for a local declaration?
bool hasLocalOwningModuleStorage() const
The results of name lookup within a DeclContext.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
RAII class for safely pairing a StartedDeserializing call with FinishedDeserializing.
Base for LValueReferenceType and RValueReferenceType.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
const TemplateParameterList * getDescribedTemplateParams() const
If this is a declaration that describes some template or partial specialization, this returns the cor...
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isFunctionReferenceType() const
Decl * LastDecl
LastDecl - The last declaration stored within this declaration context.
VersionTuple getVersionIntroduced() const
Retrieve the version of the target platform in which this declaration was introduced.
Abstract interface for external sources of AST nodes.
bool isFunctionOrMethod() const
bool isInLocalScopeForInstantiation() const
Determine whether a substitution into this declaration would occur as part of a substitution into a d...
SourceLocation getLocation() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
Represent a C++ namespace.
Represents a function declaration or definition.
Represents a struct/union/class.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
void addOrReplaceDecl(NamedDecl *D)
If this is a redeclaration of an existing decl, replace the old one with D.
void setLocalOwningModule(Module *M)
static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl * > Decls)
const LangOptions & getLangOpts() const
llvm::BumpPtrAllocator & getAllocator() const
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
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 char * getDeclKindName() const
bool isInAnonymousNamespace() const
void collectAllContextsImpl(T *Self, SmallVectorImpl< DeclContext * > &Contexts)
DeclContext * getDeclContext()
decl_iterator decls_begin() const