42 if (!PrevMemberDecl) {
52 diag::err_class_redeclared_with_different_access)
53 << MemberDecl << LexicalAS;
54 Diag(PrevMemberDecl->
getLocation(), diag::note_previous_access_declaration)
55 << PrevMemberDecl << PrevMemberDecl->
getAccess();
70 if (isa<EnumDecl>(DC))
71 DC = cast<EnumDecl>(DC)->getDeclContext();
75 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->
getDeclContext());
76 return DeclaringClass;
80struct EffectiveContext {
81 EffectiveContext() : Inner(nullptr), Dependent(
false) {}
85 Dependent(DC->isDependentContext()) {
90 if (
auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
91 if (DGD->isImplicit()) {
92 DC = DGD->getCorrespondingConstructor();
96 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
120 if (isa<CXXRecordDecl>(DC)) {
122 Records.push_back(
Record->getCanonicalDecl());
123 DC =
Record->getDeclContext();
124 }
else if (isa<FunctionDecl>(DC)) {
126 Functions.push_back(
Function->getCanonicalDecl());
127 if (
Function->getFriendObjectKind())
128 DC =
Function->getLexicalDeclContext();
139 bool isDependent()
const {
return Dependent; }
143 return llvm::is_contained(Records, R);
174 FoundDecl, BaseObjectType) {
188 bool isInstanceMember()
const {
189 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
192 bool hasInstanceContext()
const {
193 return HasInstanceContext;
196 class SavedInstanceContext {
198 SavedInstanceContext(SavedInstanceContext &&S)
202 ~SavedInstanceContext() {
204 Target->HasInstanceContext = Has;
208 friend struct AccessTarget;
209 explicit SavedInstanceContext(AccessTarget &Target)
215 SavedInstanceContext saveInstanceContext() {
216 return SavedInstanceContext(*
this);
219 void suppressInstanceContext() {
220 HasInstanceContext =
false;
224 assert(HasInstanceContext);
225 if (CalculatedInstanceContext)
226 return InstanceContext;
228 CalculatedInstanceContext =
true;
230 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
232 return InstanceContext;
236 return DeclaringClass;
244 namingClass = cast<CXXRecordDecl>(namingClass->
getParent());
250 HasInstanceContext = (isMemberAccess() &&
251 !getBaseObjectType().isNull() &&
252 getTargetDecl()->isCXXInstanceMember());
253 CalculatedInstanceContext =
false;
254 InstanceContext =
nullptr;
256 if (isMemberAccess())
259 DeclaringClass = getBaseClass();
260 DeclaringClass = DeclaringClass->getCanonicalDecl();
263 bool HasInstanceContext : 1;
264 mutable bool CalculatedInstanceContext : 1;
280 if (FromDC == ToDC)
return true;
311 for (
const auto &I : Derived->
bases()) {
316 RD = cast<CXXRecordDecl>(RT->getDecl());
334 if (Queue.empty())
break;
336 Derived = Queue.pop_back_val();
345 if (Friend == Context)
349 "can't handle friends with dependent contexts here");
351 if (!Context->isDependentContext())
364 if (Friend == Context)
367 if (!Friend->isDependentType() && !Context->isDependentType())
377 if (Context->getDeclName() != Friend->
getDeclName())
381 Context->getDeclContext(),
390 ->getAs<FunctionProtoType>();
397 if (FriendTy->getNumParams() != ContextTy->getNumParams())
401 FriendTy->getReturnType()))
404 for (
unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
406 FriendTy->getParamType(I)))
416 Context->getTemplatedDecl(),
421 const EffectiveContext &EC,
423 if (EC.includesClass(Friend))
426 if (EC.isDependent()) {
437 const EffectiveContext &EC,
440 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
443 if (Friend->isDependentType())
452 const EffectiveContext &EC,
459 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
466 if (isa<ClassTemplateSpecializationDecl>(Record)) {
467 CTD = cast<ClassTemplateSpecializationDecl>(Record)
468 ->getSpecializedTemplate();
472 CTD = Record->getDescribedClassTemplate();
481 if (!EC.isDependent())
505 const EffectiveContext &EC,
510 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
524 const EffectiveContext &EC,
531 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
535 FTD = (*I)->getDescribedFunctionTemplate();
554 const EffectiveContext &EC,
562 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
569 if (isa<ClassTemplateDecl>(Friend))
570 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
572 if (isa<FunctionTemplateDecl>(Friend))
573 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
575 if (isa<CXXRecordDecl>(Friend))
578 assert(isa<FunctionDecl>(Friend) &&
"unknown friend decl kind");
583 const EffectiveContext &EC,
588 for (
auto *Friend : Class->friends()) {
610struct ProtectedFriendContext {
612 const EffectiveContext &EC;
620 ProtectedFriendContext(
Sema &S,
const EffectiveContext &EC,
623 : S(S), EC(EC), NamingClass(NamingClass),
624 CheckDependent(InstanceContext->isDependentContext() ||
625 NamingClass->isDependentContext()),
626 EverDependent(
false) {}
630 bool checkFriendshipAlongPath(
unsigned I) {
631 assert(I < CurPath.size());
632 for (
unsigned E = CurPath.size(); I != E; ++I) {
647 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
651 if (Cur == NamingClass)
652 return checkFriendshipAlongPath(PrivateDepth);
655 EverDependent =
true;
658 for (
const auto &I : Cur->
bases()) {
661 unsigned BasePrivateDepth = PrivateDepth;
663 BasePrivateDepth = CurPath.size() - 1;
669 RD = cast<CXXRecordDecl>(RT->getDecl());
675 EverDependent =
true;
680 CurPath.push_back(RD);
690 assert(CurPath.empty());
691 CurPath.push_back(Cur);
692 return findFriendship(Cur, 0);
726 assert(InstanceContext ==
nullptr ||
733 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
735 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
736 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
742 const EffectiveContext &EC,
745 const AccessTarget &
Target) {
747 "declaration should be canonicalized before being passed here");
754 for (EffectiveContext::record_iterator
755 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
762 if (ECRecord == NamingClass)
794 if (!
Target.hasInstanceContext()) {
805 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
806 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
831 assert(
Target.isInstanceMember());
834 if (!InstanceContext) {
860 if (
Target.hasInstanceContext()) {
861 InstanceContext =
Target.resolveInstanceContext(S);
870 llvm_unreachable(
"impossible friendship kind");
880 llvm_unreachable(
"impossible friendship kind");
940 const EffectiveContext &EC,
951 assert(isDerived &&
"derived class not actually derived from base");
956 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
958 bool AnyDependent =
false;
963 AccessTarget::SavedInstanceContext _ =
Target.saveInstanceContext();
967 CXXBasePath::iterator I = PI->end(), E = PI->begin();
984 PathAccess = std::max(PathAccess, BaseAccess);
993 Target.suppressInstanceContext();
1003 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
1005 BestPath->
Access = PathAccess;
1016 "fell out of loop with public path");
1034 if (!
Target.isInstanceMember())
1037 assert(
Target.isMemberAccess());
1041 for (EffectiveContext::record_iterator
1042 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1062 if (!
Target.hasInstanceContext()) {
1064 if (NamingClass == ECRecord)
continue;
1068 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1074 assert(InstanceContext &&
"diagnosing dependent access");
1086 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1087 (isa<FunctionTemplateDecl>(D) &&
1088 isa<CXXConstructorDecl>(
1089 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1091 diag::note_access_protected_restricted_ctordtor)
1097 diag::note_access_protected_restricted_object)
1107 const EffectiveContext &EC,
1108 AccessTarget &entity) {
1109 assert(entity.isMemberAccess());
1119 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1125 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1126 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1130 if (!PrevDecl)
break;
1135 Decl *ImmediateChild;
1140 while (DC->
getParent() != DeclaringClass)
1142 ImmediateChild = cast<Decl>(DC);
1147 bool isImplicit =
true;
1148 for (
const auto *I : DeclaringClass->
decls()) {
1149 if (I == ImmediateChild)
break;
1150 if (isa<AccessSpecDecl>(I)) {
1164 const EffectiveContext &EC,
1165 AccessTarget &entity) {
1167 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1176 if (entity.isMemberAccess()) {
1179 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1181 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1186 entity.suppressInstanceContext();
1191 declaringClass == entity.getEffectiveNamingClass())
1196 llvm_unreachable(
"cannot diagnose dependent access");
1204 CXXBasePath::iterator i = path.end(), e = path.begin();
1205 CXXBasePath::iterator constrainingBase = i;
1219 if (baseAccess > accessSoFar) {
1220 constrainingBase = i;
1221 accessSoFar = baseAccess;
1224 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1228 entity.suppressInstanceContext();
1229 constrainingBase =
nullptr;
1232 llvm_unreachable(
"cannot diagnose dependent access");
1239 assert(constrainingBase == i);
1246 if (constrainingBase == path.end())
1252 unsigned diagnostic;
1253 if (entity.isMemberAccess() ||
1254 constrainingBase + 1 != path.end()) {
1255 diagnostic = diag::note_access_constrained_by_path;
1257 diagnostic = diag::note_access_natural;
1267 if (entity.isMemberAccess())
1268 S.
Diag(entity.getTargetDecl()->getLocation(),
1269 diag::note_member_declared_at);
1273 const EffectiveContext &EC,
1274 AccessTarget &Entity) {
1276 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1277 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1279 S.
Diag(Loc, Entity.getDiag())
1309 AccessTarget &Entity) {
1311 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1312 if (
UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1314 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1317 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1318 << UD->getQualifiedNameAsString()
1329 const EffectiveContext &EC,
1330 AccessTarget &Entity) {
1332 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1335 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1341 if (UnprivilegedAccess !=
AS_none) {
1342 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1358 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1364 if (Entity.isMemberAccess()) {
1368 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1370 FinalAccess =
Target->getAccess();
1371 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1379 Entity.suppressInstanceContext();
1385 if (DeclaringClass == NamingClass)
1391 assert(Entity.getDeclaringClass() != NamingClass);
1399 assert(Path->
Access <= UnprivilegedAccess &&
1400 "access along best path worse than direct?");
1407 const EffectiveContext &EC,
1409 const AccessTarget &Entity) {
1410 assert(EC.isDependent() &&
"delaying non-dependent access");
1415 Entity.isMemberAccess(),
1417 Entity.getTargetDecl(),
1418 Entity.getNamingClass(),
1419 Entity.getBaseObjectType(),
1425 const EffectiveContext &EC,
1427 AccessTarget &Entity) {
1428 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1439 if (!Entity.isQuiet())
1448 llvm_unreachable(
"invalid access result");
1452 AccessTarget &Entity) {
1479 llvm_unreachable(
"invalid access result");
1491 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1493 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1494 if (isa<DeclContext>(TD->getTemplatedDecl()))
1495 DC = cast<DeclContext>(TD->getTemplatedDecl());
1496 }
else if (
auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1500 EffectiveContext EC(DC);
1515 if (!NamingD)
return;
1518 if (!TargetD)
return;
1522 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1524 if (!BaseObjectType.
isNull()) {
1525 BaseObjectType =
SubstType(BaseObjectType, TemplateArgs, Loc,
1527 if (BaseObjectType.
isNull())
return;
1531 AccessTarget::Member,
1540 cast<CXXRecordDecl>(TargetD),
1541 cast<CXXRecordDecl>(NamingD),
1592 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1596 Entity.setDiag(
Diag);
1601 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1602 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1604 llvm_unreachable(
"bad access result");
1622 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1625 Entity.setDiag(
PDiag);
1635 bool IsCopyBindingRefToTemp) {
1642 PD =
PDiag(IsCopyBindingRefToTemp
1643 ? diag::ext_rvalue_to_reference_access_ctor
1644 : diag::err_access_ctor);
1649 PD =
PDiag(diag::err_access_base_ctor);
1656 PD =
PDiag(diag::err_access_field_ctor);
1663 PD =
PDiag(diag::err_access_lambda_capture);
1697 }
else if (
auto *Shadow =
1698 dyn_cast<ConstructorUsingShadowDecl>(Found.
getDecl())) {
1703 ObjectClass = NamingClass;
1706 AccessTarget AccessEntity(
1707 Context, AccessTarget::Member, NamingClass,
1710 AccessEntity.setDiag(PD);
1726 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1729 Entity.setDiag(diag::err_access)
1744 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1759 AccessTarget Entity(
Context, AccessTarget::Member, DecomposedClass, Field,
1761 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1776 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1778 Entity.setDiag(diag::err_access) << ObjectExpr->
getSourceRange() << Range;
1799 if (!ArgExprs.empty()) {
1801 ArgExprs.back()->getEndLoc());
1820 AccessTarget entity(
Context, AccessTarget::Member,
1824 entity.setDiag(diag::err_access_friend_function)
1836 llvm_unreachable(
"invalid access result");
1849 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1851 Entity.setDiag(diag::err_access)
1869 bool ForceUnprivileged) {
1880 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1883 Entity.setDiag(DiagID) << Derived <<
Base;
1885 if (ForceUnprivileged) {
1887 AccessLoc, Entity)) {
1892 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1900 &&
"performing access check without access control");
1901 assert(R.
getNamingClass() &&
"performing access check without naming class");
1908 Entity.setDiag(diag::err_access);
1934 if (
Target->isCXXClassMember() && NamingClass) {
1957 ClassOfMethodDecl = MD->getClassInterface();
1960 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1962 = dyn_cast<ObjCImplementationDecl>(Impl))
1963 ClassOfMethodDecl = IMPD->getClassInterface();
1965 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1966 ClassOfMethodDecl = CatImplClass->getClassInterface();
1971 if (!ClassOfMethodDecl)
1982 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.
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_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
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.
CXXSpecialMember 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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
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.
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)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
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