31 #include "llvm/ADT/DenseMap.h"
32 #include "llvm/Support/raw_ostream.h"
34 using namespace clang;
40 #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
41 #define ABSTRACT_DECL(DECL)
42 #include "clang/AST/DeclNodes.inc"
45 getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
48 #define DECL(DERIVED, BASE) \
49 static_assert(llvm::AlignOf<Decl>::Alignment >= \
50 llvm::AlignOf<DERIVED##Decl>::Alignment, \
51 "Alignment sufficient after objects prepended to " #DERIVED);
52 #define ABSTRACT_DECL(DECL)
53 #include "clang/AST/DeclNodes.inc"
59 static_assert(
sizeof(
unsigned) * 2 >= llvm::AlignOf<Decl>::Alignment,
60 "Decl won't be misaligned");
62 void *
Result = (
char*)Start + 8;
64 unsigned *PrefixPtr = (
unsigned *)Result - 2;
77 assert(!Parent || &Parent->getParentASTContext() == &Ctx);
80 if (Ctx.getLangOpts().ModulesLocalVisibility) {
84 llvm::OffsetToAlignment(
sizeof(
Module *),
85 llvm::AlignOf<Decl>::Alignment);
86 char *
Buffer =
reinterpret_cast<char *
>(
87 ::operator
new(ExtraAlign +
sizeof(
Module *) + Size + Extra, Ctx));
91 return ::operator
new(Size + Extra, Ctx);
94 Module *Decl::getOwningModuleSlow()
const {
95 assert(isFromASTFile() &&
"Not from AST file?");
96 return getASTContext().getExternalSource()->getModule(getOwningModuleID());
99 bool Decl::hasLocalOwningModuleStorage()
const {
100 return getASTContext().getLangOpts().ModulesLocalVisibility;
103 const char *Decl::getDeclKindName()
const {
105 default: llvm_unreachable(
"Declaration not in DeclNodes.inc!");
106 #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
107 #define ABSTRACT_DECL(DECL)
108 #include "clang/AST/DeclNodes.inc"
112 void Decl::setInvalidDecl(
bool Invalid) {
113 InvalidDecl = Invalid;
114 assert(!isa<TagDecl>(
this) || !cast<TagDecl>(
this)->isCompleteDefinition());
115 if (Invalid && !isa<ParmVarDecl>(
this)) {
125 default: llvm_unreachable(
"Declaration context not in DeclNodes.inc!");
126 #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
127 #define ABSTRACT_DECL(DECL)
128 #include "clang/AST/DeclNodes.inc"
132 bool Decl::StatisticsEnabled =
false;
133 void Decl::EnableStatistics() {
134 StatisticsEnabled =
true;
137 void Decl::PrintStats() {
138 llvm::errs() <<
"\n*** Decl Stats:\n";
141 #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
142 #define ABSTRACT_DECL(DECL)
143 #include "clang/AST/DeclNodes.inc"
144 llvm::errs() <<
" " << totalDecls <<
" decls total.\n";
147 #define DECL(DERIVED, BASE) \
148 if (n##DERIVED##s > 0) { \
149 totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \
150 llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \
151 << sizeof(DERIVED##Decl) << " each (" \
152 << n##DERIVED##s * sizeof(DERIVED##Decl) \
155 #define ABSTRACT_DECL(DECL)
156 #include "clang/AST/DeclNodes.inc"
158 llvm::errs() <<
"Total bytes = " << totalBytes <<
"\n";
161 void Decl::add(
Kind k) {
163 #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
164 #define ABSTRACT_DECL(DECL)
165 #include "clang/AST/DeclNodes.inc"
169 bool Decl::isTemplateParameterPack()
const {
171 return TTP->isParameterPack();
173 = dyn_cast<NonTypeTemplateParmDecl>(
this))
174 return NTTP->isParameterPack();
176 = dyn_cast<TemplateTemplateParmDecl>(
this))
177 return TTP->isParameterPack();
181 bool Decl::isParameterPack()
const {
182 if (
const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(
this))
183 return Parm->isParameterPack();
185 return isTemplateParameterPack();
192 return FTD->getTemplatedDecl();
196 bool Decl::isTemplateDecl()
const {
197 return isa<TemplateDecl>(
this);
201 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
202 return FD->getDescribedFunctionTemplate();
203 else if (
auto *RD = dyn_cast<CXXRecordDecl>(
this))
204 return RD->getDescribedClassTemplate();
205 else if (
auto *VD = dyn_cast<VarDecl>(
this))
206 return VD->getDescribedVarTemplate();
211 const DeclContext *Decl::getParentFunctionOrMethod()
const {
214 DC = DC->getParent())
215 if (DC->isFunctionOrMethod())
229 TheLoc = TheDecl->getLocation();
232 TheLoc.
print(OS, SM);
238 if (
const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
240 DN->printQualifiedName(OS);
257 void Decl::setLexicalDeclContext(
DeclContext *DC) {
258 if (DC == getLexicalDeclContext())
262 setDeclContextsImpl(getDeclContext(), DC, getASTContext());
264 getMultipleDC()->LexicalDC = DC;
266 Hidden = cast<Decl>(DC)->Hidden;
271 if (SemaDC == LexicalDC) {
274 Decl::MultipleDC *MDC =
new (Ctx) Decl::MultipleDC();
275 MDC->SemanticDC = SemaDC;
276 MDC->LexicalDC = LexicalDC;
281 bool Decl::isLexicallyWithinFunctionOrMethod()
const {
286 if (!isa<TagDecl>(LDC))
293 bool Decl::isInAnonymousNamespace()
const {
297 if (ND->isAnonymousNamespace())
304 bool Decl::isInStdNamespace()
const {
305 return getDeclContext()->isStdNamespace();
313 assert(DC &&
"This decl is not contained in a translation unit!");
317 assert(DC &&
"This decl is not contained in a translation unit!");
320 return cast<TranslationUnitDecl>(DC);
324 return getTranslationUnitDecl()->getASTContext();
328 return getASTContext().getASTMutationListener();
331 unsigned Decl::getMaxAlignment()
const {
340 Align =
std::max(Align,
I->getAlignment(Ctx));
344 bool Decl::isUsed(
bool CheckUsedAttr)
const {
351 if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>())
356 return getMostRecentDecl()->getCanonicalDecl()->Used;
369 bool Decl::isReferenced()
const {
374 for (
auto I : redecls())
381 bool Decl::hasDefiningAttr()
const {
382 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
385 const Attr *Decl::getDefiningAttr()
const {
386 if (AliasAttr *AA = getAttr<AliasAttr>())
388 if (IFuncAttr *IFA = getAttr<IFuncAttr>())
403 const AvailabilityAttr *A,
404 std::string *Message) {
408 if (TargetMinVersion.
empty())
413 StringRef ActualPlatform = A->getPlatform()->getName();
414 StringRef RealizedPlatform = ActualPlatform;
416 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
417 if (suffix != StringRef::npos)
418 RealizedPlatform = RealizedPlatform.slice(0, suffix);
424 if (RealizedPlatform != TargetPlatform)
427 StringRef PrettyPlatformName
428 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
430 if (PrettyPlatformName.empty())
431 PrettyPlatformName = ActualPlatform;
433 std::string HintMessage;
434 if (!A->getMessage().empty()) {
436 HintMessage += A->getMessage();
440 if (A->getUnavailable()) {
443 llvm::raw_string_ostream Out(*Message);
444 Out <<
"not available on " << PrettyPlatformName
452 if (!A->getIntroduced().empty() &&
453 TargetMinVersion < A->getIntroduced()) {
456 llvm::raw_string_ostream Out(*Message);
459 Out <<
"introduced in " << PrettyPlatformName <<
' '
460 << VTI << HintMessage;
467 if (!A->getObsoleted().empty() && TargetMinVersion >= A->getObsoleted()) {
470 llvm::raw_string_ostream Out(*Message);
473 Out <<
"obsoleted in " << PrettyPlatformName <<
' '
474 << VTO << HintMessage;
481 if (!A->getDeprecated().empty() && TargetMinVersion >= A->getDeprecated()) {
484 llvm::raw_string_ostream Out(*Message);
487 Out <<
"first deprecated in " << PrettyPlatformName <<
' '
488 << VTD << HintMessage;
498 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
499 return FTD->getTemplatedDecl()->getAvailability(Message);
502 std::string ResultMessage;
504 for (
const auto *A : attrs()) {
505 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
510 ResultMessage = Deprecated->getMessage();
516 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
518 *Message = Unavailable->getMessage();
522 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
532 ResultMessage.swap(*Message);
539 Message->swap(ResultMessage);
543 bool Decl::canBeWeakImported(
bool &IsDefinition)
const {
544 IsDefinition =
false;
547 if (
const VarDecl *Var = dyn_cast<VarDecl>(
this)) {
548 if (Var->isThisDeclarationADefinition()) {
555 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(
this)) {
563 }
else if (isa<ObjCInterfaceDecl>(
this) &&
564 getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {
573 bool Decl::isWeakImported()
const {
575 if (!canBeWeakImported(IsDefinition))
578 for (
const auto *A : attrs()) {
579 if (isa<WeakImportAttr>(A))
582 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
592 unsigned Decl::getIdentifierNamespaceForKind(
Kind DeclKind) {
597 case ConstructorUsingShadow:
607 return IDNS_Ordinary;
611 return IDNS_Ordinary | IDNS_Member;
613 case NonTypeTemplateParm:
617 return IDNS_Ordinary | IDNS_Tag;
619 case ObjCCompatibleAlias:
621 return IDNS_Ordinary | IDNS_Type;
625 case TypeAliasTemplate:
626 case UnresolvedUsingTypename:
627 case TemplateTypeParm:
629 return IDNS_Ordinary | IDNS_Type;
634 case UnresolvedUsingValue:
635 return IDNS_Ordinary | IDNS_Using;
641 return IDNS_ObjCProtocol;
644 case ObjCAtDefsField:
651 return IDNS_Tag | IDNS_Type;
655 return IDNS_Namespace;
657 case FunctionTemplate:
659 return IDNS_Ordinary;
662 case TemplateTemplateParm:
663 return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
665 case OMPDeclareReduction:
666 return IDNS_OMPReduction;
675 case ObjCPropertyImpl:
677 case PragmaDetectMismatch:
680 case TranslationUnit:
684 case BuiltinTemplate:
685 case ClassTemplateSpecialization:
686 case ClassTemplatePartialSpecialization:
687 case ClassScopeFunctionSpecialization:
688 case VarTemplateSpecialization:
689 case VarTemplatePartialSpecialization:
690 case ObjCImplementation:
692 case ObjCCategoryImpl:
694 case OMPThreadPrivate:
695 case OMPCapturedExpr:
701 llvm_unreachable(
"Invalid DeclKind!");
705 assert(!HasAttrs &&
"Decl already contains attrs.");
708 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
714 void Decl::dropAttrs() {
715 if (!HasAttrs)
return;
718 getASTContext().eraseDeclAttrs(
this);
721 const AttrVec &Decl::getAttrs()
const {
722 assert(HasAttrs &&
"No attrs to get!");
723 return getASTContext().getDeclAttrs(
this);
729 #define DECL(NAME, BASE)
730 #define DECL_CONTEXT(NAME) \
732 return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D));
733 #define DECL_CONTEXT_BASE(NAME)
734 #include "clang/AST/DeclNodes.inc"
736 #define DECL(NAME, BASE)
737 #define DECL_CONTEXT_BASE(NAME) \
738 if (DK >= first##NAME && DK <= last##NAME) \
739 return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D));
740 #include "clang/AST/DeclNodes.inc"
741 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
748 #define DECL(NAME, BASE)
749 #define DECL_CONTEXT(NAME) \
751 return static_cast<NAME##Decl*>(const_cast<Decl*>(D));
752 #define DECL_CONTEXT_BASE(NAME)
753 #include "clang/AST/DeclNodes.inc"
755 #define DECL(NAME, BASE)
756 #define DECL_CONTEXT_BASE(NAME) \
757 if (DK >= first##NAME && DK <= last##NAME) \
758 return static_cast<NAME##Decl*>(const_cast<Decl*>(D));
759 #include "clang/AST/DeclNodes.inc"
760 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
767 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(
this)) {
769 if (FD->hasBody(Definition))
774 if (
Stmt *Body = getBody())
775 return Body->getSourceRange().getEnd();
780 bool Decl::AccessDeclContextSanity()
const {
789 if (isa<TranslationUnitDecl>(
this) ||
790 isa<TemplateTypeParmDecl>(
this) ||
791 isa<NonTypeTemplateParmDecl>(
this) ||
792 !isa<CXXRecordDecl>(getDeclContext()) ||
794 isa<StaticAssertDecl>(
this) ||
797 isa<ParmVarDecl>(
this) ||
800 isa<CXXRecordDecl>(
this) ||
801 isa<ClassScopeFunctionSpecializationDecl>(
this))
805 "Access specifier is AS_none inside a record decl");
813 const FunctionType *Decl::getFunctionType(
bool BlocksToo)
const {
815 if (
const ValueDecl *D = dyn_cast<ValueDecl>(
this))
818 Ty = D->getUnderlyingType();
834 if (
getKind(D) == Decl::CXXMethod) {
840 }
else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
844 }
else if (
BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
846 }
else if (
CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
866 switch (D->getKind()) {
867 #define DECL(NAME, BASE)
868 #define DECL_CONTEXT(NAME) case Decl::NAME:
869 #define DECL_CONTEXT_BASE(NAME)
870 #include "clang/AST/DeclNodes.inc"
873 #define DECL(NAME, BASE)
874 #define DECL_CONTEXT_BASE(NAME) \
875 if (D->getKind() >= Decl::first##NAME && \
876 D->getKind() <= Decl::last##NAME) \
878 #include "clang/AST/DeclNodes.inc"
893 if (isa<FunctionDecl>(
this))
903 cast<NamespaceDecl>(
this)->isInline();
919 return II && II->
isStr(
"std");
926 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
929 if (
const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(
this)) {
930 if (Record->getDescribedClassTemplate())
933 if (Record->isDependentLambda())
937 if (
const FunctionDecl *Function = dyn_cast<FunctionDecl>(
this)) {
938 if (Function->getDescribedFunctionTemplate())
943 if (cast<Decl>(
this)->getFriendObjectKind())
955 if (DeclKind == Decl::Enum)
956 return !cast<EnumDecl>(
this)->isScoped();
957 else if (DeclKind == Decl::LinkageSpec)
965 while (DC->
getDeclKind() != Decl::TranslationUnit) {
967 return cast<LinkageSpecDecl>(DC)->getLanguage() ==
ID;
993 case Decl::TranslationUnit:
994 case Decl::ExternCContext:
995 case Decl::LinkageSpec:
998 case Decl::OMPDeclareReduction:
1002 case Decl::Namespace:
1004 return static_cast<NamespaceDecl*
>(
this)->getOriginalNamespace();
1006 case Decl::ObjCMethod:
1009 case Decl::ObjCInterface:
1015 case Decl::ObjCProtocol:
1021 case Decl::ObjCCategory:
1024 case Decl::ObjCImplementation:
1025 case Decl::ObjCCategoryImpl:
1029 if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) {
1032 TagDecl *Tag = cast<TagDecl>(
this);
1039 TagDecl *PossiblePartialDef = TagTy->getDecl();
1041 return PossiblePartialDef;
1049 assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction &&
1050 "Unknown DeclContext kind");
1059 if (DeclKind != Decl::Namespace) {
1060 Contexts.push_back(
this);
1066 N = N->getPreviousDecl())
1067 Contexts.push_back(N);
1069 std::reverse(Contexts.begin(), Contexts.end());
1072 std::pair<Decl *, Decl *>
1074 bool FieldsAlreadyLoaded) {
1076 Decl *FirstNewDecl =
nullptr;
1077 Decl *PrevDecl =
nullptr;
1078 for (
unsigned I = 0, N = Decls.size();
I != N; ++
I) {
1079 if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[
I]))
1084 PrevDecl->NextInContextAndBits.setPointer(D);
1091 return std::make_pair(FirstNewDecl, PrevDecl);
1097 void DeclContext::reconcileExternalVisibleStorage()
const {
1098 assert(NeedToReconcileExternalVisibleStorage && LookupPtr);
1099 NeedToReconcileExternalVisibleStorage =
false;
1101 for (
auto &Lookup : *LookupPtr)
1102 Lookup.second.setHasExternalDecls();
1109 DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1118 ExternalLexicalStorage =
false;
1126 bool FieldsAlreadyLoaded =
false;
1127 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(
this))
1128 FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage;
1132 Decl *ExternalFirst, *ExternalLast;
1133 std::tie(ExternalFirst, ExternalLast) =
1135 ExternalLast->NextInContextAndBits.setPointer(
FirstDecl);
1147 if (!(Map = DC->LookupPtr))
1148 Map = DC->CreateStoredDeclsMap(Context);
1149 if (DC->NeedToReconcileExternalVisibleStorage)
1150 DC->reconcileExternalVisibleStorage();
1152 (*Map)[
Name].removeExternalDecls();
1163 if (!(Map = DC->LookupPtr))
1164 Map = DC->CreateStoredDeclsMap(Context);
1165 if (DC->NeedToReconcileExternalVisibleStorage)
1166 DC->reconcileExternalVisibleStorage();
1179 for (
unsigned I = 0, N = Decls.size();
I != N; ++
I)
1182 Skip.push_back(Decls.size());
1185 unsigned SkipPos = 0;
1186 for (
unsigned I = 0, N = Decls.size(); I != N; ++
I) {
1187 if (I == Skip[SkipPos])
1195 I = Decls.begin(),
E = Decls.end();
I !=
E; ++
I) {
1208 LoadLexicalDeclsFromExternalStorage();
1214 LoadLexicalDeclsFromExternalStorage();
1220 return (D->getLexicalDeclContext() ==
this &&
1221 (D->NextInContextAndBits.getPointer() || D ==
LastDecl));
1225 assert(D->getLexicalDeclContext() ==
this &&
1226 "decl being removed from non-lexical context");
1227 assert((D->NextInContextAndBits.getPointer() || D ==
LastDecl) &&
1228 "decl is not in decls list");
1235 FirstDecl = D->NextInContextAndBits.getPointer();
1237 for (
Decl *
I =
FirstDecl;
true;
I =
I->NextInContextAndBits.getPointer()) {
1238 assert(
I &&
"decl not found in linked list");
1239 if (
I->NextInContextAndBits.getPointer() == D) {
1240 I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
1248 D->NextInContextAndBits.setPointer(
nullptr);
1251 if (isa<NamedDecl>(D)) {
1262 assert(Pos != Map->end() &&
"no lookup entry for decl");
1263 if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
1264 Pos->second.remove(ND);
1271 assert(D->getLexicalDeclContext() ==
this &&
1272 "Decl inserted into wrong lexical context");
1273 assert(!D->getNextDeclInContext() && D !=
LastDecl &&
1274 "Decl already inserted into a DeclContext");
1277 LastDecl->NextInContextAndBits.setPointer(D);
1286 Record->addedMember(D);
1290 if (!D->isFromASTFile()) {
1291 if (
ImportDecl *Import = dyn_cast<ImportDecl>(D))
1292 D->getASTContext().addedLocalImportDecl(Import);
1299 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1300 ND->getDeclContext()->getPrimaryContext()->
1301 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1307 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1308 ND->getDeclContext()->getPrimaryContext()->
1309 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1321 if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
1322 D->isTemplateParameter())
1329 if (isa<ClassTemplateSpecializationDecl>(D))
1332 if (FD->isFunctionTemplateSpecialization())
1348 if (!HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups)
1354 if (HasLazyExternalLexicalLookups) {
1355 HasLazyExternalLexicalLookups =
false;
1356 for (
auto *DC : Contexts) {
1358 HasLazyLocalLexicalLookups |=
1359 DC->LoadLexicalDeclsFromExternalStorage();
1362 if (!HasLazyLocalLexicalLookups)
1366 for (
auto *DC : Contexts)
1370 HasLazyLocalLexicalLookups =
false;
1378 void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1388 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1390 (!ND->isFromASTFile() ||
1393 makeDeclVisibleInContextImpl(ND, Internal);
1398 if (
DeclContext *InnerCtx = dyn_cast<DeclContext>(D))
1399 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1400 buildLookupImpl(InnerCtx, Internal);
1404 NamedDecl *
const DeclContextLookupResult::SingleElementDummyList =
nullptr;
1408 assert(DeclKind != Decl::LinkageSpec &&
1409 "Should not perform lookups into linkage specs!");
1412 if (PrimaryContext !=
this)
1413 return PrimaryContext->
lookup(Name);
1420 (void)cast<Decl>(
this)->getMostRecentDecl();
1423 assert(Source &&
"external visible storage but no external source?");
1425 if (NeedToReconcileExternalVisibleStorage)
1426 reconcileExternalVisibleStorage();
1430 if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
1438 std::pair<StoredDeclsMap::iterator, bool> R =
1440 if (!R.second && !R.first->second.hasExternalDecls())
1441 return R.first->second.getLookupResult();
1446 if (I != Map->end())
1447 return I->second.getLookupResult();
1455 if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
1462 if (I == Map->end())
1465 return I->second.getLookupResult();
1470 assert(DeclKind != Decl::LinkageSpec &&
1471 "Should not perform lookups into linkage specs!");
1474 if (PrimaryContext !=
this)
1480 if (HasLazyLocalLexicalLookups) {
1483 for (
unsigned I = 0, N = Contexts.size();
I != N; ++
I)
1485 HasLazyLocalLexicalLookups =
false;
1493 return I != Map->end() ? I->second.getLookupResult()
1505 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1511 if (Name && !HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups) {
1514 if (Pos !=
Map->end()) {
1515 Results.insert(Results.end(),
1516 Pos->second.getLookupResult().begin(),
1517 Pos->second.getLookupResult().end());
1527 for (
Decl *D =
FirstDecl; D; D = D->getNextDeclInContext()) {
1528 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1529 if (ND->getDeclName() ==
Name)
1530 Results.push_back(ND);
1555 OutermostRD = cast<RecordDecl>(DC);
1581 DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();
1584 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1587 void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1594 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1611 ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&
1618 makeDeclVisibleInContextImpl(D, Internal);
1620 HasLazyLocalLexicalLookups =
true;
1627 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1629 Decl *DCAsDecl = cast<Decl>(
this);
1631 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1633 L->AddedVisibleDecl(
this, D);
1636 void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1641 Map = CreateStoredDeclsMap(*C);
1667 if (DeclNameEntries.
isNull()) {
1683 return cast<UsingDirectiveDecl>(*I);
1700 assert(!LookupPtr &&
"context already has a decls map");
1702 "creating decls map on non-primary context");
1710 M->Previous = C.LastSDM;
1711 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1716 void ASTContext::ReleaseDeclContextMaps() {
1726 llvm::PointerIntPair<StoredDeclsMap*,1>
Next = Map->Previous;
1733 Map = Next.getPointer();
1734 Dependent = Next.getInt();
1742 &&
"cannot iterate dependent diagnostics of non-dependent context");
1744 if (!Parent->LookupPtr)
1745 Parent->CreateStoredDeclsMap(C);
1759 DD->NextDiagnostic = Map->FirstDiagnostic;
1760 Map->FirstDiagnostic = DD;
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...
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
static const Decl * getCanonicalDecl(const Decl *D)
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
void setHasExternalDecls()
AttrVec & getDeclAttrs(const Decl *D)
Retrieve the attributes for the given 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.
PointerType - C99 6.7.5.1 - Pointer Declarators.
static bool shouldBeHidden(NamedDecl *D)
shouldBeHidden - Determine whether a declaration which was declared within its semantic context shoul...
A (possibly-)qualified type.
UsingDirectiveDecl * operator*() const
Represents a version number in the form major[.minor[.subminor[.build]]].
void AddSubsequentDecl(NamedDecl *D)
AddSubsequentDecl - This is called on the second and later decl when it is not a redeclaration to mer...
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.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
static bool isLinkageSpecContext(const DeclContext *DC, LinkageSpecDecl::LanguageIDs ID)
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
FunctionType - C99 6.7.5.3 - Function Declarators.
C Language Family Type Representation.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
static TemplateDecl * getDescribedTemplate(Decl *Templated)
Defines the C++ template declaration subclasses.
static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl * > Decls)
bool isStdNamespace() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
std::unique_ptr< llvm::MemoryBuffer > Buffer
NamespaceDecl - Represent a C++ namespace.
bool isBlockPointerType() const
void localUncachedLookup(DeclarationName Name, SmallVectorImpl< NamedDecl * > &Results)
A simplistic name lookup mechanism that performs name lookup into this declaration context without co...
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...
bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer)
HandleRedeclaration - If this is a redeclaration of an existing decl, replace the old one with D and ...
VarDecl - An instance of this class is created to represent a variable declaration or definition...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled...
ObjCMethodDecl - Represents an instance or class method declaration.
Decl * FirstDecl
FirstDecl - The first declaration stored within this declaration context.
udir_range using_directives() const
Returns iterator range [First, Last) of UsingDirectiveDecls stored within this context.
ParmVarDecl - Represents a parameter to a function.
void removeDecl(Decl *D)
Removes a declaration from this context.
RecordDecl - Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
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 hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
bool isTranslationUnit() const
bool isInlineNamespace() const
static std::pair< Decl *, Decl * > BuildDeclChain(ArrayRef< Decl * > Decls, bool FieldsAlreadyLoaded)
Build up a chain of declarations.
Describes a module or submodule.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
const TargetInfo & getTargetInfo() const
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...
const LangOptions & getLangOpts() const
bool isInline() const
Returns true if this is an inline namespace declaration.
StoredDeclsMap * buildLookup()
Ensure the lookup structure is fully-built and return it.
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name)
bool containsDecl(Decl *D) const
Checks whether a declaration is in this context.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Represents an Objective-C protocol declaration.
This represents the body of a CapturedStmt, and serves as its DeclContext.
Represents an ObjC class declaration.
decl_iterator decls_begin() const
detail::InMemoryDirectory::const_iterator I
void addDeclInternal(Decl *D)
Add the declaration D into this context, but suppress searches for external declarations with the sam...
AvailabilityResult
Captures the result of checking the availability of a declaration.
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
bool isFunctionPointerType() const
void removeExternalDecls()
Remove any declarations which were imported from an external AST source.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
const char * getDeclKindName() const
const Type * getTypeForDecl() const
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
bool isLookupContext() const
Test whether the context supports looking up names.
llvm::iterator_range< udir_iterator > udir_range
Declaration of a template type parameter.
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
ASTContext & getParentASTContext() const
Decl * LastDecl
LastDecl - The last declaration stored within this declaration context.
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...
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
friend class DependentDiagnostic
bool isFunctionOrMethod() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
TagDecl * getDefinition() const
getDefinition - Returns the TagDecl that actually defines this struct/union/class/enum.
The result type of a method or function.
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.
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.
void print(raw_ostream &OS, const SourceManager &SM) const
Encodes a location in the source.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
const TemplateArgument * iterator
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...
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
Represents a static or instance method of a struct/union/class.
This file defines OpenMP nodes for declarative directives.
void print(raw_ostream &OS) const override
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isFileContext() const
DeclContextLookupResult lookup_result
An array of decls optimized for the common case of only containing one entry.
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
unsigned TypeAlias
Whether this template specialization type is a substituted type alias.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
QualType getPointeeType() const
decl_iterator - Iterates through the declarations stored within this context.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Base class for declarations which introduce a typedef-name.
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.).
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
DeclarationName - The name of a declaration.
detail::InMemoryDirectory::const_iterator E
static AvailabilityResult CheckAvailability(ASTContext &Context, const AvailabilityAttr *A, std::string *Message)
Determine the availability of the given declaration based on the target platform. ...
bool isLambda() const
Determine whether this class describes a lambda function object.
unsigned Map[Count]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
SmallVector< Context, 8 > Contexts
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)
const T * getAs() const
Member-template getAs<specific type>'.
Decl::Kind getDeclKind() const
LanguageIDs
Represents the language in a linkage specification.
void setOnlyValue(NamedDecl *ND)
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
void addDecl(Decl *D)
Add the declaration D into this context.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Represents a C++ struct/union/class.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
void * Allocate(size_t Size, unsigned Align=8) const
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.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
SourceRange getSourceRange() const override LLVM_READONLY
static Decl::Kind getKind(const Decl *D)
TranslationUnitDecl - 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...
NamedDecl - This represents a decl with a name.
void collectAllContexts(SmallVectorImpl< DeclContext * > &Contexts)
Collects all of the declaration contexts that are semantically connected to this declaration context...
Represents C++ using-directive.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
bool isBeingDefined() const
isBeingDefined - Return true if this decl is currently being defined.
Declaration of a template function.
Attr - This represents one attribute.
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any...