38 #include "llvm/ADT/ArrayRef.h" 39 #include "llvm/ADT/PointerIntPair.h" 40 #include "llvm/ADT/SmallVector.h" 41 #include "llvm/ADT/StringRef.h" 42 #include "llvm/Support/Casting.h" 43 #include "llvm/Support/ErrorHandling.h" 44 #include "llvm/Support/MathExtras.h" 45 #include "llvm/Support/raw_ostream.h" 53 using namespace clang;
59 #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0; 60 #define ABSTRACT_DECL(DECL) 61 #include "clang/AST/DeclNodes.inc" 67 #define DECL(DERIVED, BASE) \ 68 static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \ 69 "Alignment sufficient after objects prepended to " #DERIVED); 70 #define ABSTRACT_DECL(DECL) 71 #include "clang/AST/DeclNodes.inc" 77 static_assert(
sizeof(
unsigned) * 2 >=
alignof(
Decl),
78 "Decl won't be misaligned");
79 void *Start = Context.
Allocate(Size + Extra + 8);
80 void *
Result = (
char*)Start + 8;
82 unsigned *PrefixPtr = (
unsigned *)Result - 2;
95 assert(!
Parent || &
Parent->getParentASTContext() == &Ctx);
99 if (Ctx.getLangOpts().trackLocalOwningModule() || !
Parent) {
103 llvm::OffsetToAlignment(
sizeof(
Module *),
alignof(
Decl));
104 char *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)) {
150 Binding->setInvalidDecl();
157 default: llvm_unreachable(
"Declaration context not in DeclNodes.inc!");
158 #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; 159 #define ABSTRACT_DECL(DECL) 160 #include "clang/AST/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" 203 return TTP->isParameterPack();
205 = dyn_cast<NonTypeTemplateParmDecl>(
this))
206 return NTTP->isParameterPack();
208 = dyn_cast<TemplateTemplateParmDecl>(
this))
209 return TTP->isParameterPack();
214 if (
const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(
this))
215 return Parm->isParameterPack();
224 return FTD->getTemplatedDecl();
229 return isa<TemplateDecl>(
this);
233 if (
auto *FD = dyn_cast<FunctionDecl>(
this))
234 return FD->getDescribedFunctionTemplate();
235 else if (
auto *RD = dyn_cast<CXXRecordDecl>(
this))
236 return RD->getDescribedClassTemplate();
237 else if (
auto *VD = dyn_cast<VarDecl>(
this))
238 return VD->getDescribedVarTemplate();
239 else if (
auto *AD = dyn_cast<TypeAliasDecl>(
this))
240 return AD->getDescribedAliasTemplate();
250 if (
auto *AsDC = dyn_cast<DeclContext>(
this))
251 return AsDC->isDependentContext();
259 DC = DC->getParent())
260 if (DC->isFunctionOrMethod())
273 TheLoc = TheDecl->getLocation();
282 if (
const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) {
284 DN->printQualifiedName(OS);
308 getMultipleDC()->LexicalDC = DC;
322 "hidden declaration has no owning module");
327 if (SemaDC == LexicalDC) {
330 Decl::MultipleDC *MDC =
new (Ctx) Decl::MultipleDC();
331 MDC->SemanticDC = SemaDC;
332 MDC->LexicalDC = LexicalDC;
342 if (!isa<TagDecl>(LDC))
352 if (ND->isAnonymousNamespace())
368 assert(DC &&
"This decl is not contained in a translation unit!");
372 assert(DC &&
"This decl is not contained in a translation unit!");
375 return cast<TranslationUnitDecl>(DC);
395 Align =
std::max(Align, I->getAlignment(Ctx));
440 if (isa<TranslationUnitDecl>(
this) || isa<NamespaceDecl>(
this))
444 if (cast<Decl>(DC)->isModulePrivate())
446 if (isa<ExportDecl>(DC))
453 const Decl *Definition =
nullptr;
454 if (
auto ID = dyn_cast<ObjCInterfaceDecl>(
this)) {
455 Definition =
ID->getDefinition();
456 }
else if (
auto PD = dyn_cast<ObjCProtocolDecl>(
this)) {
457 Definition = PD->getDefinition();
458 }
else if (
auto TD = dyn_cast<TagDecl>(
this)) {
459 Definition = TD->getDefinition();
464 if (
auto *attr = Definition->
getAttr<ExternalSourceSymbolAttr>())
467 return dcd->
getAttr<ExternalSourceSymbolAttr>();
474 return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
478 if (AliasAttr *AA = getAttr<AliasAttr>())
480 if (IFuncAttr *IFA = getAttr<IFuncAttr>())
489 StringRef RealizedPlatform = A->getPlatform()->getName();
491 return RealizedPlatform;
492 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
493 if (suffix != StringRef::npos)
494 return RealizedPlatform.slice(0, suffix);
495 return RealizedPlatform;
508 const AvailabilityAttr *A,
509 std::string *Message,
511 if (EnclosingVersion.
empty())
514 if (EnclosingVersion.
empty())
517 StringRef ActualPlatform = A->getPlatform()->getName();
524 StringRef PrettyPlatformName
525 = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
527 if (PrettyPlatformName.empty())
528 PrettyPlatformName = ActualPlatform;
530 std::string HintMessage;
531 if (!A->getMessage().empty()) {
533 HintMessage += A->getMessage();
537 if (A->getUnavailable()) {
540 llvm::raw_string_ostream Out(*Message);
541 Out <<
"not available on " << PrettyPlatformName
549 if (!A->getIntroduced().empty() &&
550 EnclosingVersion < A->getIntroduced()) {
553 llvm::raw_string_ostream Out(*Message);
556 Out <<
"introduced in " << PrettyPlatformName <<
' ' 557 << VTI << HintMessage;
564 if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {
567 llvm::raw_string_ostream Out(*Message);
570 Out <<
"obsoleted in " << PrettyPlatformName <<
' ' 571 << VTO << HintMessage;
578 if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {
581 llvm::raw_string_ostream Out(*Message);
584 Out <<
"first deprecated in " << PrettyPlatformName <<
' ' 585 << VTD << HintMessage;
596 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
this))
597 return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion);
600 std::string ResultMessage;
602 for (
const auto *A :
attrs()) {
603 if (
const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
608 ResultMessage = Deprecated->getMessage();
614 if (
const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
616 *Message = Unavailable->getMessage();
620 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
622 Message, EnclosingVersion);
630 ResultMessage.swap(*Message);
637 Message->swap(ResultMessage);
644 for (
const auto *A :
attrs()) {
645 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
648 if (!Availability->getIntroduced().empty())
649 return Availability->getIntroduced();
656 IsDefinition =
false;
659 if (
const VarDecl *Var = dyn_cast<VarDecl>(
this)) {
660 if (Var->isThisDeclarationADefinition()) {
667 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(
this)) {
675 }
else if (isa<ObjCInterfaceDecl>(
this) &&
690 for (
const auto *A :
attrs()) {
691 if (isa<WeakImportAttr>(A))
694 if (
const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
707 case CXXDeductionGuide:
710 case ConstructorUsingShadow:
727 case NonTypeTemplateParm:
733 case ObjCCompatibleAlias:
739 case TemplateTypeParm:
743 case UnresolvedUsingTypename:
749 case UnresolvedUsingValue:
760 case ObjCAtDefsField:
773 case FunctionTemplate:
777 case TemplateTemplateParm:
778 case TypeAliasTemplate:
781 case OMPDeclareReduction:
792 case ObjCPropertyImpl:
794 case PragmaDetectMismatch:
797 case TranslationUnit:
802 case BuiltinTemplate:
803 case ClassTemplateSpecialization:
804 case ClassTemplatePartialSpecialization:
805 case ClassScopeFunctionSpecialization:
806 case VarTemplateSpecialization:
807 case VarTemplatePartialSpecialization:
808 case ObjCImplementation:
810 case ObjCCategoryImpl:
812 case OMPThreadPrivate:
813 case OMPCapturedExpr:
819 llvm_unreachable(
"Invalid DeclKind!");
823 assert(!HasAttrs &&
"Decl already contains attrs.");
826 assert(AttrBlank.empty() &&
"HasAttrs was wrong?");
833 if (!HasAttrs)
return;
840 assert(HasAttrs &&
"No attrs to get!");
847 #define DECL(NAME, BASE) 848 #define DECL_CONTEXT(NAME) \ 850 return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D)); 851 #define DECL_CONTEXT_BASE(NAME) 852 #include "clang/AST/DeclNodes.inc" 854 #define DECL(NAME, BASE) 855 #define DECL_CONTEXT_BASE(NAME) \ 856 if (DK >= first##NAME && DK <= last##NAME) \ 857 return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D)); 858 #include "clang/AST/DeclNodes.inc" 859 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
866 #define DECL(NAME, BASE) 867 #define DECL_CONTEXT(NAME) \ 869 return static_cast<NAME##Decl*>(const_cast<Decl*>(D)); 870 #define DECL_CONTEXT_BASE(NAME) 871 #include "clang/AST/DeclNodes.inc" 873 #define DECL(NAME, BASE) 874 #define DECL_CONTEXT_BASE(NAME) \ 875 if (DK >= first##NAME && DK <= last##NAME) \ 876 return static_cast<NAME##Decl*>(const_cast<Decl*>(D)); 877 #include "clang/AST/DeclNodes.inc" 878 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
885 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(
this)) {
887 if (FD->hasBody(Definition))
893 return Body->getSourceRange().getEnd();
898 bool Decl::AccessDeclContextSanity()
const {
908 if (isa<TranslationUnitDecl>(
this) ||
909 isa<TemplateTypeParmDecl>(
this) ||
910 isa<NonTypeTemplateParmDecl>(
this) ||
913 isa<StaticAssertDecl>(
this) ||
914 isa<BlockDecl>(
this) ||
917 isa<ParmVarDecl>(
this) ||
920 isa<CXXRecordDecl>(
this) ||
921 isa<ClassScopeFunctionSpecializationDecl>(
this))
925 "Access specifier is AS_none inside a record decl");
935 if (
const ValueDecl *D = dyn_cast<ValueDecl>(
this))
938 Ty = D->getUnderlyingType();
953 if (
getKind(D) == Decl::CXXMethod) {
959 }
else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
963 }
else if (
BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
965 }
else if (
CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
986 #define DECL(NAME, BASE) 987 #define DECL_CONTEXT(NAME) case Decl::NAME: 988 #define DECL_CONTEXT_BASE(NAME) 989 #include "clang/AST/DeclNodes.inc" 992 #define DECL(NAME, BASE) 993 #define DECL_CONTEXT_BASE(NAME) \ 994 if (D->getKind() >= Decl::first##NAME && \ 995 D->getKind() <= Decl::last##NAME) \ 997 #include "clang/AST/DeclNodes.inc" 1012 if (isa<FunctionDecl>(
this))
1013 if (getParent()->getRedeclContext()->isFileContext() &&
1014 getLexicalParent()->getRedeclContext()->isRecord())
1015 return getLexicalParent();
1021 return isNamespace() &&
1022 cast<NamespaceDecl>(
this)->isInline();
1034 if (!getParent()->getRedeclContext()->isTranslationUnit())
1038 return II && II->
isStr(
"std");
1042 if (isFileContext())
1045 if (isa<ClassTemplatePartialSpecializationDecl>(
this))
1048 if (
const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(
this)) {
1049 if (Record->getDescribedClassTemplate())
1052 if (Record->isDependentLambda())
1056 if (
const FunctionDecl *Function = dyn_cast<FunctionDecl>(
this)) {
1057 if (Function->getDescribedFunctionTemplate())
1062 if (cast<Decl>(
this)->getFriendObjectKind())
1063 return getLexicalParent()->isDependentContext();
1070 return getParent() && getParent()->isDependentContext();
1074 if (DeclKind == Decl::Enum)
1075 return !cast<EnumDecl>(
this)->isScoped();
1076 else if (DeclKind == Decl::LinkageSpec || DeclKind == Decl::Export)
1084 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1086 return cast<LinkageSpecDecl>(DC)->getLanguage() ==
ID;
1098 while (DC->
getDeclKind() != Decl::TranslationUnit) {
1101 return cast<LinkageSpecDecl>(DC);
1112 if (getPrimaryContext() !=
this)
1113 return getPrimaryContext()->Encloses(DC);
1123 case Decl::TranslationUnit:
1124 case Decl::ExternCContext:
1125 case Decl::LinkageSpec:
1128 case Decl::Captured:
1129 case Decl::OMPDeclareReduction:
1133 case Decl::Namespace:
1135 return static_cast<NamespaceDecl*
>(
this)->getOriginalNamespace();
1137 case Decl::ObjCMethod:
1140 case Decl::ObjCInterface:
1145 case Decl::ObjCProtocol:
1150 case Decl::ObjCCategory:
1153 case Decl::ObjCImplementation:
1154 case Decl::ObjCCategoryImpl:
1158 if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) {
1161 TagDecl *Tag = cast<TagDecl>(
this);
1168 TagDecl *PossiblePartialDef = TagTy->getDecl();
1170 return PossiblePartialDef;
1178 assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction &&
1179 "Unknown DeclContext kind");
1188 if (DeclKind != Decl::Namespace) {
1189 Contexts.push_back(
this);
1196 Contexts.push_back(N);
1198 std::reverse(Contexts.begin(), Contexts.end());
1201 std::pair<Decl *, Decl *>
1203 bool FieldsAlreadyLoaded) {
1205 Decl *FirstNewDecl =
nullptr;
1206 Decl *PrevDecl =
nullptr;
1207 for (
unsigned I = 0, N = Decls.size(); I != N; ++I) {
1208 if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I]))
1220 return std::make_pair(FirstNewDecl, PrevDecl);
1226 void DeclContext::reconcileExternalVisibleStorage()
const {
1227 assert(NeedToReconcileExternalVisibleStorage && LookupPtr);
1228 NeedToReconcileExternalVisibleStorage =
false;
1230 for (
auto &Lookup : *LookupPtr)
1231 Lookup.second.setHasExternalDecls();
1238 DeclContext::LoadLexicalDeclsFromExternalStorage()
const {
1240 assert(hasExternalLexicalStorage() && Source &&
"No external storage?");
1247 ExternalLexicalStorage =
false;
1255 bool FieldsAlreadyLoaded =
false;
1256 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(
this))
1257 FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage;
1261 Decl *ExternalFirst, *ExternalLast;
1262 std::tie(ExternalFirst, ExternalLast) =
1263 BuildDeclChain(Decls, FieldsAlreadyLoaded);
1264 ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
1265 FirstDecl = ExternalFirst;
1267 LastDecl = ExternalLast;
1276 if (!(Map = DC->LookupPtr))
1277 Map = DC->CreateStoredDeclsMap(Context);
1278 if (DC->NeedToReconcileExternalVisibleStorage)
1279 DC->reconcileExternalVisibleStorage();
1281 (*Map)[Name].removeExternalDecls();
1292 if (!(Map = DC->LookupPtr))
1293 Map = DC->CreateStoredDeclsMap(Context);
1294 if (DC->NeedToReconcileExternalVisibleStorage)
1295 DC->reconcileExternalVisibleStorage();
1308 for (
unsigned I = 0, N = Decls.size(); I != N; ++I)
1311 Skip.push_back(Decls.size());
1314 unsigned SkipPos = 0;
1315 for (
unsigned I = 0, N = Decls.size(); I != N; ++I) {
1316 if (I == Skip[SkipPos])
1324 I = Decls.begin(), E = Decls.end(); I != E; ++I) {
1336 if (hasExternalLexicalStorage())
1337 LoadLexicalDeclsFromExternalStorage();
1342 if (hasExternalLexicalStorage())
1343 LoadLexicalDeclsFromExternalStorage();
1355 "decl being removed from non-lexical context");
1357 "decl is not in decls list");
1360 if (D == FirstDecl) {
1362 FirstDecl = LastDecl =
nullptr;
1366 for (
Decl *I = FirstDecl;
true; I = I->NextInContextAndBits.getPointer()) {
1367 assert(I &&
"decl not found in linked list");
1368 if (I->NextInContextAndBits.getPointer() == D) {
1370 if (D == LastDecl) LastDecl = I;
1380 if (isa<NamedDecl>(D)) {
1390 StoredDeclsMap::iterator Pos = Map->find(ND->
getDeclName());
1391 assert(Pos != Map->end() &&
"no lookup entry for decl");
1392 if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
1393 Pos->second.remove(ND);
1395 }
while (DC->isTransparentContext() && (DC = DC->getParent()));
1401 "Decl inserted into wrong lexical context");
1403 "Decl already inserted into a DeclContext");
1406 LastDecl->NextInContextAndBits.setPointer(D);
1409 FirstDecl = LastDecl = D;
1415 Record->addedMember(D);
1420 if (
ImportDecl *Import = dyn_cast<ImportDecl>(D))
1428 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1429 ND->getDeclContext()->getPrimaryContext()->
1430 makeDeclVisibleInContextWithFlags(ND,
false,
true);
1436 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1437 ND->getDeclContext()->getPrimaryContext()->
1438 makeDeclVisibleInContextWithFlags(ND,
true,
true);
1458 if (isa<ClassTemplateSpecializationDecl>(D))
1461 if (FD->isFunctionTemplateSpecialization())
1475 assert(
this == getPrimaryContext() &&
"buildLookup called on non-primary DC");
1477 if (!HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups)
1481 collectAllContexts(Contexts);
1483 if (HasLazyExternalLexicalLookups) {
1484 HasLazyExternalLexicalLookups =
false;
1485 for (
auto *DC : Contexts) {
1486 if (DC->hasExternalLexicalStorage())
1487 HasLazyLocalLexicalLookups |=
1488 DC->LoadLexicalDeclsFromExternalStorage();
1491 if (!HasLazyLocalLexicalLookups)
1495 for (
auto *DC : Contexts)
1496 buildLookupImpl(DC, hasExternalVisibleStorage());
1499 HasLazyLocalLexicalLookups =
false;
1507 void DeclContext::buildLookupImpl(
DeclContext *DCtx,
bool Internal) {
1517 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1519 (!ND->isFromASTFile() ||
1520 (isTranslationUnit() &&
1521 !getParentASTContext().getLangOpts().CPlusPlus)))
1522 makeDeclVisibleInContextImpl(ND, Internal);
1527 if (
DeclContext *InnerCtx = dyn_cast<DeclContext>(D))
1528 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
1529 buildLookupImpl(InnerCtx, Internal);
1533 NamedDecl *
const DeclContextLookupResult::SingleElementDummyList =
nullptr;
1537 assert(DeclKind != Decl::LinkageSpec && DeclKind != Decl::Export &&
1538 "should not perform lookups into transparent contexts");
1540 const DeclContext *PrimaryContext = getPrimaryContext();
1541 if (PrimaryContext !=
this)
1542 return PrimaryContext->
lookup(Name);
1549 (void)cast<Decl>(
this)->getMostRecentDecl();
1551 if (hasExternalVisibleStorage()) {
1552 assert(Source &&
"external visible storage but no external source?");
1554 if (NeedToReconcileExternalVisibleStorage)
1555 reconcileExternalVisibleStorage();
1559 if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
1561 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1564 Map = CreateStoredDeclsMap(getParentASTContext());
1567 std::pair<StoredDeclsMap::iterator, bool> R =
1569 if (!R.second && !R.first->second.hasExternalDecls())
1570 return R.first->second.getLookupResult();
1574 StoredDeclsMap::iterator I = Map->find(Name);
1575 if (I != Map->end())
1576 return I->second.getLookupResult();
1584 if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
1585 Map =
const_cast<DeclContext*
>(
this)->buildLookup();
1590 StoredDeclsMap::iterator I = Map->find(Name);
1591 if (I == Map->end())
1594 return I->second.getLookupResult();
1599 assert(DeclKind != Decl::LinkageSpec && DeclKind != Decl::Export &&
1600 "should not perform lookups into transparent contexts");
1602 DeclContext *PrimaryContext = getPrimaryContext();
1603 if (PrimaryContext !=
this)
1609 if (HasLazyLocalLexicalLookups) {
1611 collectAllContexts(Contexts);
1612 for (
unsigned I = 0, N = Contexts.size(); I != N; ++I)
1613 buildLookupImpl(Contexts[I], hasExternalVisibleStorage());
1614 HasLazyLocalLexicalLookups =
false;
1621 StoredDeclsMap::iterator I = Map->find(Name);
1622 return I != Map->end() ? I->second.getLookupResult()
1632 if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
1634 Results.insert(Results.end(), LookupResults.
begin(), LookupResults.
end());
1640 if (Name && !HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups) {
1642 StoredDeclsMap::iterator Pos = Map->find(Name);
1643 if (Pos != Map->end()) {
1644 Results.insert(Results.end(),
1645 Pos->second.getLookupResult().begin(),
1646 Pos->second.getLookupResult().end());
1657 if (
NamedDecl *ND = dyn_cast<NamedDecl>(D))
1658 if (ND->getDeclName() == Name)
1659 Results.push_back(ND);
1684 OutermostRD = cast<RecordDecl>(DC);
1692 if (!isFileContext())
1709 DeclContext *PrimaryDC = this->getPrimaryContext();
1713 PrimaryDC->makeDeclVisibleInContextWithFlags(D,
false, PrimaryDC == DeclDC);
1716 void DeclContext::makeDeclVisibleInContextWithFlags(
NamedDecl *D,
bool Internal,
1718 assert(
this == getPrimaryContext() &&
"expected a primary DC");
1720 if (!isLookupContext()) {
1721 if (isTransparentContext())
1722 getParent()->getPrimaryContext()
1723 ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1739 if (LookupPtr || hasExternalVisibleStorage() ||
1741 (getParentASTContext().getLangOpts().CPlusPlus ||
1742 !isTranslationUnit()))) {
1747 makeDeclVisibleInContextImpl(D, Internal);
1749 HasLazyLocalLexicalLookups =
true;
1754 if (isTransparentContext() || isInlineNamespace())
1755 getParent()->getPrimaryContext()->
1756 makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
1758 Decl *DCAsDecl = cast<Decl>(
this);
1760 if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
1762 L->AddedVisibleDecl(
this, D);
1765 void DeclContext::makeDeclVisibleInContextImpl(
NamedDecl *D,
bool Internal) {
1770 Map = CreateStoredDeclsMap(*C);
1779 if (hasExternalVisibleStorage() &&
1781 Source->FindExternalVisibleDeclsByName(
this, D->
getDeclName());
1796 if (DeclNameEntries.
isNull()) {
1812 return cast<UsingDirectiveDecl>(*I);
1829 assert(!LookupPtr &&
"context already has a decls map");
1830 assert(getPrimaryContext() ==
this &&
1831 "creating decls map on non-primary context");
1834 bool Dependent = isDependentContext();
1839 M->Previous = C.LastSDM;
1840 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
1845 void ASTContext::ReleaseDeclContextMaps() {
1855 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous;
1862 Map = Next.getPointer();
1863 Dependent = Next.getInt();
1871 &&
"cannot iterate dependent diagnostics of non-dependent context");
1873 if (!Parent->LookupPtr)
1874 Parent->CreateStoredDeclsMap(C);
1888 DD->NextDiagnostic = Map->FirstDiagnostic;
1889 Map->FirstDiagnostic = DD;
static StringRef getRealizedPlatform(const AvailabilityAttr *A, const ASTContext &Context)
Defines the clang::ASTContext interface.
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.
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
getDefinition - 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.
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...
virtual void FindExternalLexicalDecls(const DeclContext *DC, llvm::function_ref< bool(Decl::Kind)> IsKindWeWant, SmallVectorImpl< Decl *> &Result)
Finds all declarations lexically contained within the given DeclContext, after applying an optional f...
RAII class for safely pairing a StartedDeserializing call with FinishedDeserializing.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
static Decl * castFromDeclContext(const DeclContext *)
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
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
const Type * getTypeForDecl() 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.
NamespaceDecl - Represent a C++ namespace.
const TargetInfo & getTargetInfo() const
unsigned getIdentifierNamespace() const
static Decl * getNonClosureContext(T *D)
Starting at a given context (a Decl or DeclContext), look for a code context that is not a closure (a...
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
unsigned Access
Access - Used by C++ decls for the access specifier.
bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer)
HandleRedeclaration - If this is a redeclaration of an existing decl, replace the old one with D and ...
bool hasOwningModule() const
Is this declaration owned by some module?
VarDecl - An instance of this class is created to represent a variable declaration or definition...
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...
ObjCMethodDecl - Represents an instance or class method declaration.
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.
ParmVarDecl - Represents a parameter to a function.
void removeDecl(Decl *D)
Removes a declaration from this context.
bool hasWeakClassImport() const
Does this runtime support weakly importing classes?
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Types, declared with 'struct foo', typedefs, etc.
bool isLexicallyWithinFunctionOrMethod() const
Returns true if this declaration lexically is inside a function.
RecordDecl - Represents a struct/union/class.
DeclarationName getDeclName() const
getDeclName - 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 ...
bool isInline() const
Returns true if this is an inline namespace declaration.
The results of name lookup within a DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Describes a module or submodule.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)
Update an out-of-date identifier.
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name)
Find all declarations with the given name in the given context, and add them to the context by callin...
Namespaces, declared with 'namespace foo {}'.
bool isReferenced() const
Whether any declaration of this entity was referenced.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
ModuleOwnershipKind getModuleOwnershipKind() const
Get the kind of module ownership for this declaration.
StoredDeclsMap * buildLookup()
Ensure the lookup structure is fully-built and return it.
static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name)
ASTContext & getASTContext() const
bool isLambda() const
Determine whether this class describes a lambda function object.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
void eraseDeclAttrs(const Decl *D)
Erase the attributes corresponding to the given declaration.
Represents an Objective-C protocol 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)
This represents the body of a CapturedStmt, and serves as its DeclContext.
Represents an ObjC class declaration.
Represents a linkage specification.
A binding in a decomposition declaration.
bool isExported() const
Whether this declaration is exported (by virtue of being lexically within an ExportDecl or by being a...
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
void addDeclInternal(Decl *D)
Add the declaration D into this context, but suppress searches for external declarations with the sam...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
AvailabilityResult
Captures the result of checking the availability of a declaration.
Decl * getNextDeclInContext()
bool canBeWeakImported(bool &IsDefinition) const
Determines whether this symbol can be weak-imported, e.g., whether it would be well-formed to add the...
udir_range using_directives() const
Returns iterator range [First, Last) of UsingDirectiveDecls stored within this context.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any...
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.
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
const Attr * getDefiningAttr() const
Return this declaration's defining attribute if it has one.
Defines the clang::LangOptions interface.
static unsigned getIdentifierNamespaceForKind(Kind DK)
const FunctionProtoType * T
bool containsDecl(Decl *D) const
Checks whether a declaration is in this context.
Declaration of a template type parameter.
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 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...
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
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...
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
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
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.
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
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
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
TagDecl - Represents the declaration of a struct/union/class/enum.
ASTContext & getASTContext() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
bool isStdNamespace() const
This file defines OpenMP nodes for declarative directives.
void print(raw_ostream &OS) const override
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.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
void * Allocate(size_t Size, unsigned Align=8) const
decl_iterator - Iterates through the declarations stored within this context.
Base class for declarations which introduce a typedef-name.
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.).
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
A decomposition declaration.
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
DeclarationName - The name of a declaration.
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
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'.
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.
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple()) const
Determine the availability of the given declaration.
unsigned getOwningModuleID() const
Retrieve the global ID of the module that owns this particular declaration.
void setOnlyValue(NamedDecl *ND)
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
const LinkageSpecDecl * getExternCContext() const
Retrieve the nearest enclosing C linkage specification context.
void addDecl(Decl *D)
Add the declaration D into this context.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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.
Represents a C++ struct/union/class.
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
Defines the clang::VersionTuple class, which represents a version in the form major[.minor[.subminor]].
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Kind
Lists the kind of concrete classes of Decl.
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...
bool trackLocalOwningModule() const
Do we need to track the owning module for a local declaration?
static void EnableStatistics()
bool isModulePrivate() const
Whether this declaration was marked as being private to the module in which it was defined...
void setLexicalDeclContext(DeclContext *DC)
NamedDecl - This represents a decl with a name.
bool isTranslationUnit() const
void setAccess(AccessSpecifier AS)
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration...
Represents C++ using-directive.
bool hasDefiningAttr() const
Return true if this declaration has an attribute which acts as definition of the entity, such as 'alias' or 'ifunc'.
bool isFunctionPointerType() const
void addedLocalImportDecl(ImportDecl *Import)
Notify the AST context that a new import declaration has been parsed or implicitly created within thi...
bool isInStdNamespace() const
TranslationUnitDecl * getTranslationUnitDecl()
const LangOptions & getLangOpts() const
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isTemplated() const
Determine whether this declaration is a templated entity (whether it is.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
Declaration of a template function.
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
isBeingDefined - 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.