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);
1290 S.
Diag(Loc, Entity.getDiag())
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) {
1490 llvm_unreachable(
"invalid access result");
1502 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1504 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1505 if (isa<DeclContext>(TD->getTemplatedDecl()))
1506 DC = cast<DeclContext>(TD->getTemplatedDecl());
1507 }
else if (
auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1511 EffectiveContext EC(DC);
1526 if (!NamingD)
return;
1529 if (!TargetD)
return;
1533 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1535 if (!BaseObjectType.
isNull()) {
1536 BaseObjectType =
SubstType(BaseObjectType, TemplateArgs, Loc,
1538 if (BaseObjectType.
isNull())
return;
1542 AccessTarget::Member,
1551 cast<CXXRecordDecl>(TargetD),
1552 cast<CXXRecordDecl>(NamingD),
1603 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1607 Entity.setDiag(
Diag);
1612 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1613 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1615 llvm_unreachable(
"bad access result");
1633 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1636 Entity.setDiag(
PDiag);
1646 bool IsCopyBindingRefToTemp) {
1653 PD =
PDiag(IsCopyBindingRefToTemp
1654 ? diag::ext_rvalue_to_reference_access_ctor
1655 : diag::err_access_ctor);
1660 PD =
PDiag(diag::err_access_base_ctor);
1669 PD =
PDiag(diag::err_access_field_ctor);
1670 PD << Field->getType()
1677 PD =
PDiag(diag::err_access_lambda_capture);
1678 PD << VarName << Entity.
getType()
1712 }
else if (
auto *Shadow =
1713 dyn_cast<ConstructorUsingShadowDecl>(Found.
getDecl())) {
1718 ObjectClass = NamingClass;
1721 AccessTarget AccessEntity(
1722 Context, AccessTarget::Member, NamingClass,
1725 AccessEntity.setDiag(PD);
1741 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1744 Entity.setDiag(diag::err_access)
1759 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1774 AccessTarget Entity(
Context, AccessTarget::Member, DecomposedClass, Field,
1776 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1791 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1793 Entity.setDiag(diag::err_access) << ObjectExpr->
getSourceRange() << Range;
1814 if (!ArgExprs.empty()) {
1816 ArgExprs.back()->getEndLoc());
1835 AccessTarget entity(
Context, AccessTarget::Member,
1839 entity.setDiag(diag::err_access_friend_function)
1851 llvm_unreachable(
"invalid access result");
1864 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1866 Entity.setDiag(diag::err_access)
1884 bool ForceUnprivileged) {
1895 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1898 Entity.setDiag(DiagID) << Derived <<
Base;
1900 if (ForceUnprivileged) {
1902 AccessLoc, Entity)) {
1907 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1915 &&
"performing access check without access control");
1916 assert(R.
getNamingClass() &&
"performing access check without naming class");
1923 Entity.setDiag(diag::err_access);
1949 if (
Target->isCXXClassMember() && NamingClass) {
1972 ClassOfMethodDecl = MD->getClassInterface();
1975 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1977 = dyn_cast<ObjCImplementationDecl>(Impl))
1978 ClassOfMethodDecl = IMPD->getClassInterface();
1980 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1981 ClassOfMethodDecl = CatImplClass->getClassInterface();
1986 if (!ClassOfMethodDecl)
1997 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
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.
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