[clang] [clang] Introduce `SemaAccess` (PR #92674)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Sat May 18 14:56:01 PDT 2024


https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/92674

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.

>From 6c333167c186d95fdf4ff698288f1026da7b1fa3 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 00:50:32 +0300
Subject: [PATCH 1/3] [clang] Introduce `SemaAccess`

---
 clang/include/clang/Sema/Lookup.h             |   3 +-
 clang/include/clang/Sema/Sema.h               |  94 +--------
 clang/include/clang/Sema/SemaAccess.h         | 113 +++++++++++
 clang/lib/Sema/Sema.cpp                       |   2 +
 clang/lib/Sema/SemaAccess.cpp                 | 182 +++++++++---------
 clang/lib/Sema/SemaCast.cpp                   |  21 +-
 clang/lib/Sema/SemaCodeComplete.cpp           |   5 +-
 clang/lib/Sema/SemaDecl.cpp                   |   3 +-
 clang/lib/Sema/SemaDeclAttr.cpp               |   3 +-
 clang/lib/Sema/SemaDeclCXX.cpp                |  31 +--
 clang/lib/Sema/SemaDeclObjC.cpp               |   3 +-
 clang/lib/Sema/SemaExceptionSpec.cpp          |  11 +-
 clang/lib/Sema/SemaExprCXX.cpp                |  23 +--
 clang/lib/Sema/SemaExprMember.cpp             |   1 +
 clang/lib/Sema/SemaInit.cpp                   |  17 +-
 clang/lib/Sema/SemaLookup.cpp                 |   5 +-
 clang/lib/Sema/SemaOpenMP.cpp                 |   9 +-
 clang/lib/Sema/SemaOverload.cpp               |  27 +--
 clang/lib/Sema/SemaTemplate.cpp               |   3 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 20 files changed, 312 insertions(+), 251 deletions(-)
 create mode 100644 clang/include/clang/Sema/SemaAccess.h

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..0bbc20d1766e5 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;
@@ -984,6 +985,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 +1055,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 +1072,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..280c41aa33124
--- /dev/null
+++ b/clang/include/clang/Sema/SemaAccess.h
@@ -0,0 +1,113 @@
+//===----- 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..1e9958d845ba7 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,7 +38,7 @@ 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,
+bool SemaAccess::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
                                     NamedDecl *PrevMemberDecl,
                                     AccessSpecifier LexicalAS) {
   if (!PrevMemberDecl) {
@@ -1459,11 +1460,11 @@ static AccessResult CheckEffectiveAccess(Sema &S,
   llvm_unreachable("invalid access result");
 }
 
-static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
+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,20 @@ 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,19 +1533,19 @@ 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,
+void SemaAccess::HandleDependentAccessCheck(const DependentDiagnostic &DD,
                         const MultiLevelTemplateArgumentList &TemplateArgs) {
   SourceLocation Loc = DD.getAccessLoc();
   AccessSpecifier Access = DD.getAccess();
 
-  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
+  Decl *NamingD = SemaRef.FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
                                        TemplateArgs);
   if (!NamingD) return;
-  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
+  Decl *TargetD = SemaRef.FindInstantiatedDecl(Loc, DD.getAccessTarget(),
                                        TemplateArgs);
   if (!TargetD) return;
 
@@ -1553,46 +1554,46 @@ void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
     NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
     QualType BaseObjectType = DD.getAccessBaseObjectType();
     if (!BaseObjectType.isNull()) {
-      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
+      BaseObjectType = SemaRef.SubstType(BaseObjectType, TemplateArgs, Loc,
                                  DeclarationName());
       if (BaseObjectType.isNull()) return;
     }
 
-    AccessTarget Entity(Context,
+    AccessTarget Entity(SemaRef.Context,
                         AccessTarget::Member,
                         NamingClass,
                         DeclAccessPair::make(TargetDecl, Access),
                         BaseObjectType);
     Entity.setDiag(DD.getDiagnostic());
-    CheckAccess(*this, Loc, Entity);
+    CheckAccess(SemaRef, Loc, Entity);
   } else {
-    AccessTarget Entity(Context,
+    AccessTarget Entity(SemaRef.Context,
                         AccessTarget::Base,
                         cast<CXXRecordDecl>(TargetD),
                         cast<CXXRecordDecl>(NamingD),
                         Access);
     Entity.setDiag(DD.getDiagnostic());
-    CheckAccess(*this, Loc, Entity);
+    CheckAccess(SemaRef, Loc, Entity);
   }
 }
 
-Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
+SemaAccess::AccessResult SemaAccess::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
                                                      DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       !E->getNamingClass() ||
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, E->getNamingClass(),
                       Found, QualType());
   Entity.setDiag(diag::err_access) << E->getSourceRange();
 
-  return CheckAccess(*this, E->getNameLoc(), Entity);
+  return CheckAccess(SemaRef, E->getNameLoc(), Entity);
 }
 
 /// Perform access-control checking on a previously-unresolved member
 /// access which has now been resolved to a member.
-Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
+SemaAccess::AccessResult SemaAccess::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
                                                      DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       Found.getAccess() == AS_public)
@@ -1602,16 +1603,16 @@ Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
   if (E->isArrow())
     BaseType = BaseType->castAs<PointerType>()->getPointeeType();
 
-  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, E->getNamingClass(),
                       Found, BaseType);
   Entity.setDiag(diag::err_access) << E->getSourceRange();
 
-  return CheckAccess(*this, E->getMemberLoc(), Entity);
+  return CheckAccess(SemaRef, E->getMemberLoc(), Entity);
 }
 
 /// Is the given member accessible for the purposes of deciding whether to
 /// define a special member function as deleted?
-bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
+bool SemaAccess::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
                                          DeclAccessPair Found,
                                          QualType ObjectType,
                                          SourceLocation Loc,
@@ -1620,13 +1621,13 @@ bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
   if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
     return true;
 
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass, Found,
                       ObjectType);
 
   // Suppress diagnostics.
   Entity.setDiag(Diag);
 
-  switch (CheckAccess(*this, Loc, Entity)) {
+  switch (CheckAccess(SemaRef, Loc, Entity)) {
   case AR_accessible: return true;
   case AR_inaccessible: return false;
   case AR_dependent: llvm_unreachable("dependent for =delete computation");
@@ -1635,7 +1636,7 @@ bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
   llvm_unreachable("bad access result");
 }
 
-Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
+SemaAccess::AccessResult SemaAccess::CheckDestructorAccess(SourceLocation Loc,
                                                CXXDestructorDecl *Dtor,
                                                const PartialDiagnostic &PDiag,
                                                QualType ObjectTy) {
@@ -1648,18 +1649,18 @@ Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
     return AR_accessible;
 
   CXXRecordDecl *NamingClass = Dtor->getParent();
-  if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
+  if (ObjectTy.isNull()) ObjectTy = SemaRef.Context.getTypeDeclType(NamingClass);
 
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass,
                       DeclAccessPair::make(Dtor, Access),
                       ObjectTy);
   Entity.setDiag(PDiag); // TODO: avoid copy
 
-  return CheckAccess(*this, Loc, Entity);
+  return CheckAccess(SemaRef, Loc, Entity);
 }
 
 /// Checks access to a constructor.
-Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
+SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLoc,
                                                 CXXConstructorDecl *Constructor,
                                                 DeclAccessPair Found,
                                                 const InitializedEntity &Entity,
@@ -1667,36 +1668,36 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
   if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
     return AR_accessible;
 
-  PartialDiagnostic PD(PDiag());
+  PartialDiagnostic PD(SemaRef.PDiag());
   switch (Entity.getKind()) {
   default:
-    PD = PDiag(IsCopyBindingRefToTemp
+    PD = SemaRef.PDiag(IsCopyBindingRefToTemp
                  ? diag::ext_rvalue_to_reference_access_ctor
                  : diag::err_access_ctor);
 
     break;
 
   case InitializedEntity::EK_Base:
-    PD = PDiag(diag::err_access_base_ctor);
+    PD = SemaRef.PDiag(diag::err_access_base_ctor);
     PD << Entity.isInheritedVirtualBase()
        << Entity.getBaseSpecifier()->getType()
-       << llvm::to_underlying(getSpecialMember(Constructor));
+       << llvm::to_underlying(SemaRef.getSpecialMember(Constructor));
     break;
 
   case InitializedEntity::EK_Member:
   case InitializedEntity::EK_ParenAggInitMember: {
     const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
-    PD = PDiag(diag::err_access_field_ctor);
+    PD = SemaRef.PDiag(diag::err_access_field_ctor);
     PD << Field->getType()
-       << llvm::to_underlying(getSpecialMember(Constructor));
+       << llvm::to_underlying(SemaRef.getSpecialMember(Constructor));
     break;
   }
 
   case InitializedEntity::EK_LambdaCapture: {
     StringRef VarName = Entity.getCapturedVarName();
-    PD = PDiag(diag::err_access_lambda_capture);
+    PD = SemaRef.PDiag(diag::err_access_lambda_capture);
     PD << VarName << Entity.getType()
-       << llvm::to_underlying(getSpecialMember(Constructor));
+       << llvm::to_underlying(SemaRef.getSpecialMember(Constructor));
     break;
   }
 
@@ -1706,7 +1707,7 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
 }
 
 /// Checks access to a constructor.
-Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
+SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLoc,
                                                 CXXConstructorDecl *Constructor,
                                                 DeclAccessPair Found,
                                                 const InitializedEntity &Entity,
@@ -1728,7 +1729,7 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
   if ((Entity.getKind() == InitializedEntity::EK_Base ||
        Entity.getKind() == InitializedEntity::EK_Delegating) &&
       !Entity.getParent()) {
-    ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
+    ObjectClass = cast<CXXConstructorDecl>(SemaRef.CurContext)->getParent();
   } else if (auto *Shadow =
                  dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
     // If we're using an inheriting constructor to construct an object,
@@ -1739,16 +1740,16 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
   }
 
   AccessTarget AccessEntity(
-      Context, AccessTarget::Member, NamingClass,
+      SemaRef.Context, AccessTarget::Member, NamingClass,
       DeclAccessPair::make(Constructor, Found.getAccess()),
-      Context.getTypeDeclType(ObjectClass));
+      SemaRef.Context.getTypeDeclType(ObjectClass));
   AccessEntity.setDiag(PD);
 
-  return CheckAccess(*this, UseLoc, AccessEntity);
+  return CheckAccess(SemaRef, UseLoc, AccessEntity);
 }
 
 /// Checks access to an overloaded operator new or delete.
-Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
+SemaAccess::AccessResult SemaAccess::CheckAllocationAccess(SourceLocation OpLoc,
                                                SourceRange PlacementRange,
                                                CXXRecordDecl *NamingClass,
                                                DeclAccessPair Found,
@@ -1758,17 +1759,17 @@ Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass, Found,
                       QualType());
   if (Diagnose)
     Entity.setDiag(diag::err_access)
       << PlacementRange;
 
-  return CheckAccess(*this, OpLoc, Entity);
+  return CheckAccess(SemaRef, OpLoc, Entity);
 }
 
 /// Checks access to a member.
-Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
+SemaAccess::AccessResult SemaAccess::CheckMemberAccess(SourceLocation UseLoc,
                                            CXXRecordDecl *NamingClass,
                                            DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
@@ -1776,29 +1777,29 @@ Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass,
                       Found, QualType());
 
-  return CheckAccess(*this, UseLoc, Entity);
+  return CheckAccess(SemaRef, UseLoc, Entity);
 }
 
 /// Checks implicit access to a member in a structured binding.
-Sema::AccessResult
-Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
+SemaAccess::AccessResult
+SemaAccess::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
                                          CXXRecordDecl *DecomposedClass,
                                          DeclAccessPair Field) {
   if (!getLangOpts().AccessControl ||
       Field.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
-                      Context.getRecordType(DecomposedClass));
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, DecomposedClass, Field,
+                      SemaRef.Context.getRecordType(DecomposedClass));
   Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
 
-  return CheckAccess(*this, UseLoc, Entity);
+  return CheckAccess(SemaRef, UseLoc, Entity);
 }
 
-Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
+SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc,
                                                    Expr *ObjectExpr,
                                                    const SourceRange &Range,
                                                    DeclAccessPair Found) {
@@ -1808,16 +1809,16 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
   const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
   CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
 
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass, Found,
                       ObjectExpr->getType());
   Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
 
-  return CheckAccess(*this, OpLoc, Entity);
+  return CheckAccess(SemaRef, OpLoc, Entity);
 }
 
 /// Checks access to an overloaded member operator, including
 /// conversion operators.
-Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
+SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc,
                                                    Expr *ObjectExpr,
                                                    Expr *ArgExpr,
                                                    DeclAccessPair Found) {
@@ -1826,7 +1827,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
       Found);
 }
 
-Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
+SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc,
                                                    Expr *ObjectExpr,
                                                    ArrayRef<Expr *> ArgExprs,
                                                    DeclAccessPair FoundDecl) {
@@ -1840,7 +1841,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
 }
 
 /// Checks access to the target of a friend declaration.
-Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
+SemaAccess::AccessResult SemaAccess::CheckFriendAccess(NamedDecl *target) {
   assert(isa<CXXMethodDecl>(target->getAsFunction()));
 
   // Friendship lookup is a redeclaration lookup, so there's never an
@@ -1852,7 +1853,7 @@ Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
 
   CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
 
-  AccessTarget entity(Context, AccessTarget::Member,
+  AccessTarget entity(SemaRef.Context, AccessTarget::Member,
                       cast<CXXRecordDecl>(target->getDeclContext()),
                       DeclAccessPair::make(target, access),
                       /*no instance context*/ QualType());
@@ -1862,16 +1863,16 @@ Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
 
   // We need to bypass delayed-diagnostics because we might be called
   // while the ParsingDeclarator is active.
-  EffectiveContext EC(CurContext);
-  switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
-  case ::AR_accessible: return Sema::AR_accessible;
-  case ::AR_inaccessible: return Sema::AR_inaccessible;
-  case ::AR_dependent: return Sema::AR_dependent;
+  EffectiveContext EC(SemaRef.CurContext);
+  switch (CheckEffectiveAccess(SemaRef, EC, target->getLocation(), entity)) {
+  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");
 }
 
-Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
+SemaAccess::AccessResult SemaAccess::CheckAddressOfMemberAccess(Expr *OvlExpr,
                                                     DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       Found.getAccess() == AS_none ||
@@ -1881,12 +1882,12 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
   OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
   CXXRecordDecl *NamingClass = Ovl->getNamingClass();
 
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass, Found,
                       /*no instance context*/ QualType());
   Entity.setDiag(diag::err_access)
     << Ovl->getSourceRange();
 
-  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
+  return CheckAccess(SemaRef, Ovl->getNameLoc(), Entity);
 }
 
 /// Checks access for a hierarchy conversion.
@@ -1895,7 +1896,7 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
 ///     control is disabled;  some things rely on this for semantics
 /// \param ForceUnprivileged true if this check should proceed as if the
 ///     context had no special privileges
-Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
+SemaAccess::AccessResult SemaAccess::CheckBaseClassAccess(SourceLocation AccessLoc,
                                               QualType Base,
                                               QualType Derived,
                                               const CXXBasePath &Path,
@@ -1912,36 +1913,36 @@ Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
   BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
   DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
 
-  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Base, BaseD, DerivedD,
                       Path.Access);
   if (DiagID)
     Entity.setDiag(DiagID) << Derived << Base;
 
   if (ForceUnprivileged) {
-    switch (CheckEffectiveAccess(*this, EffectiveContext(),
+    switch (CheckEffectiveAccess(SemaRef, EffectiveContext(),
                                  AccessLoc, 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("unexpected result from CheckEffectiveAccess");
   }
-  return CheckAccess(*this, AccessLoc, Entity);
+  return CheckAccess(SemaRef, AccessLoc, Entity);
 }
 
 /// Checks access to all the declarations in the given result set.
-void Sema::CheckLookupAccess(const LookupResult &R) {
+void SemaAccess::CheckLookupAccess(const LookupResult &R) {
   assert(getLangOpts().AccessControl
          && "performing access check without access control");
   assert(R.getNamingClass() && "performing access check without naming class");
 
   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
     if (I.getAccess() != AS_public) {
-      AccessTarget Entity(Context, AccessedEntity::Member,
+      AccessTarget Entity(SemaRef.Context, AccessedEntity::Member,
                           R.getNamingClass(), I.getPair(),
                           R.getBaseObjectType());
       Entity.setDiag(diag::err_access);
-      CheckAccess(*this, R.getNameLoc(), Entity);
+      CheckAccess(SemaRef, R.getNameLoc(), Entity);
     }
   }
 }
@@ -1963,7 +1964,7 @@ void Sema::CheckLookupAccess(const LookupResult &R) {
 ///        - target (unqualified lookup).
 ///          BaseType is null, NamingClass is the parent class of 'target'.
 /// \return true if the Target is accessible from the Class, false otherwise.
-bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
+bool SemaAccess::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
                               QualType BaseType) {
   // Perform the C++ accessibility checks first.
   if (Target->isCXXClassMember() && NamingClass) {
@@ -1973,10 +1974,10 @@ bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
     // accessed, which is described by the access in DeclAccessPair.
     // `IsAccessible` will examine the actual access of Target (i.e.
     // Decl->getAccess()) when calculating the access.
-    AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
+    AccessTarget Entity(SemaRef.Context, AccessedEntity::Member, NamingClass,
                         DeclAccessPair::make(Target, AS_none), BaseType);
-    EffectiveContext EC(CurContext);
-    return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
+    EffectiveContext EC(SemaRef.CurContext);
+    return ::IsAccessible(SemaRef, EC, Entity) != ::AR_inaccessible;
   }
 
   if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
@@ -1988,9 +1989,9 @@ bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
     // If we are inside a class or category implementation, determine the
     // interface we're in.
     ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
-    if (ObjCMethodDecl *MD = getCurMethodDecl())
+    if (ObjCMethodDecl *MD = SemaRef.getCurMethodDecl())
       ClassOfMethodDecl =  MD->getClassInterface();
-    else if (FunctionDecl *FD = getCurFunctionDecl()) {
+    else if (FunctionDecl *FD = SemaRef.getCurFunctionDecl()) {
       if (ObjCImplDecl *Impl
             = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
         if (ObjCImplementationDecl *IMPD
@@ -2019,3 +2020,12 @@ bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
 
   return true;
 }
+
+bool SemaAccess::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
+                                    DeclAccessPair Found,
+                                    QualType ObjectType) {
+  return isMemberAccessibleForDeletion(NamingClass, Found, ObjectType,
+                                        SourceLocation(), SemaRef.PDiag());
+}
+
+SemaAccess::SemaAccess(Sema &S) : SemaBase(S) {}
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 483ec7e36eaed..093e1e458bac0 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
 #include "llvm/ADT/SmallVector.h"
@@ -1735,16 +1736,16 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
   }
 
   if (!CStyle) {
-    switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
+    switch (Self.Access().CheckBaseClassAccess(OpRange.getBegin(),
                                       SrcType, DestType,
                                       Paths.front(),
                                 diag::err_downcast_from_inaccessible_base)) {
-    case Sema::AR_accessible:
-    case Sema::AR_delayed:     // be optimistic
-    case Sema::AR_dependent:   // be optimistic
+    case SemaAccess::AR_accessible:
+    case SemaAccess::AR_delayed:     // be optimistic
+    case SemaAccess::AR_dependent:   // be optimistic
       break;
 
-    case Sema::AR_inaccessible:
+    case SemaAccess::AR_inaccessible:
       msg = 0;
       return TC_Failed;
     }
@@ -1834,18 +1835,18 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
   }
 
   if (!CStyle) {
-    switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
+    switch (Self.Access().CheckBaseClassAccess(OpRange.getBegin(),
                                       DestClass, SrcClass,
                                       Paths.front(),
                                       diag::err_upcast_to_inaccessible_base)) {
-    case Sema::AR_accessible:
-    case Sema::AR_delayed:
-    case Sema::AR_dependent:
+    case SemaAccess::AR_accessible:
+    case SemaAccess::AR_delayed:
+    case SemaAccess::AR_dependent:
       // Optimistically assume that the delayed and dependent cases
       // will work out.
       break;
 
-    case Sema::AR_inaccessible:
+    case SemaAccess::AR_inaccessible:
       msg = 0;
       return TC_Failed;
     }
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index ad3ca4cc94ca6..08e6aa2d685ab 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -41,6 +41,7 @@
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCodeCompletion.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
@@ -1715,7 +1716,7 @@ class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
   ResultBuilder &Results;
   DeclContext *InitialLookupCtx;
   // NamingClass and BaseType are used for access-checking. See
-  // Sema::IsSimplyAccessible for details.
+  // SemaAccess::IsSimplyAccessible for details.
   CXXRecordDecl *NamingClass;
   QualType BaseType;
   std::vector<FixItHint> FixIts;
@@ -1778,7 +1779,7 @@ class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
       NamingClass = nullptr;
       BaseType = QualType();
     }
-    return Results.getSema().IsSimplyAccessible(ND, NamingClass, BaseType);
+    return Results.getSema().Access().IsSimplyAccessible(ND, NamingClass, BaseType);
   }
 };
 } // namespace
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f2b9202255cd4..000871001ae1a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -45,6 +45,7 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaInternal.h"
@@ -18159,7 +18160,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
 
   // Set the access specifier.
   if (!Invalid && SearchDC->isRecord())
-    SetMemberAccessSpecifier(New, PrevDecl, AS);
+    Access().SetMemberAccessSpecifier(New, PrevDecl, AS);
 
   if (PrevDecl)
     CheckRedeclarationInModule(New, PrevDecl);
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index e816ea3647a7c..0b84b8e2722ef 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -39,6 +39,7 @@
 #include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaInternal.h"
@@ -10457,7 +10458,7 @@ void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
         // inaccessible one at a time.
         if (AnyAccessFailures && isa<DecompositionDecl>(decl))
           continue;
-        HandleDelayedAccessCheck(diag, decl);
+        Access().HandleDelayedAccessCheck(diag, decl);
         if (diag.Triggered)
           AnyAccessFailures = true;
         break;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..6a47f5a90c16b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -42,6 +42,7 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
@@ -1417,7 +1418,7 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc,
     }
 
     //   ... [accessible, implied by other rules] base class of E.
-    S.CheckBaseClassAccess(Loc, BaseType, S.Context.getRecordType(RD),
+    S.Access().CheckBaseClassAccess(Loc, BaseType, S.Context.getRecordType(RD),
                            *BestPath, diag::err_decomp_decl_inaccessible_base);
     AS = BestPath->Access;
 
@@ -1501,7 +1502,7 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
     // We already checked that the base class is accessible.
     // FIXME: Add 'const' to AccessedEntity's classes so we can remove the
     // const_cast here.
-    S.CheckStructuredBindingMemberAccess(
+    S.Access().CheckStructuredBindingMemberAccess(
         Loc, const_cast<CXXRecordDecl *>(OrigRD),
         DeclAccessPair::make(FD, CXXRecordDecl::MergeAccess(
                                      BasePair.getAccess(), FD->getAccess())));
@@ -3167,12 +3168,12 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
     if (!IgnoreAccess) {
       // Check that the base class can be accessed.
       switch (
-          CheckBaseClassAccess(Loc, Base, Derived, *Path, InaccessibleBaseID)) {
-      case AR_inaccessible:
+          Access().CheckBaseClassAccess(Loc, Base, Derived, *Path, InaccessibleBaseID)) {
+      case SemaAccess::AR_inaccessible:
         return true;
-      case AR_accessible:
-      case AR_dependent:
-      case AR_delayed:
+      case SemaAccess::AR_accessible:
+      case SemaAccess::AR_dependent:
+      case SemaAccess::AR_delayed:
         break;
       }
     }
@@ -5904,7 +5905,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
     // Dtor might still be missing, e.g because it's invalid.
     if (!Dtor)
       continue;
-    CheckDestructorAccess(Field->getLocation(), Dtor,
+    Access().CheckDestructorAccess(Field->getLocation(), Dtor,
                           PDiag(diag::err_access_dtor_field)
                             << Field->getDeclName()
                             << FieldType);
@@ -5954,7 +5955,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
       continue;
 
     // FIXME: caret should be on the start of the class name
-    CheckDestructorAccess(Base.getBeginLoc(), Dtor,
+    Access().CheckDestructorAccess(Base.getBeginLoc(), Dtor,
                           PDiag(diag::err_access_dtor_base)
                               << Base.getType() << Base.getSourceRange(),
                           Context.getTypeDeclType(ClassDecl));
@@ -5991,12 +5992,12 @@ void Sema::MarkVirtualBaseDestructorsReferenced(
     // Dtor might still be missing, e.g because it's invalid.
     if (!Dtor)
       continue;
-    if (CheckDestructorAccess(
+    if (Access().CheckDestructorAccess(
             ClassDecl->getLocation(), Dtor,
             PDiag(diag::err_access_dtor_vbase)
                 << Context.getTypeDeclType(ClassDecl) << VBase.getType(),
             Context.getTypeDeclType(ClassDecl)) ==
-        AR_accessible) {
+        SemaAccess::AR_accessible) {
       CheckDerivedToBaseConversion(
           Context.getTypeDeclType(ClassDecl), VBase.getType(),
           diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(),
@@ -8266,7 +8267,7 @@ class DefaultedComparisonAnalyzer
         QualType ObjectType = Subobj.Kind == Subobject::Member
                                   ? Args[0]->getType()
                                   : S.Context.getRecordType(RD);
-        if (!S.isMemberAccessibleForDeletion(
+        if (!S.Access().isMemberAccessibleForDeletion(
                 ArgClass, Best->FoundDecl, ObjectType, Subobj.Loc,
                 Diagnose == ExplainDeleted
                     ? S.PDiag(diag::note_defaulted_comparison_inaccessible)
@@ -9465,7 +9466,7 @@ bool SpecialMemberDeletionInfo::isAccessible(Subobject Subobj,
     objectTy = S.Context.getTypeDeclType(target->getParent());
   }
 
-  return S.isMemberAccessibleForDeletion(
+  return S.Access().isMemberAccessibleForDeletion(
       target->getParent(), DeclAccessPair::make(target, access), objectTy);
 }
 
@@ -16234,7 +16235,7 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
   // though.
   if (!VD->getType()->isArrayType()) {
     MarkFunctionReferenced(VD->getLocation(), Destructor);
-    CheckDestructorAccess(VD->getLocation(), Destructor,
+    Access().CheckDestructorAccess(VD->getLocation(), Destructor,
                           PDiag(diag::err_access_dtor_var)
                               << VD->getDeclName() << VD->getType());
     DiagnoseUseOfDecl(Destructor, VD->getLocation());
@@ -18100,7 +18101,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
   if (ND->isInvalidDecl()) {
     FrD->setInvalidDecl();
   } else {
-    if (DC->isRecord()) CheckFriendAccess(ND);
+    if (DC->isRecord()) Access().CheckFriendAccess(ND);
 
     FunctionDecl *FD;
     if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 6d4379283f198..7659ca192b7be 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -26,6 +26,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
 #include "llvm/ADT/DenseMap.h"
@@ -5542,7 +5543,7 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
         CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
         if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(RD)) {
           SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor);
-          SemaRef.CheckDestructorAccess(
+          SemaRef.Access().CheckDestructorAccess(
               Field->getLocation(), Destructor,
               SemaRef.PDiag(diag::err_access_dtor_ivar)
                   << Context.getBaseElementType(Field->getType()));
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 41bf273d12f2f..5969a7010e9c0 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Sema/SemaAccess.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include <optional>
@@ -752,16 +753,16 @@ bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) {
     return false;
 
   // Do this check from a context without privileges.
-  switch (CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType,
+  switch (Access().CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType,
                                Paths.front(),
                                /*Diagnostic*/ 0,
                                /*ForceCheck*/ true,
                                /*ForceUnprivileged*/ true)) {
-  case AR_accessible: return true;
-  case AR_inaccessible: return false;
-  case AR_dependent:
+  case SemaAccess::AR_accessible: return true;
+  case SemaAccess::AR_inaccessible: return false;
+  case SemaAccess::AR_dependent:
     llvm_unreachable("access check dependent for unprivileged context");
-  case AR_delayed:
+  case SemaAccess::AR_delayed:
     llvm_unreachable("access check delayed in non-declaration");
   }
   llvm_unreachable("unexpected access check result");
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index e4601f7d6c47d..51f62d49b19e7 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -38,6 +38,7 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaLambda.h"
@@ -1044,7 +1045,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
   if (!RD->hasIrrelevantDestructor()) {
     if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
       MarkFunctionReferenced(E->getExprLoc(), Destructor);
-      CheckDestructorAccess(E->getExprLoc(), Destructor,
+      Access().CheckDestructorAccess(E->getExprLoc(), Destructor,
                             PDiag(diag::err_access_dtor_exception) << Ty);
       if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
         return true;
@@ -2615,8 +2616,8 @@ static bool resolveAllocationOverload(
   case OR_Success: {
     // Got one!
     FunctionDecl *FnDecl = Best->Function;
-    if (S.CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(),
-                                Best->FoundDecl) == Sema::AR_inaccessible)
+    if (S.Access().CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(),
+                                Best->FoundDecl) == SemaAccess::AR_inaccessible)
       return true;
 
     Operator = FnDecl;
@@ -3022,7 +3023,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
       }
     }
 
-    CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
+    Access().CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
                           Matches[0].first);
   } else if (!Matches.empty()) {
     // We found multiple suitable operators. Per [expr.new]p20, that means we
@@ -3381,8 +3382,8 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
       return true;
     }
 
-    if (CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
-                              Matches[0].Found, Diagnose) == AR_inaccessible)
+    if (Access().CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
+                              Matches[0].Found, Diagnose) == SemaAccess::AR_inaccessible)
       return true;
 
     return false;
@@ -3867,7 +3868,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
     bool IsVirtualDelete = false;
     if (PointeeRD) {
       if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
-        CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor,
+        Access().CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor,
                               PDiag(diag::err_access_dtor) << PointeeElem);
         IsVirtualDelete = Dtor->isVirtual();
       }
@@ -4216,7 +4217,7 @@ static ExprResult BuildCXXCastArgument(Sema &S,
                                   ConstructorArgs))
       return ExprError();
 
-    S.CheckConstructorAccess(CastLoc, Constructor, FoundDecl,
+    S.Access().CheckConstructorAccess(CastLoc, Constructor, FoundDecl,
                              InitializedEntity::InitializeTemporary(Ty));
     if (S.DiagnoseUseOfDecl(Method, CastLoc))
       return ExprError();
@@ -4235,7 +4236,7 @@ static ExprResult BuildCXXCastArgument(Sema &S,
   case CK_UserDefinedConversion: {
     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
 
-    S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
+    S.Access().CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
     if (S.DiagnoseUseOfDecl(Method, CastLoc))
       return ExprError();
 
@@ -7646,7 +7647,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
 
   if (Destructor) {
     MarkFunctionReferenced(E->getExprLoc(), Destructor);
-    CheckDestructorAccess(E->getExprLoc(), Destructor,
+    Access().CheckDestructorAccess(E->getExprLoc(), Destructor,
                           PDiag(diag::err_access_dtor_temp)
                             << E->getType());
     if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
@@ -7817,7 +7818,7 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
     Temp->setDestructor(Destructor);
 
     MarkFunctionReferenced(Bind->getExprLoc(), Destructor);
-    CheckDestructorAccess(Bind->getExprLoc(), Destructor,
+    Access().CheckDestructorAccess(Bind->getExprLoc(), Destructor,
                           PDiag(diag::err_access_dtor_temp)
                             << Bind->getType());
     if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()))
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 9aa60204bf29d..c6c2d77be008a 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -20,6 +20,7 @@
 #include "clang/Sema/Overload.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
 #include "clang/Sema/SemaOpenMP.h"
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 353e911c5cc33..2e328fdca61c7 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -27,6 +27,7 @@
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Ownership.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
 #include "llvm/ADT/APInt.h"
@@ -1931,7 +1932,7 @@ static bool checkDestructorReference(QualType ElementType, SourceLocation Loc,
     return false;
 
   CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(CXXRD);
-  SemaRef.CheckDestructorAccess(Loc, Destructor,
+  SemaRef.Access().CheckDestructorAccess(Loc, Destructor,
                                 SemaRef.PDiag(diag::err_access_dtor_temp)
                                 << ElementType);
   SemaRef.MarkFunctionReferenced(Loc, Destructor);
@@ -6858,7 +6859,7 @@ static ExprResult CopyObject(Sema &S,
   SmallVector<Expr*, 8> ConstructorArgs;
   CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
-  S.CheckConstructorAccess(Loc, Constructor, Best->FoundDecl, Entity,
+  S.Access().CheckConstructorAccess(Loc, Constructor, Best->FoundDecl, Entity,
                            IsExtraneousCopy);
 
   if (IsExtraneousCopy) {
@@ -6969,7 +6970,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
 
   switch (OR) {
   case OR_Success:
-    S.CheckConstructorAccess(Loc, cast<CXXConstructorDecl>(Best->Function),
+    S.Access().CheckConstructorAccess(Loc, cast<CXXConstructorDecl>(Best->Function),
                              Best->FoundDecl, Entity, Diag);
     // FIXME: Check default arguments as far as that's possible.
     break;
@@ -7172,7 +7173,7 @@ PerformConstructorInitialization(Sema &S,
     return ExprError();
 
   // Only check access if all of that succeeded.
-  S.CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl, Entity);
+  S.Access().CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl, Entity);
   if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
     return ExprError();
 
@@ -8823,7 +8824,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
     case SK_ResolveAddressOfOverloadedFunction:
       // Overload resolution determined which function invoke; update the
       // initializer to reflect that choice.
-      S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
+      S.Access().CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
       if (S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()))
         return ExprError();
       CurInit = S.FixOverloadedFunctionReference(CurInit,
@@ -8968,7 +8969,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
         if (CurInit.isInvalid())
           return ExprError();
 
-        S.CheckConstructorAccess(Kind.getLocation(), Constructor, FoundFn,
+        S.Access().CheckConstructorAccess(Kind.getLocation(), Constructor, FoundFn,
                                  Entity);
         if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
           return ExprError();
@@ -8978,7 +8979,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
       } else {
         // Build a call to the conversion function.
         CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
-        S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
+        S.Access().CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
                                     FoundFn);
         if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
           return ExprError();
@@ -9012,7 +9013,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
         if (const RecordType *Record = T->getAs<RecordType>()) {
           CXXDestructorDecl *Destructor
             = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
-          S.CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor,
+          S.Access().CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor,
                                   S.PDiag(diag::err_access_dtor_temp) << T);
           S.MarkFunctionReferenced(CurInit.get()->getBeginLoc(), Destructor);
           if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getBeginLoc()))
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 0834db95d42ad..c3c22e95e3b7f 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -33,6 +33,7 @@
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/TemplateDeduction.h"
 #include "clang/Sema/TypoCorrection.h"
@@ -4884,10 +4885,10 @@ void TypoCorrectionConsumer::performQualifiedLookups() {
         }
         for (LookupResult::iterator TRD = Result.begin(), TRDEnd = Result.end();
              TRD != TRDEnd; ++TRD) {
-          if (SemaRef.CheckMemberAccess(TC.getCorrectionRange().getBegin(),
+          if (SemaRef.Access().CheckMemberAccess(TC.getCorrectionRange().getBegin(),
                                         NSType ? NSType->getAsCXXRecordDecl()
                                                : nullptr,
-                                        TRD.getPair()) == Sema::AR_accessible)
+                                        TRD.getPair()) == SemaAccess::AR_accessible)
             TC.addCorrectionDecl(*TRD);
         }
         if (TC.isResolved()) {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 6110e5229b076..4a2e68dd54876 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -35,6 +35,7 @@
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/IndexedMap.h"
 #include "llvm/ADT/PointerEmbeddedInt.h"
@@ -19510,9 +19511,9 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
                 VD->getType().getUnqualifiedType()))) {
-          if (SemaRef.CheckBaseClassAccess(
+          if (SemaRef.Access().CheckBaseClassAccess(
                   Loc, VD->getType(), Ty, Paths.front(),
-                  /*DiagID=*/0) != Sema::AR_inaccessible) {
+                  /*DiagID=*/0) != SemaAccess::AR_inaccessible) {
             SemaRef.BuildBasePathArray(Paths, BasePath);
             return SemaRef.BuildDeclRefExpr(
                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
@@ -22357,9 +22358,9 @@ static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
               VD->getType().getUnqualifiedType()))) {
-        if (SemaRef.CheckBaseClassAccess(
+        if (SemaRef.Access().CheckBaseClassAccess(
                 Loc, VD->getType(), Type, Paths.front(),
-                /*DiagID=*/0) != Sema::AR_inaccessible) {
+                /*DiagID=*/0) != SemaAccess::AR_inaccessible) {
           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
         }
       }
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 2eb25237a0de6..6089654a04e2e 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -31,6 +31,7 @@
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Overload.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
@@ -3521,7 +3522,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
   }
 
   if (!IgnoreBaseAccess)
-    CheckBaseClassAccess(From->getExprLoc(), FromClass, ToClass,
+    Access().CheckBaseClassAccess(From->getExprLoc(), FromClass, ToClass,
                          Paths.front(),
                          diag::err_downcast_from_inaccessible_base);
 
@@ -6538,7 +6539,7 @@ diagnoseNoViableConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From,
     if (SemaRef.isSFINAEContext())
       return true;
 
-    SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
+    SemaRef.Access().CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
     ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion,
                                                        HadMultipleCandidates);
     if (Result.isInvalid())
@@ -6561,7 +6562,7 @@ static bool recordConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From,
                              DeclAccessPair &Found) {
   CXXConversionDecl *Conversion =
       cast<CXXConversionDecl>(Found->getUnderlyingDecl());
-  SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
+  SemaRef.Access().CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
 
   QualType ToType = Conversion->getConversionType().getNonReferenceType();
   if (!Converter.SuppressConversion) {
@@ -13273,7 +13274,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
       if (Resolver.IsStaticMemberFunctionFromBoundPointer())
         Resolver.ComplainIsStaticMemberFunctionFromBoundPointer();
       else
-        CheckAddressOfMemberAccess(AddressOfExpr, FoundResult);
+        Access().CheckAddressOfMemberAccess(AddressOfExpr, FoundResult);
     }
   }
 
@@ -13397,7 +13398,7 @@ bool Sema::resolveAndFixAddressOfSingleOverloadCandidate(
   // unavailable is consistent with our behavior elsewhere. So, always check
   // for both.
   DiagnoseUseOfDecl(Found, E->getExprLoc());
-  CheckAddressOfMemberAccess(E, DAP);
+  Access().CheckAddressOfMemberAccess(E, DAP);
   ExprResult Res = FixOverloadedFunctionReference(E, DAP, Found);
   if (Res.isInvalid())
     return false;
@@ -14060,7 +14061,7 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
   switch (OverloadResult) {
   case OR_Success: {
     FunctionDecl *FDecl = (*Best)->Function;
-    SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
+    SemaRef.Access().CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
     if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()))
       return ExprError();
     ExprResult Res =
@@ -14390,7 +14391,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
 
       // Convert the arguments.
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
-        CheckMemberOperatorAccess(OpLoc, Input, nullptr, Best->FoundDecl);
+        Access().CheckMemberOperatorAccess(OpLoc, Input, nullptr, Best->FoundDecl);
 
         ExprResult InputInit;
         if (Method->isExplicitObjectMemberFunction())
@@ -14787,7 +14788,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
         // Convert the arguments.
         if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
           // Best->Access is only meaningful for class members.
-          CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
+          Access().CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
 
           ExprResult Arg0, Arg1;
           unsigned ParamIdx = 0;
@@ -15244,7 +15245,7 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
         // We matched an overloaded operator. Build a call to that
         // operator.
 
-        CheckMemberOperatorAccess(LLoc, Args[0], ArgExpr, Best->FoundDecl);
+        Access().CheckMemberOperatorAccess(LLoc, Args[0], ArgExpr, Best->FoundDecl);
 
         // Convert the arguments.
         CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
@@ -15546,7 +15547,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
     case OR_Success:
       Method = cast<CXXMethodDecl>(Best->Function);
       FoundDecl = Best->FoundDecl;
-      CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
+      Access().CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
       if (DiagnoseUseOfOverloadedDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
         break;
       // If FoundDecl is different from Method (such as if one is a template
@@ -15871,7 +15872,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
       = cast<CXXConversionDecl>(
                          Best->Conversions[0].UserDefined.ConversionFunction);
 
-    CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr,
+    Access().CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr,
                               Best->FoundDecl);
     if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
       return ExprError();
@@ -15895,7 +15896,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
     return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
   }
 
-  CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl);
+  Access().CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl);
 
   // We found an overloaded operator(). Build a CXXOperatorCallExpr
   // that calls this method, using Object for the implicit object
@@ -16068,7 +16069,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
   }
   }
 
-  CheckMemberOperatorAccess(OpLoc, Base, nullptr, Best->FoundDecl);
+  Access().CheckMemberOperatorAccess(OpLoc, Base, nullptr, Best->FoundDecl);
 
   // Convert the object parameter.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4937cce4621f0..237b0311d8d7c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -33,6 +33,7 @@
 #include "clang/Sema/Overload.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
@@ -2165,7 +2166,7 @@ DeclResult Sema::CheckClassTemplate(
 
   // Set the access specifier.
   if (!Invalid && TUK != TUK_Friend && NewTemplate->getDeclContext()->isRecord())
-    SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
+    Access().SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
 
   // Set the lexical context of these templates
   NewClass->setLexicalDeclContext(CurContext);
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 381d79b2fcd46..1dbb1511f1e7f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -26,6 +26,7 @@
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaAccess.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
@@ -1961,7 +1962,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
     Owner->addDecl(InstTemplate);
   } else if (InstTemplate->getDeclContext()->isRecord() &&
              !getPreviousDeclForInstantiation(D)) {
-    SemaRef.CheckFriendAccess(InstTemplate);
+    SemaRef.Access().CheckFriendAccess(InstTemplate);
   }
 
   return InstTemplate;
@@ -2857,7 +2858,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
     // We only need to re-check access for methods which we didn't
     // manage to match during parsing.
     if (!D->getPreviousDecl())
-      SemaRef.CheckFriendAccess(Method);
+      SemaRef.Access().CheckFriendAccess(Method);
 
     Record->makeDeclVisibleInContext(Method);
 
@@ -6529,7 +6530,7 @@ void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
   for (auto *DD : Pattern->ddiags()) {
     switch (DD->getKind()) {
     case DependentDiagnostic::Access:
-      HandleDependentAccessCheck(*DD, TemplateArgs);
+      Access().HandleDependentAccessCheck(*DD, TemplateArgs);
       break;
     }
   }

>From 55757c3bf14e774e8d7ed0c2931daa4e97604e2a Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 00:50:43 +0300
Subject: [PATCH 2/3] Run clang-format

---
 clang/include/clang/Sema/SemaAccess.h |   3 +-
 clang/lib/Sema/SemaAccess.cpp         | 198 +++++++++++++-------------
 clang/lib/Sema/SemaCast.cpp           |  18 ++-
 clang/lib/Sema/SemaCodeComplete.cpp   |   3 +-
 clang/lib/Sema/SemaDeclCXX.cpp        |  29 ++--
 clang/lib/Sema/SemaExceptionSpec.cpp  |  18 +--
 clang/lib/Sema/SemaExprCXX.cpp        |  36 +++--
 clang/lib/Sema/SemaInit.cpp           |  32 +++--
 clang/lib/Sema/SemaLookup.cpp         |   8 +-
 clang/lib/Sema/SemaOverload.cpp       |  24 ++--
 10 files changed, 194 insertions(+), 175 deletions(-)

diff --git a/clang/include/clang/Sema/SemaAccess.h b/clang/include/clang/Sema/SemaAccess.h
index 280c41aa33124..dd89f042ccb89 100644
--- a/clang/include/clang/Sema/SemaAccess.h
+++ b/clang/include/clang/Sema/SemaAccess.h
@@ -100,8 +100,7 @@ class SemaAccess : public SemaBase {
                                      SourceLocation Loc,
                                      const PartialDiagnostic &Diag);
   bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
-                                     DeclAccessPair Found,
-                                     QualType ObjectType);
+                                     DeclAccessPair Found, QualType ObjectType);
 
   void HandleDependentAccessCheck(
       const DependentDiagnostic &DD,
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 1e9958d845ba7..9272020d83d33 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -39,8 +39,8 @@ enum AccessResult {
 /// Returns true on error (when the previous member decl access specifier
 /// is different from the new member decl access specifier).
 bool SemaAccess::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
-                                    NamedDecl *PrevMemberDecl,
-                                    AccessSpecifier LexicalAS) {
+                                          NamedDecl *PrevMemberDecl,
+                                          AccessSpecifier LexicalAS) {
   if (!PrevMemberDecl) {
     // Use the lexical access specifier.
     MemberDecl->setAccess(LexicalAS);
@@ -1461,7 +1461,7 @@ static AccessResult CheckEffectiveAccess(Sema &S,
 }
 
 static SemaAccess::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
-                                      AccessTarget &Entity) {
+                                            AccessTarget &Entity) {
   // If the access path is public, it's accessible everywhere.
   if (Entity.getAccess() == AS_public)
     return SemaAccess::AR_accessible;
@@ -1504,9 +1504,12 @@ static SemaAccess::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
 
   EffectiveContext EC(S.CurContext);
   switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
-  case AR_accessible: return SemaAccess::AR_accessible;
-  case AR_inaccessible: return SemaAccess::AR_inaccessible;
-  case AR_dependent: return SemaAccess::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");
 }
@@ -1537,16 +1540,17 @@ void SemaAccess::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
     DD.Triggered = true;
 }
 
-void SemaAccess::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 = SemaRef.FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
-                                       TemplateArgs);
+                                               TemplateArgs);
   if (!NamingD) return;
-  Decl *TargetD = SemaRef.FindInstantiatedDecl(Loc, DD.getAccessTarget(),
-                                       TemplateArgs);
+  Decl *TargetD =
+      SemaRef.FindInstantiatedDecl(Loc, DD.getAccessTarget(), TemplateArgs);
   if (!TargetD) return;
 
   if (DD.isAccessToMember()) {
@@ -1555,37 +1559,34 @@ void SemaAccess::HandleDependentAccessCheck(const DependentDiagnostic &DD,
     QualType BaseObjectType = DD.getAccessBaseObjectType();
     if (!BaseObjectType.isNull()) {
       BaseObjectType = SemaRef.SubstType(BaseObjectType, TemplateArgs, Loc,
-                                 DeclarationName());
+                                         DeclarationName());
       if (BaseObjectType.isNull()) return;
     }
 
-    AccessTarget Entity(SemaRef.Context,
-                        AccessTarget::Member,
-                        NamingClass,
+    AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass,
                         DeclAccessPair::make(TargetDecl, Access),
                         BaseObjectType);
     Entity.setDiag(DD.getDiagnostic());
     CheckAccess(SemaRef, Loc, Entity);
   } else {
-    AccessTarget Entity(SemaRef.Context,
-                        AccessTarget::Base,
+    AccessTarget Entity(SemaRef.Context, AccessTarget::Base,
                         cast<CXXRecordDecl>(TargetD),
-                        cast<CXXRecordDecl>(NamingD),
-                        Access);
+                        cast<CXXRecordDecl>(NamingD), Access);
     Entity.setDiag(DD.getDiagnostic());
     CheckAccess(SemaRef, Loc, Entity);
   }
 }
 
-SemaAccess::AccessResult SemaAccess::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
-                                                     DeclAccessPair Found) {
+SemaAccess::AccessResult
+SemaAccess::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
+                                        DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       !E->getNamingClass() ||
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, E->getNamingClass(),
-                      Found, QualType());
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member,
+                      E->getNamingClass(), Found, QualType());
   Entity.setDiag(diag::err_access) << E->getSourceRange();
 
   return CheckAccess(SemaRef, E->getNameLoc(), Entity);
@@ -1593,8 +1594,9 @@ SemaAccess::AccessResult SemaAccess::CheckUnresolvedLookupAccess(UnresolvedLooku
 
 /// Perform access-control checking on a previously-unresolved member
 /// access which has now been resolved to a member.
-SemaAccess::AccessResult SemaAccess::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
-                                                     DeclAccessPair Found) {
+SemaAccess::AccessResult
+SemaAccess::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
+                                        DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       Found.getAccess() == AS_public)
     return AR_accessible;
@@ -1603,8 +1605,8 @@ SemaAccess::AccessResult SemaAccess::CheckUnresolvedMemberAccess(UnresolvedMembe
   if (E->isArrow())
     BaseType = BaseType->castAs<PointerType>()->getPointeeType();
 
-  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, E->getNamingClass(),
-                      Found, BaseType);
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member,
+                      E->getNamingClass(), Found, BaseType);
   Entity.setDiag(diag::err_access) << E->getSourceRange();
 
   return CheckAccess(SemaRef, E->getMemberLoc(), Entity);
@@ -1613,10 +1615,10 @@ SemaAccess::AccessResult SemaAccess::CheckUnresolvedMemberAccess(UnresolvedMembe
 /// Is the given member accessible for the purposes of deciding whether to
 /// define a special member function as deleted?
 bool SemaAccess::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
-                                         DeclAccessPair Found,
-                                         QualType ObjectType,
-                                         SourceLocation Loc,
-                                         const PartialDiagnostic &Diag) {
+                                               DeclAccessPair Found,
+                                               QualType ObjectType,
+                                               SourceLocation Loc,
+                                               const PartialDiagnostic &Diag) {
   // Fast path.
   if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
     return true;
@@ -1636,10 +1638,10 @@ bool SemaAccess::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
   llvm_unreachable("bad access result");
 }
 
-SemaAccess::AccessResult SemaAccess::CheckDestructorAccess(SourceLocation Loc,
-                                               CXXDestructorDecl *Dtor,
-                                               const PartialDiagnostic &PDiag,
-                                               QualType ObjectTy) {
+SemaAccess::AccessResult
+SemaAccess::CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor,
+                                  const PartialDiagnostic &PDiag,
+                                  QualType ObjectTy) {
   if (!getLangOpts().AccessControl)
     return AR_accessible;
 
@@ -1649,22 +1651,21 @@ SemaAccess::AccessResult SemaAccess::CheckDestructorAccess(SourceLocation Loc,
     return AR_accessible;
 
   CXXRecordDecl *NamingClass = Dtor->getParent();
-  if (ObjectTy.isNull()) ObjectTy = SemaRef.Context.getTypeDeclType(NamingClass);
+  if (ObjectTy.isNull())
+    ObjectTy = SemaRef.Context.getTypeDeclType(NamingClass);
 
   AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass,
-                      DeclAccessPair::make(Dtor, Access),
-                      ObjectTy);
+                      DeclAccessPair::make(Dtor, Access), ObjectTy);
   Entity.setDiag(PDiag); // TODO: avoid copy
 
   return CheckAccess(SemaRef, Loc, Entity);
 }
 
 /// Checks access to a constructor.
-SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLoc,
-                                                CXXConstructorDecl *Constructor,
-                                                DeclAccessPair Found,
-                                                const InitializedEntity &Entity,
-                                                bool IsCopyBindingRefToTemp) {
+SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(
+    SourceLocation UseLoc, CXXConstructorDecl *Constructor,
+    DeclAccessPair Found, const InitializedEntity &Entity,
+    bool IsCopyBindingRefToTemp) {
   if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
     return AR_accessible;
 
@@ -1672,8 +1673,8 @@ SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLo
   switch (Entity.getKind()) {
   default:
     PD = SemaRef.PDiag(IsCopyBindingRefToTemp
-                 ? diag::ext_rvalue_to_reference_access_ctor
-                 : diag::err_access_ctor);
+                           ? diag::ext_rvalue_to_reference_access_ctor
+                           : diag::err_access_ctor);
 
     break;
 
@@ -1707,11 +1708,10 @@ SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLo
 }
 
 /// Checks access to a constructor.
-SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLoc,
-                                                CXXConstructorDecl *Constructor,
-                                                DeclAccessPair Found,
-                                                const InitializedEntity &Entity,
-                                                const PartialDiagnostic &PD) {
+SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(
+    SourceLocation UseLoc, CXXConstructorDecl *Constructor,
+    DeclAccessPair Found, const InitializedEntity &Entity,
+    const PartialDiagnostic &PD) {
   if (!getLangOpts().AccessControl ||
       Found.getAccess() == AS_public)
     return AR_accessible;
@@ -1749,11 +1749,9 @@ SemaAccess::AccessResult SemaAccess::CheckConstructorAccess(SourceLocation UseLo
 }
 
 /// Checks access to an overloaded operator new or delete.
-SemaAccess::AccessResult SemaAccess::CheckAllocationAccess(SourceLocation OpLoc,
-                                               SourceRange PlacementRange,
-                                               CXXRecordDecl *NamingClass,
-                                               DeclAccessPair Found,
-                                               bool Diagnose) {
+SemaAccess::AccessResult SemaAccess::CheckAllocationAccess(
+    SourceLocation OpLoc, SourceRange PlacementRange,
+    CXXRecordDecl *NamingClass, DeclAccessPair Found, bool Diagnose) {
   if (!getLangOpts().AccessControl ||
       !NamingClass ||
       Found.getAccess() == AS_public)
@@ -1769,16 +1767,16 @@ SemaAccess::AccessResult SemaAccess::CheckAllocationAccess(SourceLocation OpLoc,
 }
 
 /// Checks access to a member.
-SemaAccess::AccessResult SemaAccess::CheckMemberAccess(SourceLocation UseLoc,
-                                           CXXRecordDecl *NamingClass,
-                                           DeclAccessPair Found) {
+SemaAccess::AccessResult
+SemaAccess::CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass,
+                              DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       !NamingClass ||
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass,
-                      Found, QualType());
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, NamingClass, Found,
+                      QualType());
 
   return CheckAccess(SemaRef, UseLoc, Entity);
 }
@@ -1786,23 +1784,23 @@ SemaAccess::AccessResult SemaAccess::CheckMemberAccess(SourceLocation UseLoc,
 /// Checks implicit access to a member in a structured binding.
 SemaAccess::AccessResult
 SemaAccess::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
-                                         CXXRecordDecl *DecomposedClass,
-                                         DeclAccessPair Field) {
+                                               CXXRecordDecl *DecomposedClass,
+                                               DeclAccessPair Field) {
   if (!getLangOpts().AccessControl ||
       Field.getAccess() == AS_public)
     return AR_accessible;
 
-  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, DecomposedClass, Field,
-                      SemaRef.Context.getRecordType(DecomposedClass));
+  AccessTarget Entity(SemaRef.Context, AccessTarget::Member, DecomposedClass,
+                      Field, SemaRef.Context.getRecordType(DecomposedClass));
   Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
 
   return CheckAccess(SemaRef, UseLoc, Entity);
 }
 
-SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc,
-                                                   Expr *ObjectExpr,
-                                                   const SourceRange &Range,
-                                                   DeclAccessPair Found) {
+SemaAccess::AccessResult
+SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc, Expr *ObjectExpr,
+                                      const SourceRange &Range,
+                                      DeclAccessPair Found) {
   if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
     return AR_accessible;
 
@@ -1818,19 +1816,18 @@ SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation Op
 
 /// Checks access to an overloaded member operator, including
 /// conversion operators.
-SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc,
-                                                   Expr *ObjectExpr,
-                                                   Expr *ArgExpr,
-                                                   DeclAccessPair Found) {
+SemaAccess::AccessResult
+SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc, Expr *ObjectExpr,
+                                      Expr *ArgExpr, DeclAccessPair Found) {
   return CheckMemberOperatorAccess(
       OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
       Found);
 }
 
-SemaAccess::AccessResult SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc,
-                                                   Expr *ObjectExpr,
-                                                   ArrayRef<Expr *> ArgExprs,
-                                                   DeclAccessPair FoundDecl) {
+SemaAccess::AccessResult
+SemaAccess::CheckMemberOperatorAccess(SourceLocation OpLoc, Expr *ObjectExpr,
+                                      ArrayRef<Expr *> ArgExprs,
+                                      DeclAccessPair FoundDecl) {
   SourceRange R;
   if (!ArgExprs.empty()) {
     R = SourceRange(ArgExprs.front()->getBeginLoc(),
@@ -1865,15 +1862,18 @@ SemaAccess::AccessResult SemaAccess::CheckFriendAccess(NamedDecl *target) {
   // while the ParsingDeclarator is active.
   EffectiveContext EC(SemaRef.CurContext);
   switch (CheckEffectiveAccess(SemaRef, EC, target->getLocation(), entity)) {
-  case ::AR_accessible: return SemaAccess::AR_accessible;
-  case ::AR_inaccessible: return SemaAccess::AR_inaccessible;
-  case ::AR_dependent: return SemaAccess::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");
 }
 
-SemaAccess::AccessResult SemaAccess::CheckAddressOfMemberAccess(Expr *OvlExpr,
-                                                    DeclAccessPair Found) {
+SemaAccess::AccessResult
+SemaAccess::CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       Found.getAccess() == AS_none ||
       Found.getAccess() == AS_public)
@@ -1896,13 +1896,11 @@ SemaAccess::AccessResult SemaAccess::CheckAddressOfMemberAccess(Expr *OvlExpr,
 ///     control is disabled;  some things rely on this for semantics
 /// \param ForceUnprivileged true if this check should proceed as if the
 ///     context had no special privileges
-SemaAccess::AccessResult SemaAccess::CheckBaseClassAccess(SourceLocation AccessLoc,
-                                              QualType Base,
-                                              QualType Derived,
-                                              const CXXBasePath &Path,
-                                              unsigned DiagID,
-                                              bool ForceCheck,
-                                              bool ForceUnprivileged) {
+SemaAccess::AccessResult
+SemaAccess::CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base,
+                                 QualType Derived, const CXXBasePath &Path,
+                                 unsigned DiagID, bool ForceCheck,
+                                 bool ForceUnprivileged) {
   if (!ForceCheck && !getLangOpts().AccessControl)
     return AR_accessible;
 
@@ -1919,11 +1917,14 @@ SemaAccess::AccessResult SemaAccess::CheckBaseClassAccess(SourceLocation AccessL
     Entity.setDiag(DiagID) << Derived << Base;
 
   if (ForceUnprivileged) {
-    switch (CheckEffectiveAccess(SemaRef, EffectiveContext(),
-                                 AccessLoc, Entity)) {
-    case ::AR_accessible: return SemaAccess::AR_accessible;
-    case ::AR_inaccessible: return SemaAccess::AR_inaccessible;
-    case ::AR_dependent: return SemaAccess::AR_dependent;
+    switch (
+        CheckEffectiveAccess(SemaRef, EffectiveContext(), AccessLoc, Entity)) {
+    case ::AR_accessible:
+      return SemaAccess::AR_accessible;
+    case ::AR_inaccessible:
+      return SemaAccess::AR_inaccessible;
+    case ::AR_dependent:
+      return SemaAccess::AR_dependent;
     }
     llvm_unreachable("unexpected result from CheckEffectiveAccess");
   }
@@ -1964,8 +1965,9 @@ void SemaAccess::CheckLookupAccess(const LookupResult &R) {
 ///        - target (unqualified lookup).
 ///          BaseType is null, NamingClass is the parent class of 'target'.
 /// \return true if the Target is accessible from the Class, false otherwise.
-bool SemaAccess::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
-                              QualType BaseType) {
+bool SemaAccess::IsSimplyAccessible(NamedDecl *Target,
+                                    CXXRecordDecl *NamingClass,
+                                    QualType BaseType) {
   // Perform the C++ accessibility checks first.
   if (Target->isCXXClassMember() && NamingClass) {
     if (!getLangOpts().CPlusPlus)
@@ -2022,10 +2024,10 @@ bool SemaAccess::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClas
 }
 
 bool SemaAccess::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
-                                    DeclAccessPair Found,
-                                    QualType ObjectType) {
+                                               DeclAccessPair Found,
+                                               QualType ObjectType) {
   return isMemberAccessibleForDeletion(NamingClass, Found, ObjectType,
-                                        SourceLocation(), SemaRef.PDiag());
+                                       SourceLocation(), SemaRef.PDiag());
 }
 
 SemaAccess::SemaAccess(Sema &S) : SemaBase(S) {}
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 093e1e458bac0..9aabfef7aabb5 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -1736,13 +1736,12 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
   }
 
   if (!CStyle) {
-    switch (Self.Access().CheckBaseClassAccess(OpRange.getBegin(),
-                                      SrcType, DestType,
-                                      Paths.front(),
-                                diag::err_downcast_from_inaccessible_base)) {
+    switch (Self.Access().CheckBaseClassAccess(
+        OpRange.getBegin(), SrcType, DestType, Paths.front(),
+        diag::err_downcast_from_inaccessible_base)) {
     case SemaAccess::AR_accessible:
-    case SemaAccess::AR_delayed:     // be optimistic
-    case SemaAccess::AR_dependent:   // be optimistic
+    case SemaAccess::AR_delayed:   // be optimistic
+    case SemaAccess::AR_dependent: // be optimistic
       break;
 
     case SemaAccess::AR_inaccessible:
@@ -1835,10 +1834,9 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
   }
 
   if (!CStyle) {
-    switch (Self.Access().CheckBaseClassAccess(OpRange.getBegin(),
-                                      DestClass, SrcClass,
-                                      Paths.front(),
-                                      diag::err_upcast_to_inaccessible_base)) {
+    switch (Self.Access().CheckBaseClassAccess(
+        OpRange.getBegin(), DestClass, SrcClass, Paths.front(),
+        diag::err_upcast_to_inaccessible_base)) {
     case SemaAccess::AR_accessible:
     case SemaAccess::AR_delayed:
     case SemaAccess::AR_dependent:
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 08e6aa2d685ab..4f4a5c1b0ca5e 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -1779,7 +1779,8 @@ class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
       NamingClass = nullptr;
       BaseType = QualType();
     }
-    return Results.getSema().Access().IsSimplyAccessible(ND, NamingClass, BaseType);
+    return Results.getSema().Access().IsSimplyAccessible(ND, NamingClass,
+                                                         BaseType);
   }
 };
 } // namespace
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 6a47f5a90c16b..259f9ed6f6828 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1419,7 +1419,8 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc,
 
     //   ... [accessible, implied by other rules] base class of E.
     S.Access().CheckBaseClassAccess(Loc, BaseType, S.Context.getRecordType(RD),
-                           *BestPath, diag::err_decomp_decl_inaccessible_base);
+                                    *BestPath,
+                                    diag::err_decomp_decl_inaccessible_base);
     AS = BestPath->Access;
 
     ClassWithFields = BaseType->getAsCXXRecordDecl();
@@ -3167,8 +3168,8 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
   if (Path) {
     if (!IgnoreAccess) {
       // Check that the base class can be accessed.
-      switch (
-          Access().CheckBaseClassAccess(Loc, Base, Derived, *Path, InaccessibleBaseID)) {
+      switch (Access().CheckBaseClassAccess(Loc, Base, Derived, *Path,
+                                            InaccessibleBaseID)) {
       case SemaAccess::AR_inaccessible:
         return true;
       case SemaAccess::AR_accessible:
@@ -5906,9 +5907,8 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
     if (!Dtor)
       continue;
     Access().CheckDestructorAccess(Field->getLocation(), Dtor,
-                          PDiag(diag::err_access_dtor_field)
-                            << Field->getDeclName()
-                            << FieldType);
+                                   PDiag(diag::err_access_dtor_field)
+                                       << Field->getDeclName() << FieldType);
 
     MarkFunctionReferenced(Location, Dtor);
     DiagnoseUseOfDecl(Dtor, Location);
@@ -5956,9 +5956,10 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
 
     // FIXME: caret should be on the start of the class name
     Access().CheckDestructorAccess(Base.getBeginLoc(), Dtor,
-                          PDiag(diag::err_access_dtor_base)
-                              << Base.getType() << Base.getSourceRange(),
-                          Context.getTypeDeclType(ClassDecl));
+                                   PDiag(diag::err_access_dtor_base)
+                                       << Base.getType()
+                                       << Base.getSourceRange(),
+                                   Context.getTypeDeclType(ClassDecl));
 
     MarkFunctionReferenced(Location, Dtor);
     DiagnoseUseOfDecl(Dtor, Location);
@@ -5996,8 +5997,7 @@ void Sema::MarkVirtualBaseDestructorsReferenced(
             ClassDecl->getLocation(), Dtor,
             PDiag(diag::err_access_dtor_vbase)
                 << Context.getTypeDeclType(ClassDecl) << VBase.getType(),
-            Context.getTypeDeclType(ClassDecl)) ==
-        SemaAccess::AR_accessible) {
+            Context.getTypeDeclType(ClassDecl)) == SemaAccess::AR_accessible) {
       CheckDerivedToBaseConversion(
           Context.getTypeDeclType(ClassDecl), VBase.getType(),
           diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(),
@@ -16236,8 +16236,8 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
   if (!VD->getType()->isArrayType()) {
     MarkFunctionReferenced(VD->getLocation(), Destructor);
     Access().CheckDestructorAccess(VD->getLocation(), Destructor,
-                          PDiag(diag::err_access_dtor_var)
-                              << VD->getDeclName() << VD->getType());
+                                   PDiag(diag::err_access_dtor_var)
+                                       << VD->getDeclName() << VD->getType());
     DiagnoseUseOfDecl(Destructor, VD->getLocation());
   }
 
@@ -18101,7 +18101,8 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
   if (ND->isInvalidDecl()) {
     FrD->setInvalidDecl();
   } else {
-    if (DC->isRecord()) Access().CheckFriendAccess(ND);
+    if (DC->isRecord())
+      Access().CheckFriendAccess(ND);
 
     FunctionDecl *FD;
     if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 5969a7010e9c0..e78c38bd71bf2 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -10,7 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
@@ -20,6 +19,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Sema/SemaAccess.h"
+#include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include <optional>
@@ -753,13 +753,15 @@ bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) {
     return false;
 
   // Do this check from a context without privileges.
-  switch (Access().CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType,
-                               Paths.front(),
-                               /*Diagnostic*/ 0,
-                               /*ForceCheck*/ true,
-                               /*ForceUnprivileged*/ true)) {
-  case SemaAccess::AR_accessible: return true;
-  case SemaAccess::AR_inaccessible: return false;
+  switch (Access().CheckBaseClassAccess(SourceLocation(), HandlerType,
+                                        ExceptionType, Paths.front(),
+                                        /*Diagnostic*/ 0,
+                                        /*ForceCheck*/ true,
+                                        /*ForceUnprivileged*/ true)) {
+  case SemaAccess::AR_accessible:
+    return true;
+  case SemaAccess::AR_inaccessible:
+    return false;
   case SemaAccess::AR_dependent:
     llvm_unreachable("access check dependent for unprivileged context");
   case SemaAccess::AR_delayed:
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 51f62d49b19e7..3ecf777519391 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1046,7 +1046,8 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
     if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
       MarkFunctionReferenced(E->getExprLoc(), Destructor);
       Access().CheckDestructorAccess(E->getExprLoc(), Destructor,
-                            PDiag(diag::err_access_dtor_exception) << Ty);
+                                     PDiag(diag::err_access_dtor_exception)
+                                         << Ty);
       if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
         return true;
     }
@@ -2616,8 +2617,9 @@ static bool resolveAllocationOverload(
   case OR_Success: {
     // Got one!
     FunctionDecl *FnDecl = Best->Function;
-    if (S.Access().CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(),
-                                Best->FoundDecl) == SemaAccess::AR_inaccessible)
+    if (S.Access().CheckAllocationAccess(R.getNameLoc(), Range,
+                                         R.getNamingClass(), Best->FoundDecl) ==
+        SemaAccess::AR_inaccessible)
       return true;
 
     Operator = FnDecl;
@@ -3023,8 +3025,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
       }
     }
 
-    Access().CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
-                          Matches[0].first);
+    Access().CheckAllocationAccess(
+        StartLoc, Range, FoundDelete.getNamingClass(), Matches[0].first);
   } else if (!Matches.empty()) {
     // We found multiple suitable operators. Per [expr.new]p20, that means we
     // call no 'operator delete' function, but we should at least warn the user.
@@ -3382,8 +3384,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
       return true;
     }
 
-    if (Access().CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
-                              Matches[0].Found, Diagnose) == SemaAccess::AR_inaccessible)
+    if (Access().CheckAllocationAccess(StartLoc, SourceRange(),
+                                       Found.getNamingClass(), Matches[0].Found,
+                                       Diagnose) == SemaAccess::AR_inaccessible)
       return true;
 
     return false;
@@ -3869,7 +3872,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
     if (PointeeRD) {
       if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
         Access().CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor,
-                              PDiag(diag::err_access_dtor) << PointeeElem);
+                                       PDiag(diag::err_access_dtor)
+                                           << PointeeElem);
         IsVirtualDelete = Dtor->isVirtual();
       }
     }
@@ -4217,8 +4221,9 @@ static ExprResult BuildCXXCastArgument(Sema &S,
                                   ConstructorArgs))
       return ExprError();
 
-    S.Access().CheckConstructorAccess(CastLoc, Constructor, FoundDecl,
-                             InitializedEntity::InitializeTemporary(Ty));
+    S.Access().CheckConstructorAccess(
+        CastLoc, Constructor, FoundDecl,
+        InitializedEntity::InitializeTemporary(Ty));
     if (S.DiagnoseUseOfDecl(Method, CastLoc))
       return ExprError();
 
@@ -4236,7 +4241,8 @@ static ExprResult BuildCXXCastArgument(Sema &S,
   case CK_UserDefinedConversion: {
     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
 
-    S.Access().CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
+    S.Access().CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr,
+                                         FoundDecl);
     if (S.DiagnoseUseOfDecl(Method, CastLoc))
       return ExprError();
 
@@ -7648,8 +7654,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
   if (Destructor) {
     MarkFunctionReferenced(E->getExprLoc(), Destructor);
     Access().CheckDestructorAccess(E->getExprLoc(), Destructor,
-                          PDiag(diag::err_access_dtor_temp)
-                            << E->getType());
+                                   PDiag(diag::err_access_dtor_temp)
+                                       << E->getType());
     if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
       return ExprError();
 
@@ -7819,8 +7825,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
 
     MarkFunctionReferenced(Bind->getExprLoc(), Destructor);
     Access().CheckDestructorAccess(Bind->getExprLoc(), Destructor,
-                          PDiag(diag::err_access_dtor_temp)
-                            << Bind->getType());
+                                   PDiag(diag::err_access_dtor_temp)
+                                       << Bind->getType());
     if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()))
       return ExprError();
 
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 2e328fdca61c7..7eb3c13bd6285 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -1932,9 +1932,9 @@ static bool checkDestructorReference(QualType ElementType, SourceLocation Loc,
     return false;
 
   CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(CXXRD);
-  SemaRef.Access().CheckDestructorAccess(Loc, Destructor,
-                                SemaRef.PDiag(diag::err_access_dtor_temp)
-                                << ElementType);
+  SemaRef.Access().CheckDestructorAccess(
+      Loc, Destructor,
+      SemaRef.PDiag(diag::err_access_dtor_temp) << ElementType);
   SemaRef.MarkFunctionReferenced(Loc, Destructor);
   return SemaRef.DiagnoseUseOfDecl(Destructor, Loc);
 }
@@ -6860,7 +6860,7 @@ static ExprResult CopyObject(Sema &S,
   CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
   S.Access().CheckConstructorAccess(Loc, Constructor, Best->FoundDecl, Entity,
-                           IsExtraneousCopy);
+                                    IsExtraneousCopy);
 
   if (IsExtraneousCopy) {
     // If this is a totally extraneous copy for C++03 reference
@@ -6970,8 +6970,9 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
 
   switch (OR) {
   case OR_Success:
-    S.Access().CheckConstructorAccess(Loc, cast<CXXConstructorDecl>(Best->Function),
-                             Best->FoundDecl, Entity, Diag);
+    S.Access().CheckConstructorAccess(Loc,
+                                      cast<CXXConstructorDecl>(Best->Function),
+                                      Best->FoundDecl, Entity, Diag);
     // FIXME: Check default arguments as far as that's possible.
     break;
 
@@ -7173,7 +7174,8 @@ PerformConstructorInitialization(Sema &S,
     return ExprError();
 
   // Only check access if all of that succeeded.
-  S.Access().CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl, Entity);
+  S.Access().CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl,
+                                    Entity);
   if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
     return ExprError();
 
@@ -8824,7 +8826,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
     case SK_ResolveAddressOfOverloadedFunction:
       // Overload resolution determined which function invoke; update the
       // initializer to reflect that choice.
-      S.Access().CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
+      S.Access().CheckAddressOfMemberAccess(CurInit.get(),
+                                            Step->Function.FoundDecl);
       if (S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()))
         return ExprError();
       CurInit = S.FixOverloadedFunctionReference(CurInit,
@@ -8969,8 +8972,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
         if (CurInit.isInvalid())
           return ExprError();
 
-        S.Access().CheckConstructorAccess(Kind.getLocation(), Constructor, FoundFn,
-                                 Entity);
+        S.Access().CheckConstructorAccess(Kind.getLocation(), Constructor,
+                                          FoundFn, Entity);
         if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
           return ExprError();
 
@@ -8979,8 +8982,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
       } else {
         // Build a call to the conversion function.
         CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
-        S.Access().CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
-                                    FoundFn);
+        S.Access().CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(),
+                                             nullptr, FoundFn);
         if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
           return ExprError();
 
@@ -9013,8 +9016,9 @@ ExprResult InitializationSequence::Perform(Sema &S,
         if (const RecordType *Record = T->getAs<RecordType>()) {
           CXXDestructorDecl *Destructor
             = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
-          S.Access().CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor,
-                                  S.PDiag(diag::err_access_dtor_temp) << T);
+          S.Access().CheckDestructorAccess(
+              CurInit.get()->getBeginLoc(), Destructor,
+              S.PDiag(diag::err_access_dtor_temp) << T);
           S.MarkFunctionReferenced(CurInit.get()->getBeginLoc(), Destructor);
           if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getBeginLoc()))
             return ExprError();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index c3c22e95e3b7f..6e888612b8e8b 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4885,10 +4885,10 @@ void TypoCorrectionConsumer::performQualifiedLookups() {
         }
         for (LookupResult::iterator TRD = Result.begin(), TRDEnd = Result.end();
              TRD != TRDEnd; ++TRD) {
-          if (SemaRef.Access().CheckMemberAccess(TC.getCorrectionRange().getBegin(),
-                                        NSType ? NSType->getAsCXXRecordDecl()
-                                               : nullptr,
-                                        TRD.getPair()) == SemaAccess::AR_accessible)
+          if (SemaRef.Access().CheckMemberAccess(
+                  TC.getCorrectionRange().getBegin(),
+                  NSType ? NSType->getAsCXXRecordDecl() : nullptr,
+                  TRD.getPair()) == SemaAccess::AR_accessible)
             TC.addCorrectionDecl(*TRD);
         }
         if (TC.isResolved()) {
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6089654a04e2e..6c9c92383f009 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -3523,8 +3523,8 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
 
   if (!IgnoreBaseAccess)
     Access().CheckBaseClassAccess(From->getExprLoc(), FromClass, ToClass,
-                         Paths.front(),
-                         diag::err_downcast_from_inaccessible_base);
+                                  Paths.front(),
+                                  diag::err_downcast_from_inaccessible_base);
 
   // Must be a base to derived member conversion.
   BuildBasePathArray(Paths, BasePath);
@@ -6539,7 +6539,8 @@ diagnoseNoViableConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From,
     if (SemaRef.isSFINAEContext())
       return true;
 
-    SemaRef.Access().CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
+    SemaRef.Access().CheckMemberOperatorAccess(From->getExprLoc(), From,
+                                               nullptr, Found);
     ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion,
                                                        HadMultipleCandidates);
     if (Result.isInvalid())
@@ -6562,7 +6563,8 @@ static bool recordConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From,
                              DeclAccessPair &Found) {
   CXXConversionDecl *Conversion =
       cast<CXXConversionDecl>(Found->getUnderlyingDecl());
-  SemaRef.Access().CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
+  SemaRef.Access().CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr,
+                                             Found);
 
   QualType ToType = Conversion->getConversionType().getNonReferenceType();
   if (!Converter.SuppressConversion) {
@@ -14391,7 +14393,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
 
       // Convert the arguments.
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
-        Access().CheckMemberOperatorAccess(OpLoc, Input, nullptr, Best->FoundDecl);
+        Access().CheckMemberOperatorAccess(OpLoc, Input, nullptr,
+                                           Best->FoundDecl);
 
         ExprResult InputInit;
         if (Method->isExplicitObjectMemberFunction())
@@ -14788,7 +14791,8 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
         // Convert the arguments.
         if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
           // Best->Access is only meaningful for class members.
-          Access().CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
+          Access().CheckMemberOperatorAccess(OpLoc, Args[0], Args[1],
+                                             Best->FoundDecl);
 
           ExprResult Arg0, Arg1;
           unsigned ParamIdx = 0;
@@ -15245,7 +15249,8 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
         // We matched an overloaded operator. Build a call to that
         // operator.
 
-        Access().CheckMemberOperatorAccess(LLoc, Args[0], ArgExpr, Best->FoundDecl);
+        Access().CheckMemberOperatorAccess(LLoc, Args[0], ArgExpr,
+                                           Best->FoundDecl);
 
         // Convert the arguments.
         CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
@@ -15873,7 +15878,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
                          Best->Conversions[0].UserDefined.ConversionFunction);
 
     Access().CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr,
-                              Best->FoundDecl);
+                                       Best->FoundDecl);
     if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
       return ExprError();
     assert(Conv == Best->FoundDecl.getDecl() &&
@@ -15896,7 +15901,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
     return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
   }
 
-  Access().CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl);
+  Access().CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr,
+                                     Best->FoundDecl);
 
   // We found an overloaded operator(). Build a CXXOperatorCallExpr
   // that calls this method, using Object for the implicit object

>From cb11cc60400e57324fd40ee0065038c0b0587f95 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 00:52:27 +0300
Subject: [PATCH 3/3] Fix table of contents in `Sema`

---
 clang/include/clang/Sema/Sema.h | 63 ++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 32 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0bbc20d1766e5..4b0cac3b15331 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -452,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



More information about the cfe-commits mailing list