26#include "llvm/ADT/ScopeExit.h"
41 if (!PrevMemberDecl) {
51 diag::err_class_redeclared_with_different_access)
52 << MemberDecl << LexicalAS;
53 Diag(PrevMemberDecl->
getLocation(), diag::note_previous_access_declaration)
54 << PrevMemberDecl << PrevMemberDecl->
getAccess();
75 return DeclaringClass;
79struct EffectiveContext {
82 explicit EffectiveContext(DeclContext *DC)
89 if (
auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
90 if (DGD->isImplicit()) {
91 DC = DGD->getCorrespondingConstructor();
122 DC =
Record->getDeclContext();
125 Functions.push_back(
Function->getCanonicalDecl());
126 if (
Function->getFriendObjectKind())
127 DC =
Function->getLexicalDeclContext();
138 bool isDependent()
const {
return Dependent; }
140 bool includesClass(
const CXXRecordDecl *R)
const {
141 R =
R->getCanonicalDecl();
142 return llvm::is_contained(
Records, R);
147 DeclContext *getInnerContext()
const {
151 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
154 SmallVector<FunctionDecl*, 4> Functions;
155 SmallVector<CXXRecordDecl*, 4>
Records;
162 AccessTarget(
const AccessedEntity &Entity)
163 : AccessedEntity(Entity) {
167 AccessTarget(ASTContext &Context,
169 CXXRecordDecl *NamingClass,
170 DeclAccessPair FoundDecl,
171 QualType BaseObjectType)
172 : AccessedEntity(Context.getDiagAllocator(),
Member, NamingClass,
173 FoundDecl, BaseObjectType) {
177 AccessTarget(ASTContext &Context,
179 CXXRecordDecl *BaseClass,
180 CXXRecordDecl *DerivedClass,
182 : AccessedEntity(Context.getDiagAllocator(),
Base, BaseClass, DerivedClass,
187 bool isInstanceMember()
const {
188 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
191 bool hasInstanceContext()
const {
192 return HasInstanceContext;
195 class SavedInstanceContext {
197 SavedInstanceContext(SavedInstanceContext &&S)
204 SavedInstanceContext &operator=(SavedInstanceContext &&) =
delete;
208 SavedInstanceContext(
const SavedInstanceContext &) =
delete;
209 SavedInstanceContext &operator=(
const SavedInstanceContext &) =
delete;
211 ~SavedInstanceContext() {
213 Target->HasInstanceContext = Has;
217 friend struct AccessTarget;
218 explicit SavedInstanceContext(AccessTarget &
Target)
224 SavedInstanceContext saveInstanceContext() {
225 return SavedInstanceContext(*
this);
228 void suppressInstanceContext() {
229 HasInstanceContext =
false;
232 const CXXRecordDecl *resolveInstanceContext(Sema &S)
const {
233 assert(HasInstanceContext);
234 if (CalculatedInstanceContext)
235 return InstanceContext;
237 CalculatedInstanceContext =
true;
241 return InstanceContext;
244 const CXXRecordDecl *getDeclaringClass()
const {
245 return DeclaringClass;
250 const CXXRecordDecl *getEffectiveNamingClass()
const {
251 const CXXRecordDecl *namingClass = getNamingClass();
259 HasInstanceContext = (isMemberAccess() &&
260 !getBaseObjectType().isNull() &&
261 getTargetDecl()->isCXXInstanceMember());
262 CalculatedInstanceContext =
false;
263 InstanceContext =
nullptr;
265 if (isMemberAccess())
268 DeclaringClass = getBaseClass();
269 DeclaringClass = DeclaringClass->getCanonicalDecl();
272 bool HasInstanceContext : 1;
273 mutable bool CalculatedInstanceContext : 1;
274 mutable const CXXRecordDecl *InstanceContext;
275 const CXXRecordDecl *DeclaringClass;
289static const TemplateSpecializationType *
296 if (
const auto *ICNT = Ty->
getAs<InjectedClassNameType>())
297 Ty = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Context);
300 if (TST && isa_and_nonnull<ClassTemplateDecl>(
301 TST->getTemplateName().getAsTemplateDecl()))
316 if (
auto *FTD = Pattern->getDescribedFunctionTemplate())
317 return FTD->getCanonicalDecl();
318 if (
auto *FTD = Pattern->getPrimaryTemplate())
319 return FTD->getCanonicalDecl();
332 if (
auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RD))
333 return Spec->getSpecializedTemplate();
358 const TemplateSpecializationType *TST,
362 const auto *CandidateRD = dyn_cast<CXXRecordDecl>(DC);
371 const auto *CandidateSpec =
372 dyn_cast<ClassTemplateSpecializationDecl>(CandidateRD);
375 CandidateCTD = CandidateSpec->getSpecializedTemplate();
376 CandidateArgs = CandidateSpec->getTemplateArgs().asArray();
379 auto *PatternCTD = dyn_cast_if_present<ClassTemplateDecl>(
380 TST->getTemplateName().getAsTemplateDecl());
386 TST->template_arguments(), CandidateArgs,
405 : S(S), FTD(FTD), Inst(S, FTD->getLocation(), FTD),
406 Info(FTD->getLocation()), Trap(S, Info), InstantiationScope(S) {}
411 if (Inst.isInvalid())
480 for (
const auto &I : Derived->
bases()) {
487 assert(
T->isDependentType() &&
"non-dependent base wasn't a record?");
500 if (Queue.empty())
break;
502 Derived = Queue.pop_back_val();
512 assert(!
Friend->isDependentContext() &&
513 "can't handle friends with dependent contexts here");
515 if (!Context->isDependentContext())
518 if (
Friend->isFileContext())
531 if (!
Friend->isDependentType() && !Context->isDependentType())
540 if (
Friend.getQualifiers() != Context.getQualifiers())
543 if (
Friend->getNumParams() != Context->getNumParams())
549 for (
unsigned I = 0, E =
Friend->getNumParams(); I != E; ++I)
561 if (Context.getNameKind() !=
Friend.getNameKind())
564 switch (Context.getNameKind()) {
581 DeclContext *ContextDC = Context->getDeclContext();
598 Friend->getTemplatedDecl());
602 const EffectiveContext &EC,
604 if (EC.includesClass(
Friend))
607 if (EC.isDependent()) {
618 const EffectiveContext &EC,
620 if (
const auto *RD =
Friend->getAsCXXRecordDecl())
624 if (
Friend->isDependentType())
633 const EffectiveContext &EC,
640 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
649 ->getSpecializedTemplate();
653 CTD =
Record->getDescribedClassTemplate();
662 if (!EC.isDependent())
685 const EffectiveContext &EC,
690 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
704 const EffectiveContext &EC,
711 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
747 const TemplateSpecializationType *FriendTST,
786 const auto *FriendTST =
802 FriendTST, TPLs.drop_back(), TPLs.back(), FailedTSC);
820 return MatchesFriend(S, EC, FTD, FriendCTD, Qualifier, FailedTSC);
835 const TemplateSpecializationType *FriendTST,
865 FriendInfo, InstTPL, ContextTemplate,
892 return OnSpecializationFailure;
898 ContextTemplate, ArgsWritten ? &InstArgs :
nullptr, InstFriendType,
899 ContextSpecialization,
903 return OnSpecializationFailure;
905 ContextFD = ContextSpecialization;
920 if (FriendRequiresClause.
isNull() != ContextRequiresClause.
isNull())
923 if (!FriendRequiresClause)
931 if (!InstFriendRequiresClause.
isUsable())
936 InstFriendRequiresClause.
get()))
955 MatchesFriend(S, FTD, FriendFD, ContextFD, FriendTST, TPLs, FailedTSC);
969 if (
auto *FriendCTD = dyn_cast_if_present<ClassTemplateDecl>(
972 if (
auto *FriendCTD = dyn_cast<ClassTemplateDecl>(
Friend))
988 if (
auto FriendTSTL =
990 const auto *FriendTST = FriendTSTL.getTypePtr();
992 S.
Context, FriendTSTL.getQualifierLoc().getNestedNameSpecifier());
1001 FriendName = TD->getDeclName();
1004 FriendName = DTN->getName().getIdentifier();
1014 if (FriendName && ContextCTD->
getDeclName() != FriendName)
1045 const auto *FriendDNT = FriendType->
getAs<DependentNameType>();
1050 S.
Context, FriendDNT->getQualifier());
1059 if (ContextRD->
getDeclName() != FriendDNT->getIdentifier())
1067 FriendTST, TPLs, FailedTSC, DeducedArgs);
1073 S, FTD, FriendDNT->getIdentifier(), FriendTagKind, ContextCTD,
1074 FriendTST, TPLs.drop_back(), TPLs.back(), FailedTSC);
1091 TPLs, FailedTSC, DeducedArgs);
1103 const EffectiveContext &EC,
1113 return MatchesFriend(S, EC,
T->getType()->getCanonicalTypeUnqualified());
1128 assert(
Friend &&
"friend template must name a type or declaration");
1140 if (
auto *FTD = dyn_cast<FriendTemplateDecl>(
Friend))
1166struct ProtectedFriendContext {
1168 const EffectiveContext &EC;
1169 TemplateSpecCandidateSet *FailedTSC;
1170 const CXXRecordDecl *NamingClass;
1171 bool CheckDependent;
1175 SmallVector<const CXXRecordDecl*, 20> CurPath;
1177 ProtectedFriendContext(Sema &S,
const EffectiveContext &EC,
1178 const CXXRecordDecl *InstanceContext,
1179 const CXXRecordDecl *NamingClass,
1180 TemplateSpecCandidateSet *FailedTSC)
1181 : S(S), EC(EC), FailedTSC(FailedTSC), NamingClass(NamingClass),
1182 CheckDependent(InstanceContext->isDependentContext() ||
1183 NamingClass->isDependentContext()),
1184 EverDependent(
false) {}
1188 bool checkFriendshipAlongPath(
unsigned I) {
1189 assert(I < CurPath.size());
1190 for (
unsigned E = CurPath.size(); I != E; ++I) {
1205 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
1209 if (Cur == NamingClass)
1210 return checkFriendshipAlongPath(PrivateDepth);
1213 EverDependent =
true;
1216 for (
const auto &I : Cur->
bases()) {
1219 unsigned BasePrivateDepth = PrivateDepth;
1221 BasePrivateDepth = CurPath.size() - 1;
1223 const CXXRecordDecl *RD;
1225 QualType
T = I.getType();
1230 EverDependent =
true;
1235 CurPath.push_back(RD);
1244 bool findFriendship(
const CXXRecordDecl *Cur) {
1245 assert(CurPath.empty());
1246 CurPath.push_back(Cur);
1247 return findFriendship(Cur, 0);
1281 assert(InstanceContext ==
nullptr ||
1288 if (!InstanceContext)
1291 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass, FailedTSC);
1292 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
1300 const AccessTarget &
Target,
1303 "declaration should be canonicalized before being passed here");
1310 for (EffectiveContext::record_iterator
1311 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1318 if (ECRecord == NamingClass)
1350 if (!
Target.hasInstanceContext()) {
1361 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
1362 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
1387 assert(
Target.isInstanceMember());
1390 if (!InstanceContext) {
1416 if (
Target.hasInstanceContext()) {
1417 InstanceContext =
Target.resolveInstanceContext(S);
1427 llvm_unreachable(
"impossible friendship kind");
1437 llvm_unreachable(
"impossible friendship kind");
1497 const EffectiveContext &EC,
1508 assert(isDerived &&
"derived class not actually derived from base");
1513 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
1515 bool AnyDependent =
false;
1520 AccessTarget::SavedInstanceContext _ =
Target.saveInstanceContext();
1524 CXXBasePath::iterator I = PI->end(), E = PI->begin();
1528 assert(PathAccess !=
AS_none);
1541 PathAccess = std::max(PathAccess, BaseAccess);
1551 Target.suppressInstanceContext();
1554 AnyDependent =
true;
1561 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
1563 BestPath->
Access = PathAccess;
1574 "fell out of loop with public path");
1592 if (!
Target.isInstanceMember())
1595 assert(
Target.isMemberAccess());
1599 for (EffectiveContext::record_iterator
1600 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1620 if (!
Target.hasInstanceContext()) {
1622 if (NamingClass == ECRecord)
continue;
1626 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1632 assert(InstanceContext &&
"diagnosing dependent access");
1649 diag::note_access_protected_restricted_ctordtor)
1655 diag::note_access_protected_restricted_object)
1665 const EffectiveContext &EC,
1666 AccessTarget &entity) {
1667 assert(entity.isMemberAccess());
1677 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1683 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1684 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD);
1689 if (!PrevDecl)
break;
1694 Decl *ImmediateChild;
1699 while (DC->
getParent() != DeclaringClass)
1706 bool isImplicit =
true;
1707 for (
const auto *I : DeclaringClass->
decls()) {
1708 if (I == ImmediateChild)
break;
1723 const EffectiveContext &EC,
1724 AccessTarget &entity) {
1726 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1735 if (entity.isMemberAccess()) {
1738 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1740 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity,
1746 entity.suppressInstanceContext();
1751 declaringClass == entity.getEffectiveNamingClass())
1756 llvm_unreachable(
"cannot diagnose dependent access");
1764 CXXBasePath::iterator i = path.end(), e = path.begin();
1765 CXXBasePath::iterator constrainingBase = i;
1779 if (baseAccess > accessSoFar) {
1780 constrainingBase = i;
1781 accessSoFar = baseAccess;
1784 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity,
1789 entity.suppressInstanceContext();
1790 constrainingBase =
nullptr;
1793 llvm_unreachable(
"cannot diagnose dependent access");
1800 assert(constrainingBase == i);
1807 if (constrainingBase == path.end())
1813 unsigned diagnostic;
1814 if (entity.isMemberAccess() ||
1815 constrainingBase + 1 != path.end()) {
1816 diagnostic = diag::note_access_constrained_by_path;
1818 diagnostic = diag::note_access_natural;
1828 if (entity.isMemberAccess())
1829 S.
Diag(entity.getTargetDecl()->getLocation(),
1830 diag::note_member_declared_at);
1834 const EffectiveContext &EC,
1835 AccessTarget &Entity) {
1837 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1838 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1840 S.
Diag(Loc, Entity.getDiag())
1870 AccessTarget &Entity) {
1872 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1873 if (
UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1874 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1875 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1878 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1879 << UD->getQualifiedNameAsString()
1890 AccessTarget &Entity,
1893 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1896 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1902 if (UnprivilegedAccess !=
AS_none) {
1904 HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity, FailedTSC)) {
1920 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1926 if (Entity.isMemberAccess()) {
1930 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1932 FinalAccess =
Target->getAccess();
1933 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity, FailedTSC)) {
1941 Entity.suppressInstanceContext();
1947 if (DeclaringClass == NamingClass)
1953 assert(Entity.getDeclaringClass() != NamingClass);
1961 assert(Path->
Access <= UnprivilegedAccess &&
1962 "access along best path worse than direct?");
1969 const EffectiveContext &EC,
1971 const AccessTarget &Entity) {
1972 assert(EC.isDependent() &&
"delaying non-dependent access");
1977 Entity.isMemberAccess(),
1979 Entity.getTargetDecl(),
1980 Entity.getNamingClass(),
1981 Entity.getBaseObjectType(),
1987 AccessTarget &Entity,
1989 assert((Entity.isQuiet() || FailedTSC) &&
1990 "non-quiet access check requires a candidate set");
2002 if (Entity.isQuiet())
2015 llvm_unreachable(
"invalid access result");
2020 AccessTarget &Entity) {
2021 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
2023 if (Entity.isQuiet())
2033 AccessTarget &Entity) {
2063 bool IsFriendDeclaration =
false;
2064 while (TS && !IsFriendDeclaration) {
2068 if (!IsFriendDeclaration) {
2080 llvm_unreachable(
"invalid access result");
2092 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
2094 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
2095 if (
auto *D = dyn_cast_if_present<DeclContext>(TD->getTemplatedDecl()))
2097 }
else if (
auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
2101 EffectiveContext EC(DC);
2116 if (!NamingD)
return;
2119 if (!TargetD)
return;
2125 if (!BaseObjectType.
isNull()) {
2126 BaseObjectType =
SubstType(BaseObjectType, TemplateArgs, Loc,
2128 if (BaseObjectType.
isNull())
return;
2132 AccessTarget::Member,
2189 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
2193 Entity.setDiag(
Diag);
2199 llvm::scope_exit UndelayDiags(
2201 DelayedDiagnostics.popUndelayed(CurrentState);
2207 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
2208 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
2210 llvm_unreachable(
"bad access result");
2227 ObjectTy =
Context.getCanonicalTagType(NamingClass);
2229 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
2232 Entity.setDiag(
PDiag);
2241 bool IsCopyBindingRefToTemp) {
2248 PD =
PDiag(IsCopyBindingRefToTemp
2249 ? diag::ext_rvalue_to_reference_access_ctor
2250 : diag::err_access_ctor);
2255 PD =
PDiag(diag::err_access_base_ctor);
2264 PD =
PDiag(diag::err_access_field_ctor);
2265 PD << Field->getType() <<
Constructor->getSpecialMemberKind();
2271 PD =
PDiag(diag::err_access_lambda_capture);
2304 }
else if (
auto *Shadow =
2305 dyn_cast<ConstructorUsingShadowDecl>(
Found.getDecl())) {
2310 ObjectClass = NamingClass;
2313 AccessTarget AccessEntity(
2314 Context, AccessTarget::Member, NamingClass,
2316 Context.getCanonicalTagType(ObjectClass));
2317 AccessEntity.setDiag(PD);
2332 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
2335 Entity.setDiag(diag::err_access)
2349 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
2363 AccessTarget Entity(
Context, AccessTarget::Member, DecomposedClass, Field,
2364 Context.getCanonicalTagType(DecomposedClass));
2365 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
2378 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
2380 Entity.setDiag(diag::err_access) << ObjectExpr->
getSourceRange() << Range;
2399 if (!ArgExprs.empty()) {
2401 ArgExprs.back()->getEndLoc());
2419 AccessTarget entity(
Context, AccessTarget::Member,
2423 entity.setDiag(diag::err_access_friend_function)
2435 llvm_unreachable(
"invalid access result");
2448 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
2450 Entity.setDiag(diag::err_access)
2460 bool ForceUnprivileged) {
2467 AccessTarget Entity(Context, AccessTarget::Base,
Base, Derived, Path.
Access);
2469 SetupPDiag(Entity.setDiag(DiagID));
2471 if (ForceUnprivileged) {
2474 case ::AR_accessible:
2476 case ::AR_inaccessible:
2478 case ::AR_dependent:
2481 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
2489 unsigned DiagID,
bool ForceCheck,
2490 bool ForceUnprivileged) {
2494 ForceCheck, ForceUnprivileged);
2499 &&
"performing access check without access control");
2500 assert(R.getNamingClass() &&
"performing access check without naming class");
2505 R.getNamingClass(), I.getPair(),
2506 R.getBaseObjectType());
2507 Entity.setDiag(diag::err_access);
2516 if (
Target->isCXXClassMember() && NamingClass) {
2526 return ::IsAccessible(*
this, EC, Entity,
nullptr) !=
2540 ClassOfMethodDecl = MD->getClassInterface();
2543 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
2545 = dyn_cast<ObjCImplementationDecl>(Impl))
2546 ClassOfMethodDecl = IMPD->getClassInterface();
2548 = dyn_cast<ObjCCategoryImplDecl>(Impl))
2549 ClassOfMethodDecl = CatImplClass->getClassInterface();
2554 if (!ClassOfMethodDecl)
2565 return Ivar->getContainingInterface()->
isSuperClassOf(ClassOfMethodDecl);
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::Expr interface and subclasses for C++ expressions.
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::Target Target
llvm::MachO::Records Records
llvm::MachO::Record Record
static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity, TemplateSpecCandidateSet *FailedTSC)
static bool HasSameFunctionType(Sema &S, QualType FriendType, QualType ContextType, SourceLocation Loc)
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target, TemplateSpecCandidateSet *FailedTSC)
AccessResult
A copy of Sema's enum without AR_delayed.
static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, AccessTarget &Target)
Given that an entity has protected natural access, check whether access might be denied because of th...
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)
Checks whether one class is derived from another, inclusively.
static void diagnoseBadDirectAccess(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
We are unable to access a given declaration due to its direct access control; diagnose that.
static ClassTemplateDecl * GetClassTemplatePattern(ClassTemplateDecl *CTD)
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
static AccessResult DeduceTemplateArguments(Sema &S, FriendTemplateDecl *FTD, DeclContext *DC, const TemplateSpecializationType *TST, ArrayRef< TemplateParameterList * > TPLs, TemplateSpecCandidateSet *FailedTSC, MultiLevelTemplateArgumentList &DeducedArgs)
static ClassTemplateDecl * GetClassTemplateDecl(CXXRecordDecl *RD)
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
static bool IsMicrosoftUsingDeclarationAccessBug(Sema &S, SourceLocation AccessLoc, AccessTarget &Entity)
MSVC has a bug where if during an using declaration name lookup, the declaration found is unaccessibl...
static CXXBasePath * FindBestPath(Sema &S, const EffectiveContext &EC, AccessTarget &Target, AccessSpecifier FinalAccess, CXXBasePaths &Paths)
Finds the best path from the naming class to the declaring class, taking friend declarations into acc...
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity, TemplateSpecCandidateSet *FailedTSC)
Determines whether the accessed entity is accessible.
static FunctionTemplateDecl * TryGetFunctionTemplateDecl(FunctionDecl *FD)
static TemplateParameterList * SubstTemplateParameterList(Sema &S, TemplateParameterList *TPL, DeclContext *DC, const MultiLevelTemplateArgumentList &Args)
static const TemplateSpecializationType * GetQualifierClassTemplateSpecializationType(ASTContext &Context, NestedNameSpecifier NNS)
static CanQual< FunctionProtoType > GetCanonicalFunctionProto(ASTContext &Context, QualType Ty)
static bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)
Checks whether one class might instantiate to the other.
static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
Diagnose the path which caused the given declaration or base class to become inaccessible.
static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class, TemplateSpecCandidateSet *FailedTSC)
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass, TemplateSpecCandidateSet *FailedTSC)
Search for a class P that EC is a friend of, under the constraint InstanceContext <= P if InstanceCon...
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
bool hasErrorOccurred() const
MultiLevelTemplateArgumentList & getDeducedArgs()
FriendTemplateMatchContext(Sema &S, FriendTemplateDecl *FTD)
bool hasDeducedArgs() const
AccessResult getAccessResult() const
AccessResult deduce(DeclContext *DC, const TemplateSpecializationType *TST, ArrayRef< TemplateParameterList * > TPLs, TemplateSpecCandidateSet *FailedTSC)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
std::list< CXXBasePath >::iterator paths_iterator
Represents a base class of a C++ class.
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool hasDefinition() const
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
bool isInjectedClassName() const
Determines whether this declaration represents the injected class name.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a canonical, potentially-qualified type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isFileContext() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool isInvalidDecl() const
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
void setAccess(AccessSpecifier AS)
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
@ CXXConversionFunctionName
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
A dependently-generated diagnostic.
NamedDecl * getAccessNamingClass() const
QualType getAccessBaseObjectType() const
bool isAccessToMember() const
NamedDecl * getAccessTarget() const
SourceLocation getAccessLoc() const
const PartialDiagnostic & getDiagnostic() const
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
AccessSpecifier getAccess() const
This represents one expression.
Represents a member of a struct/union/class.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
virtual NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Declaration of a friend template.
NamedDecl * getFriendDecl() const override
If this friend declaration doesn't name a type, return the inner declaration.
TemplateName getFriendTemplateName() const
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
DeclarationNameInfo getNameInfo() const
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Represents a prototype with parameter type info, e.g.
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Describes an entity that is being initialized.
EntityKind getKind() const
Determine the kind of initialization.
QualType getType() const
Retrieve type being initialized.
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
bool isInheritedVirtualBase() const
Return whether the base is an inherited virtual base.
@ EK_Member
The entity being initialized is a non-static data member subobject.
@ EK_Base
The entity being initialized is a base member subobject.
@ EK_ParenAggInitMember
The entity being initialized is a non-static data member subobject of an object initialized via paren...
@ EK_Delegating
The initialization is being done by a delegating constructor.
@ EK_LambdaCapture
The entity being initialized is the field that captures a variable in a lambda.
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Represents the results of name lookup.
UnresolvedSetImpl::iterator iterator
Data structure that captures multiple levels of template argument lists for use in template instantia...
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getQualifiedNameAsString() const
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
const Type * getAsType() const
@ Type
A type, stored as a Type*.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCMethodDecl - Represents an instance or class method declaration.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Scope - A scope is a transient data structure that is used while parsing the program.
bool isFriendScope() const
Determine whether this scope is a friend scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
A class which encapsulates the logic for delaying diagnostics during parsing and other processing.
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
DelayedDiagnosticsState pushUndelayed()
Enter a new scope where access and deprecation diagnostics are not delayed.
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)
Find the instantiation of the given declaration within the current instantiation.
TypeSourceInfo * SubstFriendType(TypeSourceInfo *TSI, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity)
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, SourceLocation Loc, const PartialDiagnostic &Diag)
Is the given member accessible for the purposes of deciding whether to define a special member functi...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
ExprResult SubstConstraintExprWithoutSatisfaction(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)
Checks access to an overloaded operator new or delete.
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, const SourceRange &, DeclAccessPair FoundDecl)
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
@ TPL_TemplateMatch
We are matching the template parameter lists of two templates that might be redeclarations.
const LangOptions & getLangOpts() const
AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)
Checks implicit access to a member in a structured binding.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
Perform access-control checking on a previously-unresolved member access which has now been resolved ...
bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, QualType BaseType)
Checks access to Target from the given class.
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
void CheckLookupAccess(const LookupResult &R)
Checks access to all the declarations in the given result set.
TemplateParameterList * SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraints=true)
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New)
AccessResult CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)
Checks access to a member.
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Represents the declaration of a struct/union/class/enum.
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
TagKind getTagKind() const
A convenient class for passing around template argument information.
void setLAngleLoc(SourceLocation Loc)
void setRAngleLoc(SourceLocation Loc)
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
bool isNull() const
Determine whether this template name is NULL.
Stores a list of template parameters for a TemplateDecl and its derived classes.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
ArrayRef< NamedDecl * > asArray()
SourceLocation getTemplateLoc() const
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
const TemplateSpecializationType * getAsNonAliasTemplateSpecializationType() const
Look through sugar for an instance of TemplateSpecializationType which is not a type alias,...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
const T * getAs() const
Member-template getAs<specific type>'.
Base class for declarations which introduce a typedef-name.
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
QualType getBaseType() const
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
CXXRecordDecl * getNamingClass()
Retrieve the naming class of this lookup.
SourceLocation getMemberLoc() const
Retrieve the location of the name of the member that this expression refers to.
Represents a C++ using-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represents a variable declaration or definition.
A declaration being accessed, together with information about how it was accessed.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
AccessedEntity & getAccessData()
static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)
Provides information about an attempted template argument deduction, whose success or failure was des...
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
const FunctionProtoType * T
TagTypeKind
The kind of a tag type.
@ Union
The "union" keyword.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
@ Success
Template argument deduction was successful.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation getLAngleLoc() const
ArrayRef< TemplateArgumentLoc > arguments() const
SourceLocation getRAngleLoc() const
const Expr * ConstraintExpr
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)
Converts an elaborated type keyword into a TagTypeKind.
OverloadExpr * Expression
A stack object to be created when performing template instantiation.