llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Vlad Serebrennikov (Endilll) <details> <summary>Changes</summary> This patch moves `Sema` functions that handle access checking into the new `SemaAccess` class. This continues previous efforts to split Sema up. Additional context can be found in https://github.com/llvm/llvm-project/pull/84184. As usual, formatting changes are split into a separate commit. --- Patch is 82.52 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92674.diff 20 Files Affected: - (modified) clang/include/clang/Sema/Lookup.h (+2-1) - (modified) clang/include/clang/Sema/Sema.h (+38-119) - (added) clang/include/clang/Sema/SemaAccess.h (+112) - (modified) clang/lib/Sema/Sema.cpp (+2) - (modified) clang/lib/Sema/SemaAccess.cpp (+160-148) - (modified) clang/lib/Sema/SemaCast.cpp (+15-16) - (modified) clang/lib/Sema/SemaCodeComplete.cpp (+4-2) - (modified) clang/lib/Sema/SemaDecl.cpp (+2-1) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+2-1) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+28-26) - (modified) clang/lib/Sema/SemaDeclObjC.cpp (+2-1) - (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+13-10) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+26-19) - (modified) clang/lib/Sema/SemaExprMember.cpp (+1) - (modified) clang/lib/Sema/SemaInit.cpp (+20-15) - (modified) clang/lib/Sema/SemaLookup.cpp (+5-4) - (modified) clang/lib/Sema/SemaOpenMP.cpp (+5-4) - (modified) clang/lib/Sema/SemaOverload.cpp (+23-16) - (modified) clang/lib/Sema/SemaTemplate.cpp (+2-1) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+4-3) ``````````diff diff --git a/clang/include/clang/Sema/Lookup.h b/clang/include/clang/Sema/Lookup.h index b0a08a05ac6a0..1d2a7de941698 100644 --- a/clang/include/clang/Sema/Lookup.h +++ b/clang/include/clang/Sema/Lookup.h @@ -25,6 +25,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaAccess.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Casting.h" @@ -761,7 +762,7 @@ class LookupResult { void diagnoseAccess() { if (!isAmbiguous() && isClassLookup() && getSema().getLangOpts().AccessControl) - getSema().CheckLookupAccess(*this); + getSema().Access().CheckLookupAccess(*this); } void diagnoseAmbiguous() { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d4d4a82525a02..4b0cac3b15331 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -167,6 +167,7 @@ class Preprocessor; class PseudoDestructorTypeStorage; class PseudoObjectExpr; class QualType; +class SemaAccess; class SemaCodeCompletion; class SemaCUDA; class SemaHLSL; @@ -451,39 +452,38 @@ class Sema final : public SemaBase { // Table of Contents // ----------------- // 1. Semantic Analysis (Sema.cpp) - // 2. C++ Access Control (SemaAccess.cpp) - // 3. Attributes (SemaAttr.cpp) - // 4. Availability Attribute Handling (SemaAvailability.cpp) - // 5. Casts (SemaCast.cpp) - // 6. Extra Semantic Checking (SemaChecking.cpp) - // 7. C++ Coroutines (SemaCoroutine.cpp) - // 8. C++ Scope Specifiers (SemaCXXScopeSpec.cpp) - // 9. Declarations (SemaDecl.cpp) - // 10. Declaration Attribute Handling (SemaDeclAttr.cpp) - // 11. C++ Declarations (SemaDeclCXX.cpp) - // 12. C++ Exception Specifications (SemaExceptionSpec.cpp) - // 13. Expressions (SemaExpr.cpp) - // 14. C++ Expressions (SemaExprCXX.cpp) - // 15. Member Access Expressions (SemaExprMember.cpp) - // 16. Initializers (SemaInit.cpp) - // 17. C++ Lambda Expressions (SemaLambda.cpp) - // 18. Name Lookup (SemaLookup.cpp) - // 19. Modules (SemaModule.cpp) - // 20. C++ Overloading (SemaOverload.cpp) - // 21. Pseudo-Object (SemaPseudoObject.cpp) - // 22. Statements (SemaStmt.cpp) - // 23. `inline asm` Statement (SemaStmtAsm.cpp) - // 24. Statement Attribute Handling (SemaStmtAttr.cpp) - // 25. C++ Templates (SemaTemplate.cpp) - // 26. C++ Template Argument Deduction (SemaTemplateDeduction.cpp) - // 27. C++ Template Instantiation (SemaTemplateInstantiate.cpp) - // 28. C++ Template Declaration Instantiation + // 2. Attributes (SemaAttr.cpp) + // 3. Availability Attribute Handling (SemaAvailability.cpp) + // 4. Casts (SemaCast.cpp) + // 5. Extra Semantic Checking (SemaChecking.cpp) + // 6. C++ Coroutines (SemaCoroutine.cpp) + // 7. C++ Scope Specifiers (SemaCXXScopeSpec.cpp) + // 8. Declarations (SemaDecl.cpp) + // 9. Declaration Attribute Handling (SemaDeclAttr.cpp) + // 10. C++ Declarations (SemaDeclCXX.cpp) + // 11. C++ Exception Specifications (SemaExceptionSpec.cpp) + // 12. Expressions (SemaExpr.cpp) + // 13. C++ Expressions (SemaExprCXX.cpp) + // 14. Member Access Expressions (SemaExprMember.cpp) + // 15. Initializers (SemaInit.cpp) + // 16. C++ Lambda Expressions (SemaLambda.cpp) + // 17. Name Lookup (SemaLookup.cpp) + // 18. Modules (SemaModule.cpp) + // 19. C++ Overloading (SemaOverload.cpp) + // 20. Pseudo-Object (SemaPseudoObject.cpp) + // 21. Statements (SemaStmt.cpp) + // 22. `inline asm` Statement (SemaStmtAsm.cpp) + // 23. Statement Attribute Handling (SemaStmtAttr.cpp) + // 24. C++ Templates (SemaTemplate.cpp) + // 25. C++ Template Argument Deduction (SemaTemplateDeduction.cpp) + // 26. C++ Template Instantiation (SemaTemplateInstantiate.cpp) + // 27. C++ Template Declaration Instantiation // (SemaTemplateInstantiateDecl.cpp) - // 29. C++ Variadic Templates (SemaTemplateVariadic.cpp) - // 30. Constraints and Concepts (SemaConcept.cpp) - // 31. Types (SemaType.cpp) - // 32. FixIt Helpers (SemaFixItUtils.cpp) - // 33. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) + // 28. C++ Variadic Templates (SemaTemplateVariadic.cpp) + // 29. Constraints and Concepts (SemaConcept.cpp) + // 30. Types (SemaType.cpp) + // 31. FixIt Helpers (SemaFixItUtils.cpp) + // 32. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) /// \name Semantic Analysis /// Implementations are in Sema.cpp @@ -984,6 +984,11 @@ class Sema final : public SemaBase { /// CurContext - This is the current declaration context of parsing. DeclContext *CurContext; + SemaAccess &Access() { + assert(AccessPtr); + return *AccessPtr; + } + SemaCodeCompletion &CodeCompletion() { assert(CodeCompletionPtr); return *CodeCompletionPtr; @@ -1049,6 +1054,7 @@ class Sema final : public SemaBase { mutable IdentifierInfo *Ident_super; + std::unique_ptr<SemaAccess> AccessPtr; std::unique_ptr<SemaCodeCompletion> CodeCompletionPtr; std::unique_ptr<SemaCUDA> CUDAPtr; std::unique_ptr<SemaHLSL> HLSLPtr; @@ -1065,93 +1071,6 @@ class Sema final : public SemaBase { // // - /// \name C++ Access Control - /// Implementations are in SemaAccess.cpp - ///@{ - -public: - enum AccessResult { - AR_accessible, - AR_inaccessible, - AR_dependent, - AR_delayed - }; - - bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, - NamedDecl *PrevMemberDecl, - AccessSpecifier LexicalAS); - - AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, - DeclAccessPair FoundDecl); - AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, - DeclAccessPair FoundDecl); - AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, - SourceRange PlacementRange, - CXXRecordDecl *NamingClass, - DeclAccessPair FoundDecl, - bool Diagnose = true); - AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, - DeclAccessPair FoundDecl, - const InitializedEntity &Entity, - bool IsCopyBindingRefToTemp = false); - AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, - DeclAccessPair FoundDecl, - const InitializedEntity &Entity, - const PartialDiagnostic &PDiag); - AccessResult CheckDestructorAccess(SourceLocation Loc, - CXXDestructorDecl *Dtor, - const PartialDiagnostic &PDiag, - QualType objectType = QualType()); - AccessResult CheckFriendAccess(NamedDecl *D); - AccessResult CheckMemberAccess(SourceLocation UseLoc, - CXXRecordDecl *NamingClass, - DeclAccessPair Found); - AccessResult - CheckStructuredBindingMemberAccess(SourceLocation UseLoc, - CXXRecordDecl *DecomposedClass, - DeclAccessPair Field); - AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, - const SourceRange &, - DeclAccessPair FoundDecl); - AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, - Expr *ArgExpr, - DeclAccessPair FoundDecl); - AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, - ArrayRef<Expr *> ArgExprs, - DeclAccessPair FoundDecl); - AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, - DeclAccessPair FoundDecl); - AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, - QualType Derived, const CXXBasePath &Path, - unsigned DiagID, bool ForceCheck = false, - bool ForceUnprivileged = false); - void CheckLookupAccess(const LookupResult &R); - bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, - QualType BaseType); - bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, - DeclAccessPair Found, QualType ObjectType, - SourceLocation Loc, - const PartialDiagnostic &Diag); - bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, - DeclAccessPair Found, - QualType ObjectType) { - return isMemberAccessibleForDeletion(NamingClass, Found, ObjectType, - SourceLocation(), PDiag()); - } - - void HandleDependentAccessCheck( - const DependentDiagnostic &DD, - const MultiLevelTemplateArgumentList &TemplateArgs); - void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); - - ///@} - - // - // - // ------------------------------------------------------------------------- - // - // - /// \name Attributes /// Implementations are in SemaAttr.cpp ///@{ diff --git a/clang/include/clang/Sema/SemaAccess.h b/clang/include/clang/Sema/SemaAccess.h new file mode 100644 index 0000000000000..dd89f042ccb89 --- /dev/null +++ b/clang/include/clang/Sema/SemaAccess.h @@ -0,0 +1,112 @@ +//===----- SemaAccess.h --------- C++ Access Control ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares routines for C++ access control semantics. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAACCESS_H +#define LLVM_CLANG_SEMA_SEMAACCESS_H + +#include "clang/AST/CXXInheritance.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DependentDiagnostic.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/Type.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Sema/DelayedDiagnostic.h" +#include "clang/Sema/Initialization.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class LookupResult; +class MultiLevelTemplateArgumentList; + +class SemaAccess : public SemaBase { +public: + SemaAccess(Sema &S); + + enum AccessResult { + AR_accessible, + AR_inaccessible, + AR_dependent, + AR_delayed + }; + + bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, + NamedDecl *PrevMemberDecl, + AccessSpecifier LexicalAS); + + AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, + DeclAccessPair FoundDecl); + AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, + DeclAccessPair FoundDecl); + AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, + SourceRange PlacementRange, + CXXRecordDecl *NamingClass, + DeclAccessPair FoundDecl, + bool Diagnose = true); + AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, + DeclAccessPair FoundDecl, + const InitializedEntity &Entity, + bool IsCopyBindingRefToTemp = false); + AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, + DeclAccessPair FoundDecl, + const InitializedEntity &Entity, + const PartialDiagnostic &PDiag); + AccessResult CheckDestructorAccess(SourceLocation Loc, + CXXDestructorDecl *Dtor, + const PartialDiagnostic &PDiag, + QualType objectType = QualType()); + AccessResult CheckFriendAccess(NamedDecl *D); + AccessResult CheckMemberAccess(SourceLocation UseLoc, + CXXRecordDecl *NamingClass, + DeclAccessPair Found); + AccessResult + CheckStructuredBindingMemberAccess(SourceLocation UseLoc, + CXXRecordDecl *DecomposedClass, + DeclAccessPair Field); + AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, + const SourceRange &, + DeclAccessPair FoundDecl); + AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, + Expr *ArgExpr, + DeclAccessPair FoundDecl); + AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, + ArrayRef<Expr *> ArgExprs, + DeclAccessPair FoundDecl); + AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, + DeclAccessPair FoundDecl); + AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, + QualType Derived, const CXXBasePath &Path, + unsigned DiagID, bool ForceCheck = false, + bool ForceUnprivileged = false); + void CheckLookupAccess(const LookupResult &R); + bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, + QualType BaseType); + bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, + DeclAccessPair Found, QualType ObjectType, + SourceLocation Loc, + const PartialDiagnostic &Diag); + bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, + DeclAccessPair Found, QualType ObjectType); + + void HandleDependentAccessCheck( + const DependentDiagnostic &DD, + const MultiLevelTemplateArgumentList &TemplateArgs); + void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAACCESS_H \ No newline at end of file diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index f847c49920cf3..0940885f12d19 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -41,6 +41,7 @@ #include "clang/Sema/RISCVIntrinsicManager.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaAccess.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaCodeCompletion.h" #include "clang/Sema/SemaConsumer.h" @@ -203,6 +204,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr), CurScope(nullptr), Ident_super(nullptr), + AccessPtr(std::make_unique<SemaAccess>(*this)), CodeCompletionPtr( std::make_unique<SemaCodeCompletion>(*this, CodeCompleter)), CUDAPtr(std::make_unique<SemaCUDA>(*this)), diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 979a64b065f3d..9272020d83d33 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Sema/SemaAccess.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" @@ -37,9 +38,9 @@ enum AccessResult { /// SetMemberAccessSpecifier - Set the access specifier of a member. /// Returns true on error (when the previous member decl access specifier /// is different from the new member decl access specifier). -bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, - NamedDecl *PrevMemberDecl, - AccessSpecifier LexicalAS) { +bool SemaAccess::SetMemberAccessSpecifier(NamedDecl *MemberDecl, + NamedDecl *PrevMemberDecl, + AccessSpecifier LexicalAS) { if (!PrevMemberDecl) { // Use the lexical access specifier. MemberDecl->setAccess(LexicalAS); @@ -1459,11 +1460,11 @@ static AccessResult CheckEffectiveAccess(Sema &S, llvm_unreachable("invalid access result"); } -static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, - AccessTarget &Entity) { +static SemaAccess::AccessResult CheckAccess(Sema &S, SourceLocation Loc, + AccessTarget &Entity) { // If the access path is public, it's accessible everywhere. if (Entity.getAccess() == AS_public) - return Sema::AR_accessible; + return SemaAccess::AR_accessible; // If we're currently parsing a declaration, we may need to delay // access control checking, because our effective context might be @@ -1497,20 +1498,23 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, } if (!IsFriendDeclaration) { S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity)); - return Sema::AR_delayed; + return SemaAccess::AR_delayed; } } EffectiveContext EC(S.CurContext); switch (CheckEffectiveAccess(S, EC, Loc, Entity)) { - case AR_accessible: return Sema::AR_accessible; - case AR_inaccessible: return Sema::AR_inaccessible; - case AR_dependent: return Sema::AR_dependent; + case AR_accessible: + return SemaAccess::AR_accessible; + case AR_inaccessible: + return SemaAccess::AR_inaccessible; + case AR_dependent: + return SemaAccess::AR_dependent; } llvm_unreachable("invalid access result"); } -void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) { +void SemaAccess::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) { // Access control for names used in the declarations of functions // and function templates should normally be evaluated in the context // of the declaration, just in case it's a friend of something. @@ -1532,20 +1536,21 @@ void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) { AccessTarget Target(DD.getAccessData()); - if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible) + if (CheckEffectiveAccess(SemaRef, EC, DD.Loc, Target) == ::AR_inaccessible) DD.Triggered = true; } -void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD, - const MultiLevelTemplateArgumentList &TemplateArgs) { +void SemaAccess::HandleDependentAccessCheck( + const DependentDiagnostic &DD, + const MultiLevelTemplateArgumentList &TemplateArgs) { SourceLocation Loc = DD.getAccessLoc(); AccessSpecifier Access = DD.getAccess(); - Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(), - TemplateArgs); + Decl *NamingD = SemaRef.FindInstantiatedDecl(Loc, DD.getAccessNamingClass(), + TemplateArgs); if (!NamingD) return; - Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(), - ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/92674 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits