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) {}
85 Dependent(DC->isDependentContext()) {
106 if (isa<CXXRecordDecl>(DC)) {
110 }
else if (isa<FunctionDecl>(DC)) {
125 bool isDependent()
const {
return Dependent; }
129 return std::find(Records.begin(), Records.end(), R)
161 FoundDecl, BaseObjectType) {
175 bool isInstanceMember()
const {
176 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
179 bool hasInstanceContext()
const {
180 return HasInstanceContext;
183 class SavedInstanceContext {
185 SavedInstanceContext(SavedInstanceContext &&
S)
186 : Target(
S.Target), Has(
S.Has) {
189 ~SavedInstanceContext() {
191 Target->HasInstanceContext = Has;
195 friend struct AccessTarget;
196 explicit SavedInstanceContext(AccessTarget &Target)
197 : Target(&Target), Has(Target.HasInstanceContext) {}
198 AccessTarget *Target;
202 SavedInstanceContext saveInstanceContext() {
203 return SavedInstanceContext(*
this);
206 void suppressInstanceContext() {
207 HasInstanceContext =
false;
211 assert(HasInstanceContext);
212 if (CalculatedInstanceContext)
213 return InstanceContext;
215 CalculatedInstanceContext =
true;
217 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
219 return InstanceContext;
223 return DeclaringClass;
231 namingClass = cast<CXXRecordDecl>(namingClass->
getParent());
237 HasInstanceContext = (isMemberAccess() &&
238 !getBaseObjectType().isNull() &&
239 getTargetDecl()->isCXXInstanceMember());
240 CalculatedInstanceContext =
false;
241 InstanceContext =
nullptr;
243 if (isMemberAccess())
246 DeclaringClass = getBaseClass();
247 DeclaringClass = DeclaringClass->getCanonicalDecl();
250 bool HasInstanceContext : 1;
251 mutable bool CalculatedInstanceContext : 1;
267 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()) {
416 for (EffectiveContext::record_iterator
417 I = EC.Records.begin(),
E = EC.Records.end();
I !=
E; ++
I) {
429 const EffectiveContext &EC,
432 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
435 if (Friend->isDependentType())
444 const EffectiveContext &EC,
451 I = EC.Records.begin(),
E = EC.Records.end();
I !=
E; ++
I) {
458 if (isa<ClassTemplateSpecializationDecl>(Record)) {
459 CTD = cast<ClassTemplateSpecializationDecl>(Record)
460 ->getSpecializedTemplate();
473 if (!EC.isDependent())
497 const EffectiveContext &EC,
502 I = EC.Functions.begin(),
E = EC.Functions.end();
I !=
E; ++
I) {
516 const EffectiveContext &EC,
523 I = EC.Functions.begin(),
E = EC.Functions.end();
I !=
E; ++
I) {
527 FTD = (*I)->getDescribedFunctionTemplate();
546 const EffectiveContext &EC,
554 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
561 if (isa<ClassTemplateDecl>(Friend))
562 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
564 if (isa<FunctionTemplateDecl>(Friend))
565 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
567 if (isa<CXXRecordDecl>(Friend))
570 assert(isa<FunctionDecl>(Friend) &&
"unknown friend decl kind");
575 const EffectiveContext &EC,
580 for (
auto *Friend : Class->
friends()) {
602 struct ProtectedFriendContext {
604 const EffectiveContext &EC;
612 ProtectedFriendContext(
Sema &S,
const EffectiveContext &EC,
615 : S(S), EC(EC), NamingClass(NamingClass),
616 CheckDependent(InstanceContext->isDependentContext() ||
617 NamingClass->isDependentContext()),
618 EverDependent(
false) {}
622 bool checkFriendshipAlongPath(
unsigned I) {
623 assert(I < CurPath.size());
624 for (
unsigned E = CurPath.size(); I !=
E; ++
I) {
639 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
643 if (Cur == NamingClass)
644 return checkFriendshipAlongPath(PrivateDepth);
647 EverDependent =
true;
650 for (
const auto &I : Cur->
bases()) {
653 unsigned BasePrivateDepth = PrivateDepth;
655 BasePrivateDepth = CurPath.size() - 1;
661 RD = cast<CXXRecordDecl>(RT->getDecl());
667 EverDependent =
true;
672 CurPath.push_back(RD);
682 assert(CurPath.empty());
683 CurPath.push_back(Cur);
684 return findFriendship(Cur, 0);
718 assert(InstanceContext ==
nullptr ||
725 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
727 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
728 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
734 const EffectiveContext &EC,
737 const AccessTarget &Target) {
739 "declaration should be canonicalized before being passed here");
746 for (EffectiveContext::record_iterator
747 I = EC.Records.begin(),
E = EC.Records.end(); I !=
E; ++
I) {
754 if (ECRecord == NamingClass)
786 if (!Target.hasInstanceContext()) {
797 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
798 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
823 assert(Target.isInstanceMember());
825 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
826 if (!InstanceContext) {
849 if (Access ==
AS_protected && Target.isInstanceMember()) {
852 if (Target.hasInstanceContext()) {
853 InstanceContext = Target.resolveInstanceContext(S);
862 llvm_unreachable(
"impossible friendship kind");
872 llvm_unreachable(
"impossible friendship kind");
932 const EffectiveContext &EC,
933 AccessTarget &Target,
941 bool isDerived = Derived->
isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
943 assert(isDerived &&
"derived class not actually derived from base");
948 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
950 bool AnyDependent =
false;
955 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
976 PathAccess = std::max(PathAccess, BaseAccess);
978 switch (
HasAccess(S, EC, NC, PathAccess, Target)) {
985 Target.suppressInstanceContext();
995 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
997 BestPath->
Access = PathAccess;
1008 "fell out of loop with public path");
1024 AccessTarget &Target) {
1026 if (!Target.isInstanceMember())
1029 assert(Target.isMemberAccess());
1031 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1033 for (EffectiveContext::record_iterator
1034 I = EC.Records.begin(),
E = EC.Records.end(); I !=
E; ++
I) {
1054 if (!Target.hasInstanceContext()) {
1056 if (NamingClass == ECRecord)
continue;
1060 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1065 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1066 assert(InstanceContext &&
"diagnosing dependent access");
1078 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1079 (isa<FunctionTemplateDecl>(D) &&
1080 isa<CXXConstructorDecl>(
1081 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1083 diag::note_access_protected_restricted_ctordtor)
1089 diag::note_access_protected_restricted_object)
1099 const EffectiveContext &EC,
1100 AccessTarget &entity) {
1101 assert(entity.isMemberAccess());
1109 while (D->isOutOfLine()) {
1111 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1117 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1118 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1122 if (!PrevDecl)
break;
1127 Decl *ImmediateChild;
1128 if (D->getDeclContext() == DeclaringClass)
1132 while (DC->
getParent() != DeclaringClass)
1134 ImmediateChild = cast<Decl>(DC);
1139 bool isImplicit =
true;
1140 for (
const auto *I : DeclaringClass->
decls()) {
1141 if (I == ImmediateChild)
break;
1142 if (isa<AccessSpecDecl>(I)) {
1148 S.
Diag(D->getLocation(), diag::note_access_natural)
1156 const EffectiveContext &EC,
1157 AccessTarget &entity) {
1159 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1168 if (entity.isMemberAccess()) {
1171 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1173 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1178 entity.suppressInstanceContext();
1183 declaringClass == entity.getEffectiveNamingClass())
1188 llvm_unreachable(
"cannot diagnose dependent access");
1211 if (baseAccess > accessSoFar) {
1212 constrainingBase = i;
1213 accessSoFar = baseAccess;
1216 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1220 entity.suppressInstanceContext();
1221 constrainingBase =
nullptr;
1224 llvm_unreachable(
"cannot diagnose dependent access");
1231 assert(constrainingBase == i);
1238 if (constrainingBase == path.end())
1244 unsigned diagnostic;
1245 if (entity.isMemberAccess() ||
1246 constrainingBase + 1 != path.end()) {
1247 diagnostic = diag::note_access_constrained_by_path;
1249 diagnostic = diag::note_access_natural;
1259 if (entity.isMemberAccess())
1260 S.
Diag(entity.getTargetDecl()->getLocation(),
1261 diag::note_member_declared_at);
1265 const EffectiveContext &EC,
1266 AccessTarget &Entity) {
1268 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1269 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1271 S.
Diag(Loc, Entity.getDiag())
1301 AccessTarget &Entity) {
1303 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
1304 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1305 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1308 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1309 << Shadow->getUsingDecl()->getQualifiedNameAsString()
1320 const EffectiveContext &EC,
1321 AccessTarget &Entity) {
1323 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1326 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1332 if (UnprivilegedAccess !=
AS_none) {
1333 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1349 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1355 if (Entity.isMemberAccess()) {
1358 NamedDecl *Target = Entity.getTargetDecl();
1359 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1362 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1370 Entity.suppressInstanceContext();
1376 if (DeclaringClass == NamingClass)
1382 assert(Entity.getDeclaringClass() != NamingClass);
1390 assert(Path->
Access <= UnprivilegedAccess &&
1391 "access along best path worse than direct?");
1398 const EffectiveContext &EC,
1400 const AccessTarget &Entity) {
1401 assert(EC.isDependent() &&
"delaying non-dependent access");
1403 assert(DC->isDependentContext() &&
"delaying non-dependent access");
1406 Entity.isMemberAccess(),
1408 Entity.getTargetDecl(),
1409 Entity.getNamingClass(),
1410 Entity.getBaseObjectType(),
1416 const EffectiveContext &EC,
1418 AccessTarget &Entity) {
1419 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1430 if (!Entity.isQuiet())
1439 llvm_unreachable(
"invalid access result");
1443 AccessTarget &Entity) {
1470 llvm_unreachable(
"invalid access result");
1482 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1484 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1485 DC = cast<DeclContext>(TD->getTemplatedDecl());
1488 EffectiveContext EC(DC);
1503 if (!NamingD)
return;
1506 if (!TargetD)
return;
1510 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1512 if (!BaseObjectType.isNull()) {
1513 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1515 if (BaseObjectType.isNull())
return;
1519 AccessTarget::Member,
1528 cast<CXXRecordDecl>(TargetD),
1529 cast<CXXRecordDecl>(NamingD),
1538 if (!getLangOpts().AccessControl ||
1545 Entity.setDiag(diag::err_access) << E->getSourceRange();
1554 if (!getLangOpts().AccessControl ||
1564 Entity.setDiag(diag::err_access) << E->getSourceRange();
1575 if (access ==
AS_public || !getLangOpts().AccessControl)
return true;
1581 entity.setDiag(PDiag());
1586 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1587 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1589 llvm_unreachable(
"bad access result");
1596 if (!getLangOpts().AccessControl)
1607 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1610 Entity.setDiag(PDiag);
1620 bool IsCopyBindingRefToTemp) {
1621 if (!getLangOpts().AccessControl || Access ==
AS_public)
1627 PD = PDiag(IsCopyBindingRefToTemp
1628 ? diag::ext_rvalue_to_reference_access_ctor
1629 : diag::err_access_ctor);
1634 PD = PDiag(diag::err_access_base_ctor);
1641 PD = PDiag(diag::err_access_field_ctor);
1642 PD << Field->
getType() << getSpecialMember(Constructor);
1648 PD = PDiag(diag::err_access_lambda_capture);
1649 PD << VarName << Entity.
getType() << getSpecialMember(Constructor);
1655 return CheckConstructorAccess(UseLoc, Constructor, Entity, Access, PD);
1664 if (!getLangOpts().AccessControl ||
1675 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1677 ObjectClass = NamingClass;
1680 AccessTarget AccessEntity(
Context, AccessTarget::Member, NamingClass,
1683 AccessEntity.setDiag(PD);
1694 if (!getLangOpts().AccessControl ||
1699 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1702 Entity.setDiag(diag::err_access)
1712 if (!getLangOpts().AccessControl ||
1717 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1729 if (!getLangOpts().AccessControl ||
1736 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1738 Entity.setDiag(diag::err_access)
1739 << ObjectExpr->getSourceRange()
1740 << (ArgExpr ? ArgExpr->getSourceRange() :
SourceRange());
1753 if (!getLangOpts().AccessControl || access ==
AS_public)
1758 AccessTarget entity(
Context, AccessTarget::Member,
1762 entity.setDiag(diag::err_access_friend_function)
1768 EffectiveContext EC(CurContext);
1774 llvm_unreachable(
"invalid access result");
1779 if (!getLangOpts().AccessControl ||
1787 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1789 Entity.setDiag(diag::err_access)
1790 << Ovl->getSourceRange();
1807 bool ForceUnprivileged) {
1808 if (!ForceCheck && !getLangOpts().AccessControl)
1816 DerivedD = cast<CXXRecordDecl>(Derived->
getAs<
RecordType>()->getDecl());
1818 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1821 Entity.setDiag(DiagID) << Derived << Base;
1823 if (ForceUnprivileged) {
1825 AccessLoc, Entity)) {
1830 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1837 assert(getLangOpts().AccessControl
1838 &&
"performing access check without access control");
1839 assert(R.
getNamingClass() &&
"performing access check without naming class");
1846 Entity.setDiag(diag::err_access);
1870 EffectiveContext EC(CurContext);
1874 if (
ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) {
1884 ClassOfMethodDecl = MD->getClassInterface();
1887 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1889 = dyn_cast<ObjCImplementationDecl>(Impl))
1890 ClassOfMethodDecl = IMPD->getClassInterface();
1892 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1893 ClassOfMethodDecl = CatImplClass->getClassInterface();
1898 if (!ClassOfMethodDecl)
1909 return Ivar->getContainingInterface()->
isSuperClassOf(ClassOfMethodDecl);
Defines the clang::ASTContext interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
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.
AccessSpecifier getAccess() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
NamedDecl * getAccessNamingClass() const
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
const LangOptions & getLangOpts() const
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
AccessSpecifier getAccess() const
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, const InitializedEntity &Entity, AccessSpecifier Access, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
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.
bool hasDefinition() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
friend_range friends() const
bool isAccessToMember() const
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.
EntityKind getKind() const
Determine the kind of initialization.
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
QualType getBaseObjectType() const
Returns the base object type associated with this lookup; important for [class.protected].
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
AccessSpecifier getAccess() const
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.
SourceLocation getAccessLoc() const
ObjCMethodDecl - Represents an instance or class method declaration.
QualType getBaseType() const
Defines the clang::Expr interface and subclasses for C++ expressions.
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
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 ...
DeclaratorDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
CXXRecordDecl * getNamingClass() const
Gets the naming class of this lookup, if any.
AccessedEntity & getAccessData()
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
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...
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.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getAccessBaseObjectType() const
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Represents the results of name lookup.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
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...
NamedDecl * getAccessTarget() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
RecordDecl * getDecl() const
The entity being initialized is a non-static data member subobject.
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)...
Represents an ObjC class declaration.
detail::InMemoryDirectory::const_iterator I
QualType getCanonicalTypeInternal() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
Perform access-control checking on a previously-unresolved member access which has now been resolved ...
bool isInheritedVirtualBase() const
Return whether the base is an inherited virtual base.
Sema - This implements semantic analysis and AST building for C.
bool isCXXClassMember() const
Determine whether this declaration is a C++ class member.
Expr - This represents one expression.
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
A declaration being accessed, together with information about how it was accessed.
SourceLocation getNameLoc() const
Gets the location of the name.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the identifier.
SourceLocation getMemberLoc() const
Represents a C++ destructor within a class.
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
bool isLocalExternDecl()
Determine whether this is a block-scope declaration with linkage.
DeclContext * getDeclContext()
CXXRecordDecl * getNamingClass() const
Retrieve the naming class of this lookup.
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Data structure that captures multiple levels of template argument lists for use in template instantia...
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
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.
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.
Encodes a location in the source.
const TemplateArgument * iterator
TagDecl - Represents the declaration of a struct/union/class/enum.
bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx)
Checks access to Decl from the given class.
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...
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
bool isFileContext() const
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '...
The injected class name of a C++ class template or class template partial specialization.
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
QualType getPointeeType() const
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.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Base class for declarations which introduce a typedef-name.
bool isAnonymousStructOrUnion() const
isAnonymousStructOrUnion - Whether this is an anonymous struct or union.
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
bool isUnsupportedFriend() const
Determines if this friend kind is unsupported.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
const PartialDiagnostic & getDiagnostic() const
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
The base class of all kinds of template declarations (e.g., class, function, etc.).
bool isInvalidDecl() const
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
DeclarationName - The name of a declaration.
OverloadExpr * Expression
detail::InMemoryDirectory::const_iterator E
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CXXRecordDecl * getNamingClass() const
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
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)
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
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.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so...
Represents a base class of a C++ class.
QualType getType() const
Retrieve type being initialized.
std::string getQualifiedNameAsString() const
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.
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.
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.
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...
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
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
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
NamedDecl - This represents a decl with a name.
DeclarationNameInfo getNameInfo() const
void setAccess(AccessSpecifier AS)
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Describes an entity that is being initialized.
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...
Declaration of a template function.
std::list< CXXBasePath >::iterator paths_iterator
static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)
Represents a shadow declaration introduced into a scope by a (resolved) using declaration.