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)
205 SavedInstanceContext &operator=(SavedInstanceContext &&) =
delete;
209 SavedInstanceContext(
const SavedInstanceContext &) =
delete;
210 SavedInstanceContext &operator=(
const SavedInstanceContext &) =
delete;
212 ~SavedInstanceContext() {
214 Target->HasInstanceContext = Has;
218 friend struct AccessTarget;
219 explicit SavedInstanceContext(AccessTarget &Target)
225 SavedInstanceContext saveInstanceContext() {
226 return SavedInstanceContext(*
this);
229 void suppressInstanceContext() {
230 HasInstanceContext =
false;
234 assert(HasInstanceContext);
235 if (CalculatedInstanceContext)
236 return InstanceContext;
238 CalculatedInstanceContext =
true;
240 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
242 return InstanceContext;
246 return DeclaringClass;
254 namingClass = cast<CXXRecordDecl>(namingClass->
getParent());
260 HasInstanceContext = (isMemberAccess() &&
261 !getBaseObjectType().isNull() &&
262 getTargetDecl()->isCXXInstanceMember());
263 CalculatedInstanceContext =
false;
264 InstanceContext =
nullptr;
266 if (isMemberAccess())
269 DeclaringClass = getBaseClass();
270 DeclaringClass = DeclaringClass->getCanonicalDecl();
273 bool HasInstanceContext : 1;
274 mutable bool CalculatedInstanceContext : 1;
290 if (FromDC == ToDC)
return true;
321 for (
const auto &I : Derived->
bases()) {
326 RD = cast<CXXRecordDecl>(RT->getDecl());
344 if (Queue.empty())
break;
346 Derived = Queue.pop_back_val();
355 if (Friend == Context)
359 "can't handle friends with dependent contexts here");
361 if (!Context->isDependentContext())
374 if (Friend == Context)
377 if (!Friend->isDependentType() && !Context->isDependentType())
387 if (Context->getDeclName() != Friend->
getDeclName())
391 Context->getDeclContext(),
400 ->getAs<FunctionProtoType>();
407 if (FriendTy->getNumParams() != ContextTy->getNumParams())
411 FriendTy->getReturnType()))
414 for (
unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
416 FriendTy->getParamType(I)))
426 Context->getTemplatedDecl(),
431 const EffectiveContext &EC,
433 if (EC.includesClass(Friend))
436 if (EC.isDependent()) {
447 const EffectiveContext &EC,
450 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
453 if (Friend->isDependentType())
462 const EffectiveContext &EC,
469 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
476 if (isa<ClassTemplateSpecializationDecl>(Record)) {
477 CTD = cast<ClassTemplateSpecializationDecl>(Record)
478 ->getSpecializedTemplate();
482 CTD = Record->getDescribedClassTemplate();
491 if (!EC.isDependent())
515 const EffectiveContext &EC,
520 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
534 const EffectiveContext &EC,
541 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
545 FTD = (*I)->getDescribedFunctionTemplate();
564 const EffectiveContext &EC,
572 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
579 if (isa<ClassTemplateDecl>(Friend))
580 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
582 if (isa<FunctionTemplateDecl>(Friend))
583 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
585 if (isa<CXXRecordDecl>(Friend))
588 assert(isa<FunctionDecl>(Friend) &&
"unknown friend decl kind");
593 const EffectiveContext &EC,
598 for (
auto *Friend : Class->friends()) {
620struct ProtectedFriendContext {
622 const EffectiveContext &EC;
630 ProtectedFriendContext(
Sema &S,
const EffectiveContext &EC,
633 : S(S), EC(EC), NamingClass(NamingClass),
634 CheckDependent(InstanceContext->isDependentContext() ||
635 NamingClass->isDependentContext()),
636 EverDependent(
false) {}
640 bool checkFriendshipAlongPath(
unsigned I) {
641 assert(I < CurPath.size());
642 for (
unsigned E = CurPath.size(); I != E; ++I) {
657 bool findFriendship(
const CXXRecordDecl *Cur,
unsigned PrivateDepth) {
661 if (Cur == NamingClass)
662 return checkFriendshipAlongPath(PrivateDepth);
665 EverDependent =
true;
668 for (
const auto &I : Cur->
bases()) {
671 unsigned BasePrivateDepth = PrivateDepth;
673 BasePrivateDepth = CurPath.size() - 1;
679 RD = cast<CXXRecordDecl>(RT->getDecl());
685 EverDependent =
true;
690 CurPath.push_back(RD);
700 assert(CurPath.empty());
701 CurPath.push_back(Cur);
702 return findFriendship(Cur, 0);
736 assert(InstanceContext ==
nullptr ||
743 if (!InstanceContext)
return GetFriendKind(S, EC, NamingClass);
745 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
746 if (PRC.findFriendship(InstanceContext))
return AR_accessible;
752 const EffectiveContext &EC,
755 const AccessTarget &
Target) {
757 "declaration should be canonicalized before being passed here");
764 for (EffectiveContext::record_iterator
765 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
772 if (ECRecord == NamingClass)
804 if (!
Target.hasInstanceContext()) {
815 if (S.
getLangOpts().MSVCCompat && !EC.Functions.empty())
816 if (
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
841 assert(
Target.isInstanceMember());
844 if (!InstanceContext) {
870 if (
Target.hasInstanceContext()) {
871 InstanceContext =
Target.resolveInstanceContext(S);
880 llvm_unreachable(
"impossible friendship kind");
890 llvm_unreachable(
"impossible friendship kind");
950 const EffectiveContext &EC,
961 assert(isDerived &&
"derived class not actually derived from base");
966 assert(FinalAccess !=
AS_none &&
"forbidden access after declaring class");
968 bool AnyDependent =
false;
973 AccessTarget::SavedInstanceContext _ =
Target.saveInstanceContext();
977 CXXBasePath::iterator I = PI->end(), E = PI->begin();
994 PathAccess = std::max(PathAccess, BaseAccess);
1003 Target.suppressInstanceContext();
1006 AnyDependent =
true;
1013 if (BestPath ==
nullptr || PathAccess < BestPath->Access) {
1015 BestPath->
Access = PathAccess;
1026 "fell out of loop with public path");
1044 if (!
Target.isInstanceMember())
1047 assert(
Target.isMemberAccess());
1051 for (EffectiveContext::record_iterator
1052 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1072 if (!
Target.hasInstanceContext()) {
1074 if (NamingClass == ECRecord)
continue;
1078 S.
Diag(D->
getLocation(), diag::note_access_protected_restricted_noobject)
1084 assert(InstanceContext &&
"diagnosing dependent access");
1096 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1097 (isa<FunctionTemplateDecl>(D) &&
1098 isa<CXXConstructorDecl>(
1099 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1101 diag::note_access_protected_restricted_ctordtor)
1107 diag::note_access_protected_restricted_object)
1117 const EffectiveContext &EC,
1118 AccessTarget &entity) {
1119 assert(entity.isMemberAccess());
1129 if (
VarDecl *VD = dyn_cast<VarDecl>(D))
1135 else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
1136 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1140 if (!PrevDecl)
break;
1145 Decl *ImmediateChild;
1150 while (DC->
getParent() != DeclaringClass)
1152 ImmediateChild = cast<Decl>(DC);
1157 bool isImplicit =
true;
1158 for (
const auto *I : DeclaringClass->
decls()) {
1159 if (I == ImmediateChild)
break;
1160 if (isa<AccessSpecDecl>(I)) {
1174 const EffectiveContext &EC,
1175 AccessTarget &entity) {
1177 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1186 if (entity.isMemberAccess()) {
1189 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1191 switch (
HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1196 entity.suppressInstanceContext();
1201 declaringClass == entity.getEffectiveNamingClass())
1206 llvm_unreachable(
"cannot diagnose dependent access");
1214 CXXBasePath::iterator i = path.end(), e = path.begin();
1215 CXXBasePath::iterator constrainingBase = i;
1229 if (baseAccess > accessSoFar) {
1230 constrainingBase = i;
1231 accessSoFar = baseAccess;
1234 switch (
HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1238 entity.suppressInstanceContext();
1239 constrainingBase =
nullptr;
1242 llvm_unreachable(
"cannot diagnose dependent access");
1249 assert(constrainingBase == i);
1256 if (constrainingBase == path.end())
1262 unsigned diagnostic;
1263 if (entity.isMemberAccess() ||
1264 constrainingBase + 1 != path.end()) {
1265 diagnostic = diag::note_access_constrained_by_path;
1267 diagnostic = diag::note_access_natural;
1277 if (entity.isMemberAccess())
1278 S.
Diag(entity.getTargetDecl()->getLocation(),
1279 diag::note_member_declared_at);
1283 const EffectiveContext &EC,
1284 AccessTarget &Entity) {
1286 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1287 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() :
nullptr);
1289 S.
Diag(Loc, Entity.getDiag())
1319 AccessTarget &Entity) {
1321 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1322 if (
UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1324 if (Entity.getTargetDecl()->getAccess() ==
AS_private &&
1327 S.
Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1328 << UD->getQualifiedNameAsString()
1339 const EffectiveContext &EC,
1340 AccessTarget &Entity) {
1342 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1345 assert(UnprivilegedAccess !=
AS_public &&
"public access not weeded out");
1351 if (UnprivilegedAccess !=
AS_none) {
1352 switch (
HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1368 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1374 if (Entity.isMemberAccess()) {
1378 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1380 FinalAccess =
Target->getAccess();
1381 switch (
HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1389 Entity.suppressInstanceContext();
1395 if (DeclaringClass == NamingClass)
1401 assert(Entity.getDeclaringClass() != NamingClass);
1409 assert(Path->
Access <= UnprivilegedAccess &&
1410 "access along best path worse than direct?");
1417 const EffectiveContext &EC,
1419 const AccessTarget &Entity) {
1420 assert(EC.isDependent() &&
"delaying non-dependent access");
1425 Entity.isMemberAccess(),
1427 Entity.getTargetDecl(),
1428 Entity.getNamingClass(),
1429 Entity.getBaseObjectType(),
1435 const EffectiveContext &EC,
1437 AccessTarget &Entity) {
1438 assert(Entity.getAccess() !=
AS_public &&
"called for public access!");
1449 if (!Entity.isQuiet())
1458 llvm_unreachable(
"invalid access result");
1462 AccessTarget &Entity) {
1489 llvm_unreachable(
"invalid access result");
1501 }
else if (
FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1503 }
else if (
TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1504 if (isa<DeclContext>(TD->getTemplatedDecl()))
1505 DC = cast<DeclContext>(TD->getTemplatedDecl());
1506 }
else if (
auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1510 EffectiveContext EC(DC);
1525 if (!NamingD)
return;
1528 if (!TargetD)
return;
1532 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1534 if (!BaseObjectType.
isNull()) {
1535 BaseObjectType =
SubstType(BaseObjectType, TemplateArgs, Loc,
1537 if (BaseObjectType.
isNull())
return;
1541 AccessTarget::Member,
1550 cast<CXXRecordDecl>(TargetD),
1551 cast<CXXRecordDecl>(NamingD),
1602 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1606 Entity.setDiag(
Diag);
1611 case AR_dependent: llvm_unreachable(
"dependent for =delete computation");
1612 case AR_delayed: llvm_unreachable(
"cannot delay =delete computation");
1614 llvm_unreachable(
"bad access result");
1632 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1635 Entity.setDiag(
PDiag);
1645 bool IsCopyBindingRefToTemp) {
1652 PD =
PDiag(IsCopyBindingRefToTemp
1653 ? diag::ext_rvalue_to_reference_access_ctor
1654 : diag::err_access_ctor);
1659 PD =
PDiag(diag::err_access_base_ctor);
1667 PD =
PDiag(diag::err_access_field_ctor);
1674 PD =
PDiag(diag::err_access_lambda_capture);
1708 }
else if (
auto *Shadow =
1709 dyn_cast<ConstructorUsingShadowDecl>(Found.
getDecl())) {
1714 ObjectClass = NamingClass;
1717 AccessTarget AccessEntity(
1718 Context, AccessTarget::Member, NamingClass,
1721 AccessEntity.setDiag(PD);
1737 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1740 Entity.setDiag(diag::err_access)
1755 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass,
1770 AccessTarget Entity(
Context, AccessTarget::Member, DecomposedClass, Field,
1772 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1787 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1789 Entity.setDiag(diag::err_access) << ObjectExpr->
getSourceRange() << Range;
1810 if (!ArgExprs.empty()) {
1812 ArgExprs.back()->getEndLoc());
1831 AccessTarget entity(
Context, AccessTarget::Member,
1835 entity.setDiag(diag::err_access_friend_function)
1847 llvm_unreachable(
"invalid access result");
1860 AccessTarget Entity(
Context, AccessTarget::Member, NamingClass, Found,
1862 Entity.setDiag(diag::err_access)
1880 bool ForceUnprivileged) {
1891 AccessTarget Entity(
Context, AccessTarget::Base, BaseD, DerivedD,
1894 Entity.setDiag(DiagID) << Derived <<
Base;
1896 if (ForceUnprivileged) {
1898 AccessLoc, Entity)) {
1903 llvm_unreachable(
"unexpected result from CheckEffectiveAccess");
1911 &&
"performing access check without access control");
1912 assert(R.
getNamingClass() &&
"performing access check without naming class");
1919 Entity.setDiag(diag::err_access);
1945 if (
Target->isCXXClassMember() && NamingClass) {
1968 ClassOfMethodDecl = MD->getClassInterface();
1971 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1973 = dyn_cast<ObjCImplementationDecl>(Impl))
1974 ClassOfMethodDecl = IMPD->getClassInterface();
1976 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1977 ClassOfMethodDecl = CatImplClass->getClassInterface();
1982 if (!ClassOfMethodDecl)
1993 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_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
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