26 using namespace clang;
42 if (!PrevMemberDecl) {
44 MemberDecl->setAccess(LexicalAS);
50 if (LexicalAS !=
AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
51 Diag(MemberDecl->getLocation(),
52 diag::err_class_redeclared_with_different_access)
53 << MemberDecl << LexicalAS;
54 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
55 << PrevMemberDecl << PrevMemberDecl->getAccess();
57 MemberDecl->setAccess(LexicalAS);
61 MemberDecl->setAccess(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)) {
109 DC = Record->getDeclContext();
110 }
else if (isa<FunctionDecl>(DC)) {
113 if (Function->getFriendObjectKind())
114 DC = Function->getLexicalDeclContext();
116 DC = Function->getDeclContext();
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;
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;
298 for (
const auto &
I : Derived->
bases()) {
303 RD = cast<CXXRecordDecl>(RT->getDecl());
321 if (Queue.empty())
break;
323 Derived = Queue.pop_back_val();
332 if (Friend == Context)
336 "can't handle friends with dependent contexts here");
351 if (Friend == Context)
354 if (!Friend->isDependentType() && !Context->isDependentType())
368 Context->getDeclContext(),
369 Friend->getDeclContext()))
374 ->getAs<FunctionProtoType>();
377 ->getAs<FunctionProtoType>();
384 if (FriendTy->getNumParams() != ContextTy->getNumParams())
388 FriendTy->getReturnType()))
391 for (
unsigned I = 0,
E = FriendTy->getNumParams();
I !=
E; ++
I)
393 FriendTy->getParamType(
I)))
408 const EffectiveContext &EC,
410 if (EC.includesClass(Friend))
413 if (EC.isDependent()) {
424 const EffectiveContext &EC,
427 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
430 if (Friend->isDependentType())
439 const EffectiveContext &EC,
446 I = EC.Records.begin(),
E = EC.Records.end();
I !=
E; ++
I) {
453 if (isa<ClassTemplateSpecializationDecl>(Record)) {
454 CTD = cast<ClassTemplateSpecializationDecl>(Record)
455 ->getSpecializedTemplate();
468 if (!EC.isDependent())
479 Friend->getDeclContext()))
492 const EffectiveContext &EC,
497 I = EC.Functions.begin(),
E = EC.Functions.end();
I !=
E; ++
I) {
511 const EffectiveContext &EC,
518 I = EC.Functions.begin(),
E = EC.Functions.end();
I !=
E; ++
I) {
522 FTD = (*I)->getDescribedFunctionTemplate();
541 const EffectiveContext &EC,
549 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
552 = cast<NamedDecl>(FriendD->
getFriendDecl()->getCanonicalDecl());
556 if (isa<ClassTemplateDecl>(Friend))
557 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
559 if (isa<FunctionTemplateDecl>(Friend))
560 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
562 if (isa<CXXRecordDecl>(Friend))
565 assert(isa<FunctionDecl>(Friend) &&
"unknown friend decl kind");
570 const EffectiveContext &EC,
575 for (
auto *Friend : Class->
friends()) {
597 struct ProtectedFriendContext {
599 const EffectiveContext &EC;
607 ProtectedFriendContext(
Sema &S,
const EffectiveContext &EC,
610 : S(S), EC(EC), NamingClass(NamingClass),
611 CheckDependent(InstanceContext->isDependentContext() ||
612 NamingClass->isDependentContext()),
613 EverDependent(
false) {}
617 bool checkFriendshipAlongPath(
unsigned I) {
618 assert(I < CurPath.size());
619 for (
unsigned E = CurPath.size(); I !=
E; ++
I) {
634 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
638 if (Cur == NamingClass)
639 return checkFriendshipAlongPath(PrivateDepth);
642 EverDependent =
true;
645 for (
const auto &I : Cur->
bases()) {
648 unsigned BasePrivateDepth = PrivateDepth;
650 BasePrivateDepth = CurPath.size() - 1;
656 RD = cast<CXXRecordDecl>(RT->getDecl());
662 EverDependent =
true;
667 CurPath.push_back(RD);
677 assert(CurPath.empty());
678 CurPath.push_back(Cur);
679 return findFriendship(Cur, 0);
713 assert(InstanceContext ==
nullptr ||
720 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
722 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
723 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
729 const EffectiveContext &EC,
732 const AccessTarget &Target) {
734 "declaration should be canonicalized before being passed here");
741 for (EffectiveContext::record_iterator
742 I = EC.Records.begin(),
E = EC.Records.end(); I !=
E; ++
I) {
749 if (ECRecord == NamingClass)
781 if (!Target.hasInstanceContext()) {
792 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
793 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
818 assert(Target.isInstanceMember());
820 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
821 if (!InstanceContext) {
844 if (Access ==
AS_protected && Target.isInstanceMember()) {
847 if (Target.hasInstanceContext()) {
848 InstanceContext = Target.resolveInstanceContext(S);
857 llvm_unreachable(
"impossible friendship kind");
867 llvm_unreachable(
"impossible friendship kind");
927 const EffectiveContext &EC,
928 AccessTarget &Target,
936 bool isDerived = Derived->
isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
938 assert(isDerived &&
"derived class not actually derived from base");
943 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
945 bool AnyDependent =
false;
950 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
971 PathAccess =
std::max(PathAccess, BaseAccess);
973 switch (
HasAccess(S, EC, NC, PathAccess, Target)) {
980 Target.suppressInstanceContext();
990 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
992 BestPath->
Access = PathAccess;
1003 "fell out of loop with public path");
1019 AccessTarget &Target) {
1021 if (!Target.isInstanceMember())
1024 assert(Target.isMemberAccess());
1026 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1028 for (EffectiveContext::record_iterator
1029 I = EC.Records.begin(),
E = EC.Records.end(); I !=
E; ++
I) {
1049 if (!Target.hasInstanceContext()) {
1051 if (NamingClass == ECRecord)
continue;
1055 S.
Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1060 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1061 assert(InstanceContext &&
"diagnosing dependent access");
1073 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1074 (isa<FunctionTemplateDecl>(D) &&
1075 isa<CXXConstructorDecl>(
1076 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1077 return S.
Diag(D->getLocation(),
1078 diag::note_access_protected_restricted_ctordtor)
1079 << isa<CXXDestructorDecl>(D->getAsFunction());
1083 return S.
Diag(D->getLocation(),
1084 diag::note_access_protected_restricted_object)
1094 const EffectiveContext &EC,
1095 AccessTarget &entity) {
1096 assert(entity.isMemberAccess());
1104 while (D->isOutOfLine()) {
1106 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1107 PrevDecl = VD->getPreviousDecl();
1109 PrevDecl = FD->getPreviousDecl();
1111 PrevDecl = TND->getPreviousDecl();
1112 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1113 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1115 PrevDecl = TD->getPreviousDecl();
1117 if (!PrevDecl)
break;
1122 Decl *ImmediateChild;
1123 if (D->getDeclContext() == DeclaringClass)
1127 while (DC->
getParent() != DeclaringClass)
1129 ImmediateChild = cast<Decl>(DC);
1134 bool isImplicit =
true;
1135 for (
const auto *I : DeclaringClass->
decls()) {
1136 if (I == ImmediateChild)
break;
1137 if (isa<AccessSpecDecl>(I)) {
1143 S.
Diag(D->getLocation(), diag::note_access_natural)
1151 const EffectiveContext &EC,
1152 AccessTarget &entity) {
1154 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1163 if (entity.isMemberAccess()) {
1165 accessSoFar = D->getAccess();
1166 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1168 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1173 entity.suppressInstanceContext();
1178 declaringClass == entity.getEffectiveNamingClass())
1183 llvm_unreachable(
"cannot diagnose dependent access");
1206 if (baseAccess > accessSoFar) {
1207 constrainingBase = i;
1208 accessSoFar = baseAccess;
1211 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1215 entity.suppressInstanceContext();
1216 constrainingBase =
nullptr;
1219 llvm_unreachable(
"cannot diagnose dependent access");
1226 assert(constrainingBase == i);
1233 if (constrainingBase == path.end())
1239 unsigned diagnostic;
1240 if (entity.isMemberAccess() ||
1241 constrainingBase + 1 != path.end()) {
1242 diagnostic = diag::note_access_constrained_by_path;
1244 diagnostic = diag::note_access_natural;
1254 if (entity.isMemberAccess())
1255 S.
Diag(entity.getTargetDecl()->getLocation(),
1256 diag::note_member_declared_at);
1260 const EffectiveContext &EC,
1261 AccessTarget &Entity) {
1263 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1264 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1266 S.
Diag(Loc, Entity.getDiag())
1296 AccessTarget &Entity) {
1298 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
1299 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1300 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1303 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1304 << Shadow->getUsingDecl()->getQualifiedNameAsString()
1315 const EffectiveContext &EC,
1316 AccessTarget &Entity) {
1318 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1321 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1327 if (UnprivilegedAccess !=
AS_none) {
1328 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1344 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1350 if (Entity.isMemberAccess()) {
1353 NamedDecl *Target = Entity.getTargetDecl();
1354 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1356 FinalAccess = Target->getAccess();
1357 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1365 Entity.suppressInstanceContext();
1371 if (DeclaringClass == NamingClass)
1377 assert(Entity.getDeclaringClass() != NamingClass);
1385 assert(Path->
Access <= UnprivilegedAccess &&
1386 "access along best path worse than direct?");
1393 const EffectiveContext &EC,
1395 const AccessTarget &Entity) {
1396 assert(EC.isDependent() &&
"delaying non-dependent access");
1398 assert(DC->isDependentContext() &&
"delaying non-dependent access");
1401 Entity.isMemberAccess(),
1403 Entity.getTargetDecl(),
1404 Entity.getNamingClass(),
1405 Entity.getBaseObjectType(),
1411 const EffectiveContext &EC,
1413 AccessTarget &Entity) {
1414 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1425 if (!Entity.isQuiet())
1434 llvm_unreachable(
"invalid access result");
1438 AccessTarget &Entity) {
1465 llvm_unreachable(
"invalid access result");
1475 if (D->isLocalExternDecl()) {
1476 DC = D->getLexicalDeclContext();
1477 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1479 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1480 DC = cast<DeclContext>(TD->getTemplatedDecl());
1483 EffectiveContext EC(DC);
1498 if (!NamingD)
return;
1501 if (!TargetD)
return;
1505 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1507 if (!BaseObjectType.isNull()) {
1508 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1510 if (BaseObjectType.isNull())
return;
1514 AccessTarget::Member,
1523 cast<CXXRecordDecl>(TargetD),
1524 cast<CXXRecordDecl>(NamingD),
1533 if (!getLangOpts().AccessControl ||
1540 Entity.setDiag(diag::err_access) << E->getSourceRange();
1549 if (!getLangOpts().AccessControl ||
1559 Entity.setDiag(diag::err_access) << E->getSourceRange();
1570 if (access ==
AS_public || !getLangOpts().AccessControl)
return true;
1576 entity.setDiag(PDiag());
1581 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1582 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1584 llvm_unreachable(
"bad access result");
1591 if (!getLangOpts().AccessControl)
1602 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1605 Entity.setDiag(PDiag);
1615 bool IsCopyBindingRefToTemp) {
1622 PD = PDiag(IsCopyBindingRefToTemp
1623 ? diag::ext_rvalue_to_reference_access_ctor
1624 : diag::err_access_ctor);
1629 PD = PDiag(diag::err_access_base_ctor);
1636 PD = PDiag(diag::err_access_field_ctor);
1637 PD << Field->
getType() << getSpecialMember(Constructor);
1643 PD = PDiag(diag::err_access_lambda_capture);
1644 PD << VarName << Entity.
getType() << getSpecialMember(Constructor);
1650 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1659 if (!getLangOpts().AccessControl ||
1676 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1677 }
else if (
auto *Shadow =
1678 dyn_cast<ConstructorUsingShadowDecl>(Found.
getDecl())) {
1683 ObjectClass = NamingClass;
1686 AccessTarget AccessEntity(
1687 Context, AccessTarget::Member, NamingClass,
1690 AccessEntity.setDiag(PD);
1701 if (!getLangOpts().AccessControl ||
1706 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1709 Entity.setDiag(diag::err_access)
1719 if (!getLangOpts().AccessControl ||
1724 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1736 if (!getLangOpts().AccessControl ||
1743 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1745 Entity.setDiag(diag::err_access)
1746 << ObjectExpr->getSourceRange()
1747 << (ArgExpr ? ArgExpr->getSourceRange() :
SourceRange());
1754 assert(isa<CXXMethodDecl>(target->getAsFunction()));
1760 if (!getLangOpts().AccessControl || access ==
AS_public)
1763 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1765 AccessTarget entity(
Context, AccessTarget::Member,
1766 cast<CXXRecordDecl>(target->getDeclContext()),
1769 entity.setDiag(diag::err_access_friend_function)
1775 EffectiveContext EC(CurContext);
1781 llvm_unreachable(
"invalid access result");
1786 if (!getLangOpts().AccessControl ||
1794 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1796 Entity.setDiag(diag::err_access)
1797 << Ovl->getSourceRange();
1814 bool ForceUnprivileged) {
1815 if (!ForceCheck && !getLangOpts().AccessControl)
1823 DerivedD = cast<CXXRecordDecl>(Derived->
getAs<
RecordType>()->getDecl());
1825 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1828 Entity.setDiag(DiagID) << Derived << Base;
1830 if (ForceUnprivileged) {
1832 AccessLoc, Entity)) {
1837 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1844 assert(getLangOpts().AccessControl
1845 &&
"performing access check without access control");
1846 assert(R.
getNamingClass() &&
"performing access check without naming class");
1853 Entity.setDiag(diag::err_access);
1870 QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal();
1877 EffectiveContext EC(CurContext);
1881 if (
ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) {
1891 ClassOfMethodDecl = MD->getClassInterface();
1894 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1896 = dyn_cast<ObjCImplementationDecl>(Impl))
1897 ClassOfMethodDecl = IMPD->getClassInterface();
1899 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1900 ClassOfMethodDecl = CatImplClass->getClassInterface();
1905 if (!ClassOfMethodDecl)
1916 return Ivar->getContainingInterface()->
isSuperClassOf(ClassOfMethodDecl);
Defines the clang::ASTContext interface.
static const Decl * getCanonicalDecl(const Decl *D)
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.
AccessSpecifier getAccess() const
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
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.
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
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
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
Represents an ObjC class declaration.
detail::InMemoryDirectory::const_iterator I
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.
NamedDecl * getDecl() const
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.
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...
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.
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
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.).
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 ...
bool isLambda() const
Determine whether this class describes a lambda function object.
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
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.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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 ...
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
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
A trivial tuple used to represent a source range.
FunctionDecl * getCanonicalDecl() override
NamedDecl - This represents a decl with a name.
DeclarationNameInfo getNameInfo() const
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.