25#include "llvm/ADT/STLForwardCompat.h"
43 if (!PrevMemberDecl) {
53 diag::err_class_redeclared_with_different_access)
54 << MemberDecl << LexicalAS;
55 Diag(PrevMemberDecl->
getLocation(), diag::note_previous_access_declaration)
56 << PrevMemberDecl << PrevMemberDecl->
getAccess();
71 if (isa<EnumDecl>(DC))
72 DC = cast<EnumDecl>(DC)->getDeclContext();
76 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->
getDeclContext());
77 return DeclaringClass;
81struct EffectiveContext {
82 EffectiveContext() : Inner(nullptr), Dependent(
false) {}
86 Dependent(DC->isDependentContext()) {
91 if (
auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
92 if (DGD->isImplicit()) {
93 DC = DGD->getCorrespondingConstructor();
97 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
121 if (isa<CXXRecordDecl>(DC)) {
124 DC =
Record->getDeclContext();
125 }
else if (isa<FunctionDecl>(DC)) {
127 Functions.push_back(
Function->getCanonicalDecl());
128 if (
Function->getFriendObjectKind())
129 DC =
Function->getLexicalDeclContext();
140 bool isDependent()
const {
return Dependent; }
144 return llvm::is_contained(
Records, R);
175 FoundDecl, BaseObjectType) {
189 bool isInstanceMember()
const {
190 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
193 bool hasInstanceContext()
const {
194 return HasInstanceContext;
197 class SavedInstanceContext {
199 SavedInstanceContext(SavedInstanceContext &&S)
206 SavedInstanceContext &operator=(SavedInstanceContext &&) =
delete;
210 SavedInstanceContext(
const SavedInstanceContext &) =
delete;
211 SavedInstanceContext &operator=(
const SavedInstanceContext &) =
delete;
213 ~SavedInstanceContext() {
215 Target->HasInstanceContext = Has;
219 friend struct AccessTarget;
220 explicit SavedInstanceContext(AccessTarget &
Target)
226 SavedInstanceContext saveInstanceContext() {
227 return SavedInstanceContext(*
this);
230 void suppressInstanceContext() {
231 HasInstanceContext =
false;
235 assert(HasInstanceContext);
236 if (CalculatedInstanceContext)
237 return InstanceContext;
239 CalculatedInstanceContext =
true;
241 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
243 return InstanceContext;
247 return DeclaringClass;
255 namingClass = cast<CXXRecordDecl>(namingClass->
getParent());
261 HasInstanceContext = (isMemberAccess() &&
262 !getBaseObjectType().isNull() &&
263 getTargetDecl()->isCXXInstanceMember());
264 CalculatedInstanceContext =
false;
265 InstanceContext =
nullptr;
267 if (isMemberAccess())
270 DeclaringClass = getBaseClass();
271 DeclaringClass = DeclaringClass->getCanonicalDecl();
274 bool HasInstanceContext : 1;
275 mutable bool CalculatedInstanceContext : 1;
291 if (FromDC == ToDC)
return true;
322 for (
const auto &I : Derived->
bases()) {
327 RD = cast<CXXRecordDecl>(RT->getDecl());
345 if (Queue.empty())
break;
347 Derived = Queue.pop_back_val();
356 if (Friend == Context)
360 "can't handle friends with dependent contexts here");
362 if (!Context->isDependentContext())
375 if (Friend == Context)
378 if (!Friend->isDependentType() && !Context->isDependentType())
388 if (Context->getDeclName() != Friend->
getDeclName())
392 Context->getDeclContext(),
401 ->getAs<FunctionProtoType>();
408 if (FriendTy->getNumParams() != ContextTy->getNumParams())
412 FriendTy->getReturnType()))
415 for (
unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
417 FriendTy->getParamType(I)))
427 Context->getTemplatedDecl(),
432 const EffectiveContext &EC,
434 if (EC.includesClass(Friend))
437 if (EC.isDependent()) {
448 const EffectiveContext &EC,
451 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
454 if (Friend->isDependentType())
463 const EffectiveContext &EC,
470 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
477 if (isa<ClassTemplateSpecializationDecl>(
Record)) {
478 CTD = cast<ClassTemplateSpecializationDecl>(
Record)
479 ->getSpecializedTemplate();
483 CTD =
Record->getDescribedClassTemplate();
492 if (!EC.isDependent())
516 const EffectiveContext &EC,
521 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
535 const EffectiveContext &EC,
542 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
546 FTD = (*I)->getDescribedFunctionTemplate();
565 const EffectiveContext &EC,
580 if (isa<ClassTemplateDecl>(Friend))
581 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
583 if (isa<FunctionTemplateDecl>(Friend))
584 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
586 if (isa<CXXRecordDecl>(Friend))
589 assert(isa<FunctionDecl>(Friend) &&
"unknown friend decl kind");
594 const EffectiveContext &EC,
599 for (
auto *Friend :
Class->friends()) {
621struct ProtectedFriendContext {
623 const EffectiveContext &EC;
631 ProtectedFriendContext(
Sema &S,
const EffectiveContext &EC,
634 : S(S), EC(EC), NamingClass(NamingClass),
635 CheckDependent(InstanceContext->isDependentContext() ||
636 NamingClass->isDependentContext()),
637 EverDependent(
false) {}
641 bool checkFriendshipAlongPath(
unsigned I) {
642 assert(I < CurPath.size());
643 for (
unsigned E = CurPath.size(); I != E; ++I) {
658 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
662 if (Cur == NamingClass)
663 return checkFriendshipAlongPath(PrivateDepth);
666 EverDependent =
true;
669 for (
const auto &I : Cur->
bases()) {
672 unsigned BasePrivateDepth = PrivateDepth;
674 BasePrivateDepth = CurPath.size() - 1;
680 RD = cast<CXXRecordDecl>(RT->getDecl());
686 EverDependent =
true;
691 CurPath.push_back(RD);
701 assert(CurPath.empty());
702 CurPath.push_back(Cur);
703 return findFriendship(Cur, 0);
737 assert(InstanceContext ==
nullptr ||
744 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
746 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
747 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
753 const EffectiveContext &EC,
756 const AccessTarget &
Target) {
758 "declaration should be canonicalized before being passed here");
765 for (EffectiveContext::record_iterator
766 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
773 if (ECRecord == NamingClass)
805 if (!
Target.hasInstanceContext()) {
816 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
817 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
842 assert(
Target.isInstanceMember());
845 if (!InstanceContext) {
871 if (
Target.hasInstanceContext()) {
872 InstanceContext =
Target.resolveInstanceContext(S);
881 llvm_unreachable(
"impossible friendship kind");
891 llvm_unreachable(
"impossible friendship kind");
951 const EffectiveContext &EC,
962 assert(isDerived &&
"derived class not actually derived from base");
967 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
969 bool AnyDependent =
false;
974 AccessTarget::SavedInstanceContext _ =
Target.saveInstanceContext();
978 CXXBasePath::iterator I = PI->end(), E = PI->begin();
995 PathAccess = std::max(PathAccess, BaseAccess);
1004 Target.suppressInstanceContext();
1007 AnyDependent =
true;
1014 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
1016 BestPath->
Access = PathAccess;
1027 "fell out of loop with public path");
1045 if (!
Target.isInstanceMember())
1048 assert(
Target.isMemberAccess());
1052 for (EffectiveContext::record_iterator
1053 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1073 if (!
Target.hasInstanceContext()) {
1075 if (NamingClass == ECRecord)
continue;
1079 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1085 assert(InstanceContext &&
"diagnosing dependent access");
1097 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1098 (isa<FunctionTemplateDecl>(D) &&
1099 isa<CXXConstructorDecl>(
1100 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1102 diag::note_access_protected_restricted_ctordtor)
1108 diag::note_access_protected_restricted_object)
1118 const EffectiveContext &EC,
1119 AccessTarget &entity) {
1120 assert(entity.isMemberAccess());
1130 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1136 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1137 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1141 if (!PrevDecl)
break;
1146 Decl *ImmediateChild;
1151 while (DC->
getParent() != DeclaringClass)
1153 ImmediateChild = cast<Decl>(DC);
1158 bool isImplicit =
true;
1159 for (
const auto *I : DeclaringClass->
decls()) {
1160 if (I == ImmediateChild)
break;
1161 if (isa<AccessSpecDecl>(I)) {
1175 const EffectiveContext &EC,
1176 AccessTarget &entity) {
1178 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1187 if (entity.isMemberAccess()) {
1190 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1192 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1197 entity.suppressInstanceContext();
1202 declaringClass == entity.getEffectiveNamingClass())
1207 llvm_unreachable(
"cannot diagnose dependent access");
1215 CXXBasePath::iterator i = path.end(), e = path.begin();
1216 CXXBasePath::iterator constrainingBase = i;
1230 if (baseAccess > accessSoFar) {
1231 constrainingBase = i;
1232 accessSoFar = baseAccess;
1235 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1239 entity.suppressInstanceContext();
1240 constrainingBase =
nullptr;
1243 llvm_unreachable(
"cannot diagnose dependent access");
1250 assert(constrainingBase == i);
1257 if (constrainingBase == path.end())
1263 unsigned diagnostic;
1264 if (entity.isMemberAccess() ||
1265 constrainingBase + 1 != path.end()) {
1266 diagnostic = diag::note_access_constrained_by_path;
1268 diagnostic = diag::note_access_natural;
1278 if (entity.isMemberAccess())
1279 S.
Diag(entity.getTargetDecl()->getLocation(),
1280 diag::note_member_declared_at);
1284 const EffectiveContext &EC,
1285 AccessTarget &Entity) {
1287 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1288 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1320 AccessTarget &Entity) {
1322 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1323 if (
UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1325 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1328 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1329 << UD->getQualifiedNameAsString()
1340 const EffectiveContext &EC,
1341 AccessTarget &Entity) {
1343 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1346 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1352 if (UnprivilegedAccess !=
AS_none) {
1353 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1369 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1375 if (Entity.isMemberAccess()) {
1379 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1382 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1390 Entity.suppressInstanceContext();
1396 if (DeclaringClass == NamingClass)
1402 assert(Entity.getDeclaringClass() != NamingClass);
1410 assert(Path->
Access <= UnprivilegedAccess &&
1411 "access along best path worse than direct?");
1418 const EffectiveContext &EC,
1420 const AccessTarget &Entity) {
1421 assert(EC.isDependent() &&
"delaying non-dependent access");
1426 Entity.isMemberAccess(),
1428 Entity.getTargetDecl(),
1429 Entity.getNamingClass(),
1430 Entity.getBaseObjectType(),
1436 const EffectiveContext &EC,
1438 AccessTarget &Entity) {
1439 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1450 if (!Entity.isQuiet())
1459 llvm_unreachable(
"invalid access result");
1463 AccessTarget &Entity) {
1493 bool IsFriendDeclaration =
false;
1494 while (TS && !IsFriendDeclaration) {
1498 if (!IsFriendDeclaration) {
1510 llvm_unreachable(
"invalid access result");
1522 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1524 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1525 if (isa<DeclContext>(TD->getTemplatedDecl()))
1526 DC = cast<DeclContext>(TD->getTemplatedDecl());
1527 }
else if (
auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1531 EffectiveContext EC(DC);
1546 if (!NamingD)
return;
1549 if (!TargetD)
return;
1553 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1555 if (!BaseObjectType.
isNull()) {
1556 BaseObjectType =
SubstType(BaseObjectType, TemplateArgs,
Loc,
1558 if (BaseObjectType.
isNull())
return;
1562 AccessTarget::Member,
1571 cast<CXXRecordDecl>(TargetD),
1572 cast<CXXRecordDecl>(NamingD),
1623 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1627 Entity.setDiag(
Diag);
1632 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1633 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1635 llvm_unreachable(
"bad access result");
1653 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1656 Entity.setDiag(
PDiag);
1666 bool IsCopyBindingRefToTemp) {
1673 PD =
PDiag(IsCopyBindingRefToTemp
1674 ? diag::ext_rvalue_to_reference_access_ctor
1675 : diag::err_access_ctor);
1680 PD =
PDiag(diag::err_access_base_ctor);
1689 PD =
PDiag(diag::err_access_field_ctor);
1690 PD << Field->getType()
1697 PD =
PDiag(diag::err_access_lambda_capture);
1698 PD << VarName << Entity.
getType()
1732 }
else if (
auto *Shadow =
1733 dyn_cast<ConstructorUsingShadowDecl>(Found.
getDecl())) {
1738 ObjectClass = NamingClass;
1741 AccessTarget AccessEntity(
1742 Context, AccessTarget::Member, NamingClass,
1745 AccessEntity.setDiag(PD);
1761 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1764 Entity.setDiag(diag::err_access)
1779 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1794 AccessTarget Entity(
Context, AccessTarget::Member, DecomposedClass, Field,
1796 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1811 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1834 if (!ArgExprs.empty()) {
1836 ArgExprs.back()->getEndLoc());
1855 AccessTarget entity(
Context, AccessTarget::Member,
1859 entity.setDiag(diag::err_access_friend_function)
1871 llvm_unreachable(
"invalid access result");
1884 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1886 Entity.setDiag(diag::err_access)
1904 bool ForceUnprivileged) {
1915 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1918 Entity.setDiag(DiagID) << Derived <<
Base;
1920 if (ForceUnprivileged) {
1922 AccessLoc, Entity)) {
1927 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1935 &&
"performing access check without access control");
1936 assert(R.
getNamingClass() &&
"performing access check without naming class");
1943 Entity.setDiag(diag::err_access);
1969 if (
Target->isCXXClassMember() && NamingClass) {
1992 ClassOfMethodDecl = MD->getClassInterface();
1995 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1997 = dyn_cast<ObjCImplementationDecl>(Impl))
1998 ClassOfMethodDecl = IMPD->getClassInterface();
2000 = dyn_cast<ObjCCategoryImplDecl>(Impl))
2001 ClassOfMethodDecl = CatImplClass->getClassInterface();
2006 if (!ClassOfMethodDecl)
2017 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.
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.
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRecordType(const RecordDecl *Decl) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
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.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool hasDefinition() const
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.
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 this template.
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
NamedDecl * getDecl() const
AccessSpecifier getAccess() const
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.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
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 this template.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
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.
The injected class name of a C++ class template or class template partial specialization.
Represents the results of name lookup.
SourceLocation getNameLoc() const
Gets the location of the identifier.
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
QualType getBaseObjectType() const
Returns the base object type associated with this lookup; important for [class.protected].
Data structure that captures multiple levels of template argument lists for use in template instantia...
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
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)
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
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.
CanQualType getCanonicalTypeUnqualified() 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...
const T * getAs() const
Member-template getAs<specific type>'.
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.
The iterator over UnresolvedSets.
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.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
OverloadExpr * Expression