26 using namespace clang;
42 if (!PrevMemberDecl) {
52 diag::err_class_redeclared_with_different_access)
53 << MemberDecl << LexicalAS;
54 Diag(PrevMemberDecl->
getLocation(), diag::note_previous_access_declaration)
55 << PrevMemberDecl << PrevMemberDecl->
getAccess();
70 if (isa<EnumDecl>(DC))
71 DC = cast<EnumDecl>(DC)->getDeclContext();
75 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->
getDeclContext());
76 return DeclaringClass;
80 struct EffectiveContext {
81 EffectiveContext() : Inner(
nullptr), Dependent(
false) {}
106 if (isa<CXXRecordDecl>(DC)) {
110 }
else if (isa<FunctionDecl>(DC)) {
125 bool isDependent()
const {
return Dependent; }
129 return llvm::find(Records, R) != Records.end();
160 FoundDecl, BaseObjectType) {
174 bool isInstanceMember()
const {
175 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
178 bool hasInstanceContext()
const {
179 return HasInstanceContext;
182 class SavedInstanceContext {
184 SavedInstanceContext(SavedInstanceContext &&S)
185 :
Target(S.Target), Has(S.Has) {
188 ~SavedInstanceContext() {
190 Target->HasInstanceContext = Has;
194 friend struct AccessTarget;
195 explicit SavedInstanceContext(AccessTarget &
Target)
196 : Target(&Target), Has(Target.HasInstanceContext) {}
197 AccessTarget *Target;
201 SavedInstanceContext saveInstanceContext() {
202 return SavedInstanceContext(*
this);
205 void suppressInstanceContext() {
206 HasInstanceContext =
false;
210 assert(HasInstanceContext);
211 if (CalculatedInstanceContext)
212 return InstanceContext;
214 CalculatedInstanceContext =
true;
218 return InstanceContext;
222 return DeclaringClass;
230 namingClass = cast<CXXRecordDecl>(namingClass->
getParent());
236 HasInstanceContext = (isMemberAccess() &&
237 !getBaseObjectType().isNull() &&
238 getTargetDecl()->isCXXInstanceMember());
239 CalculatedInstanceContext =
false;
240 InstanceContext =
nullptr;
242 if (isMemberAccess())
245 DeclaringClass = getBaseClass();
246 DeclaringClass = DeclaringClass->getCanonicalDecl();
249 bool HasInstanceContext : 1;
250 mutable bool CalculatedInstanceContext : 1;
266 if (FromDC == ToDC)
return true;
297 for (
const auto &I : Derived->
bases()) {
302 RD = cast<CXXRecordDecl>(RT->getDecl());
320 if (Queue.empty())
break;
322 Derived = Queue.pop_back_val();
331 if (Friend == Context)
335 "can't handle friends with dependent contexts here");
350 if (Friend == Context)
353 if (!Friend->isDependentType() && !Context->isDependentType())
373 ->getAs<FunctionProtoType>();
376 ->getAs<FunctionProtoType>();
383 if (FriendTy->getNumParams() != ContextTy->getNumParams())
387 FriendTy->getReturnType()))
390 for (
unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
392 FriendTy->getParamType(I)))
407 const EffectiveContext &EC,
409 if (EC.includesClass(Friend))
412 if (EC.isDependent()) {
423 const EffectiveContext &EC,
426 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
429 if (Friend->isDependentType())
438 const EffectiveContext &EC,
445 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
452 if (isa<ClassTemplateSpecializationDecl>(Record)) {
453 CTD = cast<ClassTemplateSpecializationDecl>(Record)
454 ->getSpecializedTemplate();
467 if (!EC.isDependent())
491 const EffectiveContext &EC,
496 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
510 const EffectiveContext &EC,
517 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
521 FTD = (*I)->getDescribedFunctionTemplate();
540 const EffectiveContext &EC,
548 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
555 if (isa<ClassTemplateDecl>(Friend))
556 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
558 if (isa<FunctionTemplateDecl>(Friend))
559 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
561 if (isa<CXXRecordDecl>(Friend))
564 assert(isa<FunctionDecl>(Friend) &&
"unknown friend decl kind");
569 const EffectiveContext &EC,
574 for (
auto *Friend : Class->
friends()) {
596 struct ProtectedFriendContext {
598 const EffectiveContext &EC;
606 ProtectedFriendContext(
Sema &S,
const EffectiveContext &EC,
609 : S(S), EC(EC), NamingClass(NamingClass),
612 EverDependent(
false) {}
616 bool checkFriendshipAlongPath(
unsigned I) {
617 assert(I < CurPath.size());
618 for (
unsigned E = CurPath.size(); I != E; ++I) {
633 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
637 if (Cur == NamingClass)
638 return checkFriendshipAlongPath(PrivateDepth);
641 EverDependent =
true;
644 for (
const auto &I : Cur->
bases()) {
647 unsigned BasePrivateDepth = PrivateDepth;
649 BasePrivateDepth = CurPath.size() - 1;
655 RD = cast<CXXRecordDecl>(RT->getDecl());
661 EverDependent =
true;
666 CurPath.push_back(RD);
676 assert(CurPath.empty());
677 CurPath.push_back(Cur);
678 return findFriendship(Cur, 0);
712 assert(InstanceContext ==
nullptr ||
719 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
721 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
722 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
728 const EffectiveContext &EC,
731 const AccessTarget &Target) {
733 "declaration should be canonicalized before being passed here");
740 for (EffectiveContext::record_iterator
741 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
748 if (ECRecord == NamingClass)
780 if (!Target.hasInstanceContext()) {
791 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
792 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
817 assert(Target.isInstanceMember());
819 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
820 if (!InstanceContext) {
843 if (Access ==
AS_protected && Target.isInstanceMember()) {
846 if (Target.hasInstanceContext()) {
847 InstanceContext = Target.resolveInstanceContext(S);
856 llvm_unreachable(
"impossible friendship kind");
866 llvm_unreachable(
"impossible friendship kind");
926 const EffectiveContext &EC,
927 AccessTarget &Target,
935 bool isDerived = Derived->
isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
937 assert(isDerived &&
"derived class not actually derived from base");
942 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
944 bool AnyDependent =
false;
949 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
953 CXXBasePath::iterator I = PI->end(), E = PI->begin();
970 PathAccess =
std::max(PathAccess, BaseAccess);
972 switch (
HasAccess(S, EC, NC, PathAccess, Target)) {
979 Target.suppressInstanceContext();
989 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
991 BestPath->
Access = PathAccess;
1002 "fell out of loop with public path");
1018 AccessTarget &Target) {
1020 if (!Target.isInstanceMember())
1023 assert(Target.isMemberAccess());
1025 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1027 for (EffectiveContext::record_iterator
1028 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1048 if (!Target.hasInstanceContext()) {
1050 if (NamingClass == ECRecord)
continue;
1054 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1059 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1060 assert(InstanceContext &&
"diagnosing dependent access");
1072 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1073 (isa<FunctionTemplateDecl>(D) &&
1074 isa<CXXConstructorDecl>(
1075 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1077 diag::note_access_protected_restricted_ctordtor)
1083 diag::note_access_protected_restricted_object)
1093 const EffectiveContext &EC,
1094 AccessTarget &entity) {
1095 assert(entity.isMemberAccess());
1103 while (D->isOutOfLine()) {
1105 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1111 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1112 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1116 if (!PrevDecl)
break;
1121 Decl *ImmediateChild;
1122 if (D->getDeclContext() == DeclaringClass)
1126 while (DC->
getParent() != DeclaringClass)
1128 ImmediateChild = cast<Decl>(DC);
1133 bool isImplicit =
true;
1134 for (
const auto *I : DeclaringClass->
decls()) {
1135 if (I == ImmediateChild)
break;
1136 if (isa<AccessSpecDecl>(I)) {
1142 S.
Diag(D->getLocation(), diag::note_access_natural)
1150 const EffectiveContext &EC,
1151 AccessTarget &entity) {
1153 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1162 if (entity.isMemberAccess()) {
1165 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1167 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1172 entity.suppressInstanceContext();
1177 declaringClass == entity.getEffectiveNamingClass())
1182 llvm_unreachable(
"cannot diagnose dependent access");
1190 CXXBasePath::iterator
i = path.end(), e = path.begin();
1191 CXXBasePath::iterator constrainingBase =
i;
1205 if (baseAccess > accessSoFar) {
1206 constrainingBase =
i;
1207 accessSoFar = baseAccess;
1210 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1214 entity.suppressInstanceContext();
1215 constrainingBase =
nullptr;
1218 llvm_unreachable(
"cannot diagnose dependent access");
1225 assert(constrainingBase == i);
1232 if (constrainingBase == path.end())
1238 unsigned diagnostic;
1239 if (entity.isMemberAccess() ||
1240 constrainingBase + 1 != path.end()) {
1241 diagnostic = diag::note_access_constrained_by_path;
1243 diagnostic = diag::note_access_natural;
1253 if (entity.isMemberAccess())
1254 S.
Diag(entity.getTargetDecl()->getLocation(),
1255 diag::note_member_declared_at);
1259 const EffectiveContext &EC,
1260 AccessTarget &Entity) {
1262 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1263 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1265 S.
Diag(Loc, Entity.getDiag())
1295 AccessTarget &Entity) {
1297 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
1298 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1299 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1302 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1303 << Shadow->getUsingDecl()->getQualifiedNameAsString()
1314 const EffectiveContext &EC,
1315 AccessTarget &Entity) {
1317 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1320 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1326 if (UnprivilegedAccess !=
AS_none) {
1327 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1343 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1349 if (Entity.isMemberAccess()) {
1353 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1356 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1364 Entity.suppressInstanceContext();
1370 if (DeclaringClass == NamingClass)
1376 assert(Entity.getDeclaringClass() != NamingClass);
1384 assert(Path->
Access <= UnprivilegedAccess &&
1385 "access along best path worse than direct?");
1392 const EffectiveContext &EC,
1394 const AccessTarget &Entity) {
1395 assert(EC.isDependent() &&
"delaying non-dependent access");
1397 assert(DC->isDependentContext() &&
"delaying non-dependent access");
1400 Entity.isMemberAccess(),
1402 Entity.getTargetDecl(),
1403 Entity.getNamingClass(),
1404 Entity.getBaseObjectType(),
1410 const EffectiveContext &EC,
1412 AccessTarget &Entity) {
1413 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1424 if (!Entity.isQuiet())
1433 llvm_unreachable(
"invalid access result");
1437 AccessTarget &Entity) {
1464 llvm_unreachable(
"invalid access result");
1476 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1478 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1479 DC = cast<DeclContext>(TD->getTemplatedDecl());
1482 EffectiveContext EC(DC);
1497 if (!NamingD)
return;
1500 if (!TargetD)
return;
1504 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1506 if (!BaseObjectType.isNull()) {
1507 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1509 if (BaseObjectType.isNull())
return;
1512 AccessTarget Entity(Context,
1513 AccessTarget::Member,
1520 AccessTarget Entity(Context,
1522 cast<CXXRecordDecl>(TargetD),
1523 cast<CXXRecordDecl>(NamingD),
1532 if (!getLangOpts().AccessControl ||
1537 AccessTarget Entity(Context, AccessTarget::Member, E->
getNamingClass(),
1548 if (!getLangOpts().AccessControl ||
1556 AccessTarget Entity(Context, AccessTarget::Member, E->
getNamingClass(),
1569 if (access ==
AS_public || !getLangOpts().AccessControl)
return true;
1571 AccessTarget entity(Context, AccessTarget::Member, decl->
getParent(),
1575 entity.setDiag(PDiag());
1580 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1581 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1583 llvm_unreachable(
"bad access result");
1590 if (!getLangOpts().AccessControl)
1601 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1604 Entity.setDiag(PDiag);
1614 bool IsCopyBindingRefToTemp) {
1621 PD = PDiag(IsCopyBindingRefToTemp
1622 ? diag::ext_rvalue_to_reference_access_ctor
1623 : diag::err_access_ctor);
1628 PD = PDiag(diag::err_access_base_ctor);
1635 PD = PDiag(diag::err_access_field_ctor);
1636 PD << Field->
getType() << getSpecialMember(Constructor);
1642 PD = PDiag(diag::err_access_lambda_capture);
1643 PD << VarName << Entity.
getType() << getSpecialMember(Constructor);
1649 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1658 if (!getLangOpts().AccessControl ||
1675 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1676 }
else if (
auto *Shadow =
1677 dyn_cast<ConstructorUsingShadowDecl>(Found.
getDecl())) {
1682 ObjectClass = NamingClass;
1685 AccessTarget AccessEntity(
1686 Context, AccessTarget::Member, NamingClass,
1689 AccessEntity.setDiag(PD);
1700 if (!getLangOpts().AccessControl ||
1705 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1708 Entity.setDiag(diag::err_access)
1718 if (!getLangOpts().AccessControl ||
1723 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1734 if (!getLangOpts().AccessControl ||
1738 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1740 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1751 if (!getLangOpts().AccessControl ||
1758 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1760 Entity.setDiag(diag::err_access)
1775 if (!getLangOpts().AccessControl || access ==
AS_public)
1780 AccessTarget entity(Context, AccessTarget::Member,
1784 entity.setDiag(diag::err_access_friend_function)
1790 EffectiveContext EC(CurContext);
1796 llvm_unreachable(
"invalid access result");
1801 if (!getLangOpts().AccessControl ||
1809 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1811 Entity.setDiag(diag::err_access)
1829 bool ForceUnprivileged) {
1830 if (!ForceCheck && !getLangOpts().AccessControl)
1838 DerivedD = cast<CXXRecordDecl>(Derived->
getAs<
RecordType>()->getDecl());
1840 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1843 Entity.setDiag(DiagID) << Derived << Base;
1845 if (ForceUnprivileged) {
1847 AccessLoc, Entity)) {
1852 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1859 assert(getLangOpts().AccessControl
1860 &&
"performing access check without access control");
1861 assert(R.
getNamingClass() &&
"performing access check without naming class");
1868 Entity.setDiag(diag::err_access);
1895 if (!getLangOpts().CPlusPlus)
1903 EffectiveContext EC(CurContext);
1907 if (
ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1917 ClassOfMethodDecl = MD->getClassInterface();
1920 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1922 = dyn_cast<ObjCImplementationDecl>(Impl))
1923 ClassOfMethodDecl = IMPD->getClassInterface();
1925 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1926 ClassOfMethodDecl = CatImplClass->getClassInterface();
1931 if (!ClassOfMethodDecl)
1942 return Ivar->getContainingInterface()->
isSuperClassOf(ClassOfMethodDecl);
Defines the clang::ASTContext interface.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
AccessSpecifier getAccess() const
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
QualType getBaseObjectType() const
Returns the base object type associated with this lookup; important for [class.protected].
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration, or NULL if there is no previous declaration.
NamedDecl * getDecl() const
SourceLocation getAccessLoc() const
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
A container of type source information.
The entity being initialized is a base member subobject.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
Represents a C++ constructor within a class.
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
std::list< CXXBasePath >::iterator paths_iterator
const PartialDiagnostic & getDiagnostic() const
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
void CheckLookupAccess(const LookupResult &R)
Checks access to all the declarations in the given result set.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isInvalidDecl() const
EntityKind getKind() const
Determine the kind of initialization.
bool hasDefinition() const
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
Defines the clang::Expr interface and subclasses for C++ expressions.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity)
Determines whether the accessed entity is accessible.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isInheritedVirtualBase() const
Return whether the base is an inherited virtual base.
Represents a member of a struct/union/class.
AccessedEntity & getAccessData()
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
The iterator over UnresolvedSets.
Represents a C++ member access expression for which lookup produced a set of overloaded functions...
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...
__DEVICE__ int max(int __a, int __b)
static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class)
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)
Checks whether one class is derived from another, inclusively.
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Represents the results of name lookup.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl, AccessSpecifier access, QualType objectType)
Is the given special member function accessible for the purposes of deciding whether to define a spec...
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
The entity being initialized is a non-static data member subobject.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, QualType BaseType)
Checks access to Target from the given class.
AccessResult
A copy of Sema's enum without AR_delayed.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
const LangOptions & getLangOpts() const
Represents an ObjC class declaration.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
SourceLocation getMemberLoc() const
Retrieve the location of the name of the member that this expression refers to.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
Perform access-control checking on a previously-unresolved member access which has now been resolved ...
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
Sema - This implements semantic analysis and AST building for C.
This represents one expression.
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '...
A declaration being accessed, together with information about how it was accessed.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
const T * castAs() const
Member-template castAs<specific type>.
Represents a C++ destructor within a class.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)
Checks implicit access to a member in a structured binding.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
bool isLocalExternDecl()
Determine whether this is a block-scope declaration with linkage.
bool isFileContext() const
DeclContext * getDeclContext()
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
PartialDiagnostic::StorageAllocator & getDiagAllocator()
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Data structure that captures multiple levels of template argument lists for use in template instantia...
QualType getRecordType(const RecordDecl *Decl) const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
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 bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)
Checks whether one class might instantiate to the other.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so...
RecordDecl * getDecl() const
static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity)
Checks access to an entity from the given effective context.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr...
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...
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
SourceLocation getNameLoc() const
Gets the location of the name.
Encodes a location in the source.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
bool isAccessToMember() const
Represents the declaration of a struct/union/class/enum.
Represents a static or instance method of a struct/union/class.
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
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...
NamedDecl * getAccessNamingClass() const
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
AccessSpecifier getAccess() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
DeclarationNameInfo getNameInfo() const
CXXRecordDecl * getNamingClass()
Retrieve the naming class of this lookup.
The injected class name of a C++ class template or class template partial specialization.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
Defines various enumerations that describe declaration and type specifiers.
A POD class for pairing a NamedDecl* with an access specifier.
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)
Checks access to an overloaded operator new or delete.
Base class for declarations which introduce a typedef-name.
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
QualType getType() const
Retrieve type being initialized.
Dataflow Directional Tag Classes.
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
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.).
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
AccessSpecifier getAccess() const
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
The name of a declaration.
bool isCXXClassMember() const
Determine whether this declaration is a C++ class member.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
OverloadExpr * Expression
QualType getAccessBaseObjectType() const
friend_range friends() const
A dependently-generated diagnostic.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, Expr *ArgExpr, DeclAccessPair FoundDecl)
Checks access to an overloaded member operator, including conversion operators.
Represents a base class of a C++ class.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
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.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
ObjCIvarDecl - Represents an ObjC instance variable.
NamedDecl * getAccessTarget() const
The entity being initialized is the field that captures a variable in a lambda.
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)
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 CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)
Checks access to a member.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Declaration of a class template.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
AccessSpecifier Access
The access along this inheritance path.
static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
Diagnose the path which caused the given declaration or base class to become inaccessible.
std::string getQualifiedNameAsString() const
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass)
Search for a class P that EC is a friend of, under the constraint InstanceContext <= P if InstanceCon...
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
The initialization is being done by a delegating constructor.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
A trivial tuple used to represent a source range.
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
This represents a decl that may have a name.
void setAccess(AccessSpecifier AS)
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
SourceLocation getNameLoc() const
Gets the location of the identifier.
Describes an entity that is being initialized.
SourceLocation getBegin() const
static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target)
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
bool isUnsupportedFriend() const
Determines if this friend kind is unsupported.
QualType getBaseType() const
Declaration of a template function.
static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)
SourceLocation getLocation() const
Represents a shadow declaration introduced into a scope by a (resolved) using declaration.
QualType getType() const
Retrieves the type of the base class.