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() {
186 Target.HasInstanceContext = Has;
190 friend struct AccessTarget;
191 explicit SavedInstanceContext(AccessTarget &Target)
192 : Target(Target), Has(Target.HasInstanceContext) {}
193 AccessTarget &Target;
197 SavedInstanceContext saveInstanceContext() {
198 return SavedInstanceContext(*
this);
201 void suppressInstanceContext() {
202 HasInstanceContext =
false;
206 assert(HasInstanceContext);
207 if (CalculatedInstanceContext)
208 return InstanceContext;
210 CalculatedInstanceContext =
true;
212 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
214 return InstanceContext;
218 return DeclaringClass;
226 namingClass = cast<CXXRecordDecl>(namingClass->
getParent());
232 HasInstanceContext = (isMemberAccess() &&
233 !getBaseObjectType().isNull() &&
234 getTargetDecl()->isCXXInstanceMember());
235 CalculatedInstanceContext =
false;
236 InstanceContext =
nullptr;
238 if (isMemberAccess())
241 DeclaringClass = getBaseClass();
242 DeclaringClass = DeclaringClass->getCanonicalDecl();
245 bool HasInstanceContext : 1;
246 mutable bool CalculatedInstanceContext : 1;
262 if (FromDC == ToDC)
return true;
292 for (
const auto &I : Derived->
bases()) {
297 RD = cast<CXXRecordDecl>(RT->getDecl());
315 if (Queue.empty())
break;
317 Derived = Queue.pop_back_val();
326 if (Friend == Context)
330 "can't handle friends with dependent contexts here");
345 if (Friend == Context)
348 if (!Friend->isDependentType() && !Context->isDependentType())
368 ->getAs<FunctionProtoType>();
371 ->getAs<FunctionProtoType>();
378 if (FriendTy->getNumParams() != ContextTy->getNumParams())
382 FriendTy->getReturnType()))
385 for (
unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
387 FriendTy->getParamType(I)))
402 const EffectiveContext &EC,
404 if (EC.includesClass(Friend))
407 if (EC.isDependent()) {
411 for (EffectiveContext::record_iterator
412 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
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())
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());
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();
954 CXXBasePath::iterator I = PI->end(), E = PI->begin();
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()))) {
1078 diag::note_access_protected_restricted_ctordtor)
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))
1112 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1113 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
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()) {
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");
1191 CXXBasePath::iterator i = path.end(), e = path.begin();
1192 CXXBasePath::iterator constrainingBase = i;
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();
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");
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) {
1616 if (!getLangOpts().AccessControl || Access ==
AS_public)
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, Entity, Access, PD);
1659 if (!getLangOpts().AccessControl ||
1670 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1672 ObjectClass = NamingClass;
1675 AccessTarget AccessEntity(
Context, AccessTarget::Member, NamingClass,
1678 AccessEntity.setDiag(PD);
1689 if (!getLangOpts().AccessControl ||
1694 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1697 Entity.setDiag(diag::err_access)
1707 if (!getLangOpts().AccessControl ||
1712 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1724 if (!getLangOpts().AccessControl ||
1731 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1733 Entity.setDiag(diag::err_access)
1734 << ObjectExpr->getSourceRange()
1735 << (ArgExpr ? ArgExpr->getSourceRange() :
SourceRange());
1748 if (!getLangOpts().AccessControl || access ==
AS_public)
1753 AccessTarget entity(
Context, AccessTarget::Member,
1757 entity.setDiag(diag::err_access_friend_function)
1763 EffectiveContext EC(CurContext);
1769 llvm_unreachable(
"falling off end");
1774 if (!getLangOpts().AccessControl ||
1782 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1784 Entity.setDiag(diag::err_access)
1785 << Ovl->getSourceRange();
1802 bool ForceUnprivileged) {
1803 if (!ForceCheck && !getLangOpts().AccessControl)
1811 DerivedD = cast<CXXRecordDecl>(Derived->
getAs<
RecordType>()->getDecl());
1813 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1816 Entity.setDiag(DiagID) << Derived << Base;
1818 if (ForceUnprivileged) {
1820 AccessLoc, Entity)) {
1825 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1832 assert(getLangOpts().AccessControl
1833 &&
"performing access check without access control");
1834 assert(R.
getNamingClass() &&
"performing access check without naming class");
1841 Entity.setDiag(diag::err_access);
1865 EffectiveContext EC(CurContext);
1869 if (
ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) {
1879 ClassOfMethodDecl = MD->getClassInterface();
1882 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1884 = dyn_cast<ObjCImplementationDecl>(Impl))
1885 ClassOfMethodDecl = IMPD->getClassInterface();
1887 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1888 ClassOfMethodDecl = CatImplClass->getClassInterface();
1893 if (!ClassOfMethodDecl)
1904 return Ivar->getContainingInterface()->
isSuperClassOf(ClassOfMethodDecl);
Defines the clang::ASTContext interface.
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
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)
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
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.
QualType getBaseObjectType() const
Returns the base object type associated with this lookup; important for [class.protected]. Most lookups do not have an associated base object.
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
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
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
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity)
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.
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.
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)
static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class)
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)
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)
NamedDecl * getAccessTarget() const
const CXXRecordDecl * getParent() const
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()
Represents an ObjC class declaration.
QualType getCanonicalTypeInternal() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
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.
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e. the class which was looked into to find these result...
Qualifiers getQualifiers() const
Retrieve all qualifiers.
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
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. This will either be a local variabl...
DeclContext * getDeclContext()
CXXRecordDecl * getNamingClass() const
Retrieve the naming class of this lookup.
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
bool isDependentType() const
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
static bool IsMicrosoftUsingDeclarationAccessBug(Sema &S, SourceLocation AccessLoc, AccessTarget &Entity)
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.
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
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)
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
TagDecl - Represents the declaration of a struct/union/class/enum.
bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx)
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)
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
SourceLocation getBegin() const
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. Used to record that a type was spelled with a bare identifier rather than as a template-id; the equivalent for non-templated classes is just RecordType.
QualType getPointeeType() const
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
Base class for declarations which introduce a typedef-name.
bool isAnonymousStructOrUnion() const
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.
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)
OverloadExpr * Expression
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CXXRecordDecl * getNamingClass() const
A dependently-generated diagnostic.
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
NamedDecl * getFriendDecl() const
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)
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.
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)
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. This is only calculated when recording paths. AS_none is a special value used to indicate a path which permits no legal access.
static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass)
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
DeclContext * getPrimaryContext()
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.
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
isNull - 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)
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.