24#include "llvm/ADT/ScopeExit.h"
39 if (!PrevMemberDecl) {
49 diag::err_class_redeclared_with_different_access)
50 << MemberDecl << LexicalAS;
51 Diag(PrevMemberDecl->
getLocation(), diag::note_previous_access_declaration)
52 << PrevMemberDecl << PrevMemberDecl->
getAccess();
73 return DeclaringClass;
77struct EffectiveContext {
80 explicit EffectiveContext(DeclContext *DC)
87 if (
auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
88 if (DGD->isImplicit()) {
89 DC = DGD->getCorrespondingConstructor();
120 DC =
Record->getDeclContext();
123 Functions.push_back(
Function->getCanonicalDecl());
124 if (
Function->getFriendObjectKind())
125 DC =
Function->getLexicalDeclContext();
136 bool isDependent()
const {
return Dependent; }
138 bool includesClass(
const CXXRecordDecl *R)
const {
139 R =
R->getCanonicalDecl();
140 return llvm::is_contained(
Records, R);
145 DeclContext *getInnerContext()
const {
149 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
152 SmallVector<FunctionDecl*, 4> Functions;
153 SmallVector<CXXRecordDecl*, 4>
Records;
160 AccessTarget(
const AccessedEntity &Entity)
161 : AccessedEntity(Entity) {
165 AccessTarget(ASTContext &Context,
167 CXXRecordDecl *NamingClass,
168 DeclAccessPair FoundDecl,
169 QualType BaseObjectType)
170 : AccessedEntity(Context.getDiagAllocator(),
Member, NamingClass,
171 FoundDecl, BaseObjectType) {
175 AccessTarget(ASTContext &Context,
177 CXXRecordDecl *BaseClass,
178 CXXRecordDecl *DerivedClass,
180 : AccessedEntity(Context.getDiagAllocator(),
Base, BaseClass, DerivedClass,
185 bool isInstanceMember()
const {
186 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
189 bool hasInstanceContext()
const {
190 return HasInstanceContext;
193 class SavedInstanceContext {
195 SavedInstanceContext(SavedInstanceContext &&S)
202 SavedInstanceContext &operator=(SavedInstanceContext &&) =
delete;
206 SavedInstanceContext(
const SavedInstanceContext &) =
delete;
207 SavedInstanceContext &operator=(
const SavedInstanceContext &) =
delete;
209 ~SavedInstanceContext() {
211 Target->HasInstanceContext = Has;
215 friend struct AccessTarget;
216 explicit SavedInstanceContext(AccessTarget &
Target)
222 SavedInstanceContext saveInstanceContext() {
223 return SavedInstanceContext(*
this);
226 void suppressInstanceContext() {
227 HasInstanceContext =
false;
230 const CXXRecordDecl *resolveInstanceContext(Sema &S)
const {
231 assert(HasInstanceContext);
232 if (CalculatedInstanceContext)
233 return InstanceContext;
235 CalculatedInstanceContext =
true;
239 return InstanceContext;
242 const CXXRecordDecl *getDeclaringClass()
const {
243 return DeclaringClass;
248 const CXXRecordDecl *getEffectiveNamingClass()
const {
249 const CXXRecordDecl *namingClass = getNamingClass();
257 HasInstanceContext = (isMemberAccess() &&
258 !getBaseObjectType().isNull() &&
259 getTargetDecl()->isCXXInstanceMember());
260 CalculatedInstanceContext =
false;
261 InstanceContext =
nullptr;
263 if (isMemberAccess())
266 DeclaringClass = getBaseClass();
267 DeclaringClass = DeclaringClass->getCanonicalDecl();
270 bool HasInstanceContext : 1;
271 mutable bool CalculatedInstanceContext : 1;
272 mutable const CXXRecordDecl *InstanceContext;
273 const CXXRecordDecl *DeclaringClass;
287 if (FromDC == ToDC)
return true;
318 for (
const auto &I : Derived->
bases()) {
325 assert(
T->isDependentType() &&
"non-dependent base wasn't a record?");
338 if (Queue.empty())
break;
340 Derived = Queue.pop_back_val();
352 assert(!
Friend->isDependentContext() &&
353 "can't handle friends with dependent contexts here");
355 if (!Context->isDependentContext())
358 if (
Friend->isFileContext())
371 if (!
Friend->isDependentType() && !Context->isDependentType())
381 if (Context->getDeclName() !=
Friend->getDeclName())
385 Context->getDeclContext(),
386 Friend->getDeclContext()))
401 if (FriendTy->getNumParams() != ContextTy->getNumParams())
405 FriendTy->getReturnType()))
408 for (
unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
410 FriendTy->getParamType(I)))
420 Context->getTemplatedDecl(),
421 Friend->getTemplatedDecl());
425 const EffectiveContext &EC,
427 if (EC.includesClass(
Friend))
430 if (EC.isDependent()) {
441 const EffectiveContext &EC,
443 if (
const auto *RD =
Friend->getAsCXXRecordDecl())
447 if (
Friend->isDependentType())
456 const EffectiveContext &EC,
463 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
472 ->getSpecializedTemplate();
476 CTD =
Record->getDescribedClassTemplate();
485 if (!EC.isDependent())
496 Friend->getDeclContext()))
509 const EffectiveContext &EC,
514 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
528 const EffectiveContext &EC,
535 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
539 FTD = (*I)->getDescribedFunctionTemplate();
558 const EffectiveContext &EC,
566 return MatchesFriend(S, EC,
T->getType()->getCanonicalTypeUnqualified());
587 const EffectiveContext &EC,
592 for (
auto *
Friend : Class->friends()) {
614struct ProtectedFriendContext {
616 const EffectiveContext &EC;
617 const CXXRecordDecl *NamingClass;
622 SmallVector<const CXXRecordDecl*, 20> CurPath;
624 ProtectedFriendContext(Sema &S,
const EffectiveContext &EC,
625 const CXXRecordDecl *InstanceContext,
626 const CXXRecordDecl *NamingClass)
627 : S(S), EC(EC), NamingClass(NamingClass),
628 CheckDependent(InstanceContext->isDependentContext() ||
629 NamingClass->isDependentContext()),
630 EverDependent(
false) {}
634 bool checkFriendshipAlongPath(
unsigned I) {
635 assert(I < CurPath.size());
636 for (
unsigned E = CurPath.size(); I != E; ++I) {
651 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
655 if (Cur == NamingClass)
656 return checkFriendshipAlongPath(PrivateDepth);
659 EverDependent =
true;
662 for (
const auto &I : Cur->
bases()) {
665 unsigned BasePrivateDepth = PrivateDepth;
667 BasePrivateDepth = CurPath.size() - 1;
669 const CXXRecordDecl *RD;
671 QualType
T = I.getType();
676 EverDependent =
true;
681 CurPath.push_back(RD);
690 bool findFriendship(
const CXXRecordDecl *Cur) {
691 assert(CurPath.empty());
692 CurPath.push_back(Cur);
693 return findFriendship(Cur, 0);
727 assert(InstanceContext ==
nullptr ||
734 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
736 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
737 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
743 const EffectiveContext &EC,
746 const AccessTarget &
Target) {
748 "declaration should be canonicalized before being passed here");
755 for (EffectiveContext::record_iterator
756 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
763 if (ECRecord == NamingClass)
795 if (!
Target.hasInstanceContext()) {
806 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
807 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
832 assert(
Target.isInstanceMember());
835 if (!InstanceContext) {
861 if (
Target.hasInstanceContext()) {
862 InstanceContext =
Target.resolveInstanceContext(S);
871 llvm_unreachable(
"impossible friendship kind");
881 llvm_unreachable(
"impossible friendship kind");
941 const EffectiveContext &EC,
952 assert(isDerived &&
"derived class not actually derived from base");
957 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
959 bool AnyDependent =
false;
964 AccessTarget::SavedInstanceContext _ =
Target.saveInstanceContext();
968 CXXBasePath::iterator I = PI->end(), E = PI->begin();
985 PathAccess = std::max(PathAccess, BaseAccess);
994 Target.suppressInstanceContext();
1004 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
1006 BestPath->
Access = PathAccess;
1017 "fell out of loop with public path");
1035 if (!
Target.isInstanceMember())
1038 assert(
Target.isMemberAccess());
1042 for (EffectiveContext::record_iterator
1043 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1063 if (!
Target.hasInstanceContext()) {
1065 if (NamingClass == ECRecord)
continue;
1069 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1075 assert(InstanceContext &&
"diagnosing dependent access");
1092 diag::note_access_protected_restricted_ctordtor)
1098 diag::note_access_protected_restricted_object)
1108 const EffectiveContext &EC,
1109 AccessTarget &entity) {
1110 assert(entity.isMemberAccess());
1120 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1126 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1127 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD);
1132 if (!PrevDecl)
break;
1137 Decl *ImmediateChild;
1142 while (DC->
getParent() != DeclaringClass)
1149 bool isImplicit =
true;
1150 for (
const auto *I : DeclaringClass->
decls()) {
1151 if (I == ImmediateChild)
break;
1166 const EffectiveContext &EC,
1167 AccessTarget &entity) {
1169 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1178 if (entity.isMemberAccess()) {
1181 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1183 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1188 entity.suppressInstanceContext();
1193 declaringClass == entity.getEffectiveNamingClass())
1198 llvm_unreachable(
"cannot diagnose dependent access");
1206 CXXBasePath::iterator i = path.end(), e = path.begin();
1207 CXXBasePath::iterator constrainingBase = i;
1221 if (baseAccess > accessSoFar) {
1222 constrainingBase = i;
1223 accessSoFar = baseAccess;
1226 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1230 entity.suppressInstanceContext();
1231 constrainingBase =
nullptr;
1234 llvm_unreachable(
"cannot diagnose dependent access");
1241 assert(constrainingBase == i);
1248 if (constrainingBase == path.end())
1254 unsigned diagnostic;
1255 if (entity.isMemberAccess() ||
1256 constrainingBase + 1 != path.end()) {
1257 diagnostic = diag::note_access_constrained_by_path;
1259 diagnostic = diag::note_access_natural;
1269 if (entity.isMemberAccess())
1270 S.
Diag(entity.getTargetDecl()->getLocation(),
1271 diag::note_member_declared_at);
1275 const EffectiveContext &EC,
1276 AccessTarget &Entity) {
1278 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1279 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1281 S.
Diag(Loc, Entity.getDiag())
1311 AccessTarget &Entity) {
1313 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1314 if (
UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1315 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1316 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1319 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1320 << UD->getQualifiedNameAsString()
1331 const EffectiveContext &EC,
1332 AccessTarget &Entity) {
1334 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1337 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1343 if (UnprivilegedAccess !=
AS_none) {
1344 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1360 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1366 if (Entity.isMemberAccess()) {
1370 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1372 FinalAccess =
Target->getAccess();
1373 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1381 Entity.suppressInstanceContext();
1387 if (DeclaringClass == NamingClass)
1393 assert(Entity.getDeclaringClass() != NamingClass);
1401 assert(Path->
Access <= UnprivilegedAccess &&
1402 "access along best path worse than direct?");
1409 const EffectiveContext &EC,
1411 const AccessTarget &Entity) {
1412 assert(EC.isDependent() &&
"delaying non-dependent access");
1417 Entity.isMemberAccess(),
1419 Entity.getTargetDecl(),
1420 Entity.getNamingClass(),
1421 Entity.getBaseObjectType(),
1427 const EffectiveContext &EC,
1429 AccessTarget &Entity) {
1430 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1441 if (!Entity.isQuiet())
1450 llvm_unreachable(
"invalid access result");
1454 AccessTarget &Entity) {
1484 bool IsFriendDeclaration =
false;
1485 while (TS && !IsFriendDeclaration) {
1489 if (!IsFriendDeclaration) {
1501 llvm_unreachable(
"invalid access result");
1513 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1515 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1516 if (
auto *D = dyn_cast_if_present<DeclContext>(TD->getTemplatedDecl()))
1518 }
else if (
auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1522 EffectiveContext EC(DC);
1537 if (!NamingD)
return;
1540 if (!TargetD)
return;
1546 if (!BaseObjectType.
isNull()) {
1547 BaseObjectType =
SubstType(BaseObjectType, TemplateArgs, Loc,
1549 if (BaseObjectType.
isNull())
return;
1553 AccessTarget::Member,
1610 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
1614 Entity.setDiag(
Diag);
1620 llvm::scope_exit UndelayDiags(
1622 DelayedDiagnostics.popUndelayed(CurrentState);
1628 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1629 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1631 llvm_unreachable(
"bad access result");
1648 ObjectTy =
Context.getCanonicalTagType(NamingClass);
1650 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1653 Entity.setDiag(
PDiag);
1662 bool IsCopyBindingRefToTemp) {
1669 PD =
PDiag(IsCopyBindingRefToTemp
1670 ? diag::ext_rvalue_to_reference_access_ctor
1671 : diag::err_access_ctor);
1676 PD =
PDiag(diag::err_access_base_ctor);
1684 PD =
PDiag(diag::err_access_field_ctor);
1691 PD =
PDiag(diag::err_access_lambda_capture);
1724 }
else if (
auto *Shadow =
1725 dyn_cast<ConstructorUsingShadowDecl>(
Found.getDecl())) {
1730 ObjectClass = NamingClass;
1733 AccessTarget AccessEntity(
1734 Context, AccessTarget::Member, NamingClass,
1736 Context.getCanonicalTagType(ObjectClass));
1737 AccessEntity.setDiag(PD);
1752 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
1755 Entity.setDiag(diag::err_access)
1769 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1783 AccessTarget Entity(
Context, AccessTarget::Member, DecomposedClass, Field,
1784 Context.getCanonicalTagType(DecomposedClass));
1785 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1798 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
1800 Entity.setDiag(diag::err_access) << ObjectExpr->
getSourceRange() << Range;
1819 if (!ArgExprs.empty()) {
1821 ArgExprs.back()->getEndLoc());
1839 AccessTarget entity(
Context, AccessTarget::Member,
1843 entity.setDiag(diag::err_access_friend_function)
1855 llvm_unreachable(
"invalid access result");
1868 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
Found,
1870 Entity.setDiag(diag::err_access)
1880 bool ForceUnprivileged) {
1887 AccessTarget Entity(Context, AccessTarget::Base,
Base, Derived, Path.
Access);
1889 SetupPDiag(Entity.setDiag(DiagID));
1891 if (ForceUnprivileged) {
1894 case ::AR_accessible:
1896 case ::AR_inaccessible:
1898 case ::AR_dependent:
1901 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1909 unsigned DiagID,
bool ForceCheck,
1910 bool ForceUnprivileged) {
1914 ForceCheck, ForceUnprivileged);
1919 &&
"performing access check without access control");
1920 assert(R.getNamingClass() &&
"performing access check without naming class");
1925 R.getNamingClass(), I.getPair(),
1926 R.getBaseObjectType());
1927 Entity.setDiag(diag::err_access);
1936 if (
Target->isCXXClassMember() && NamingClass) {
1959 ClassOfMethodDecl = MD->getClassInterface();
1962 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1964 = dyn_cast<ObjCImplementationDecl>(Impl))
1965 ClassOfMethodDecl = IMPD->getClassInterface();
1967 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1968 ClassOfMethodDecl = CatImplClass->getClassInterface();
1973 if (!ClassOfMethodDecl)
1984 return Ivar->getContainingInterface()->
isSuperClassOf(ClassOfMethodDecl);
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::MachO::Target Target
llvm::MachO::Records Records
llvm::MachO::Record Record
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
AccessResult
A copy of Sema's enum without AR_delayed.
static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, AccessTarget &Target)
Given that an entity has protected natural access, check whether access might be denied because of th...
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)
Checks whether one class is derived from another, inclusively.
static void diagnoseBadDirectAccess(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
We are unable to access a given declaration due to its direct access control; diagnose that.
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class)
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
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...
static bool IsMicrosoftUsingDeclarationAccessBug(Sema &S, SourceLocation AccessLoc, AccessTarget &Entity)
MSVC has a bug where if during an using declaration name lookup, the declaration found is unaccessibl...
static CXXBasePath * FindBestPath(Sema &S, const EffectiveContext &EC, AccessTarget &Target, AccessSpecifier FinalAccess, CXXBasePaths &Paths)
Finds the best path from the naming class to the declaring class, taking friend declarations into acc...
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity)
Determines whether the accessed entity is accessible.
static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target)
static bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)
Checks whether one class might instantiate to the other.
static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
Diagnose the path which caused the given declaration or base class to become inaccessible.
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity)
Checks access to an entity from the given effective context.
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
std::list< CXXBasePath >::iterator paths_iterator
Represents a base class of a C++ class.
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool hasDefinition() const
bool isInjectedClassName() const
Determines whether this declaration represents the injected class name.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a canonical, potentially-qualified type.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
Declaration of a class template.
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isFileContext() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool isInvalidDecl() const
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
void setAccess(AccessSpecifier AS)
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
A dependently-generated diagnostic.
NamedDecl * getAccessNamingClass() const
QualType getAccessBaseObjectType() const
bool isAccessToMember() const
NamedDecl * getAccessTarget() const
SourceLocation getAccessLoc() const
const PartialDiagnostic & getDiagnostic() const
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
AccessSpecifier getAccess() const
This represents one expression.
Represents a member of a struct/union/class.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
bool isUnsupportedFriend() const
Determines if this friend kind is unsupported.
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Represents a function declaration or definition.
DeclarationNameInfo getNameInfo() const
Represents a prototype with parameter type info, e.g.
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Describes an entity that is being initialized.
EntityKind getKind() const
Determine the kind of initialization.
QualType getType() const
Retrieve type being initialized.
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
bool isInheritedVirtualBase() const
Return whether the base is an inherited virtual base.
@ EK_Member
The entity being initialized is a non-static data member subobject.
@ EK_Base
The entity being initialized is a base member subobject.
@ EK_ParenAggInitMember
The entity being initialized is a non-static data member subobject of an object initialized via paren...
@ EK_Delegating
The initialization is being done by a delegating constructor.
@ EK_LambdaCapture
The entity being initialized is the field that captures a variable in a lambda.
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
Represents the results of name lookup.
UnresolvedSetImpl::iterator iterator
Data structure that captures multiple levels of template argument lists for use in template instantia...
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getQualifiedNameAsString() const
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCMethodDecl - Represents an instance or class method declaration.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isFriendScope() const
Determine whether this scope is a friend scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
A class which encapsulates the logic for delaying diagnostics during parsing and other processing.
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
DelayedDiagnosticsState pushUndelayed()
Enter a new scope where access and deprecation diagnostics are not delayed.
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
CXXSpecialMemberKind getSpecialMember(const CXXMethodDecl *MD)
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)
Find the instantiation of the given declaration within the current instantiation.
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, SourceLocation Loc, const PartialDiagnostic &Diag)
Is the given member accessible for the purposes of deciding whether to define a special member functi...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)
Checks access to an overloaded operator new or delete.
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, const SourceRange &, DeclAccessPair FoundDecl)
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
const LangOptions & getLangOpts() const
AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)
Checks implicit access to a member in a structured binding.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
Perform access-control checking on a previously-unresolved member access which has now been resolved ...
bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, QualType BaseType)
Checks access to Target from the given class.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
void CheckLookupAccess(const LookupResult &R)
Checks access to all the declarations in the given result set.
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)
AccessResult CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)
Checks access to a member.
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Represents the declaration of a struct/union/class/enum.
The base class of all kinds of template declarations (e.g., class, function, etc.).
A container of type source information.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Base class for declarations which introduce a typedef-name.
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
QualType getBaseType() const
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
CXXRecordDecl * getNamingClass()
Retrieve the naming class of this lookup.
SourceLocation getMemberLoc() const
Retrieve the location of the name of the member that this expression refers to.
Represents a C++ using-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represents a variable declaration or definition.
A declaration being accessed, together with information about how it was accessed.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
AccessedEntity & getAccessData()
static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
OverloadExpr * Expression