Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang] Introduce SemaAccess #92674

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/Lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -761,7 +762,7 @@ class LookupResult {
void diagnoseAccess() {
if (!isAmbiguous() && isClassLookup() &&
getSema().getLangOpts().AccessControl)
getSema().CheckLookupAccess(*this);
getSema().Access().CheckLookupAccess(*this);
}

void diagnoseAmbiguous() {
Expand Down
157 changes: 38 additions & 119 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ class Preprocessor;
class PseudoDestructorTypeStorage;
class PseudoObjectExpr;
class QualType;
class SemaAccess;
class SemaCodeCompletion;
class SemaCUDA;
class SemaHLSL;
Expand Down Expand Up @@ -452,39 +453,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
Expand Down Expand Up @@ -985,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;
Expand Down Expand Up @@ -1050,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;
Expand All @@ -1066,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
///@{
Expand Down
112 changes: 112 additions & 0 deletions clang/include/clang/Sema/SemaAccess.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//===----- SemaAccess.h --------- C++ Access Control ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// This file declares routines for C++ access control semantics.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMAACCESS_H
#define LLVM_CLANG_SEMA_SEMAACCESS_H

#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DependentDiagnostic.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/DelayedDiagnostic.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class LookupResult;
class MultiLevelTemplateArgumentList;

class SemaAccess : public SemaBase {
public:
SemaAccess(Sema &S);

enum AccessResult {
AR_accessible,
AR_inaccessible,
AR_dependent,
AR_delayed
};

bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
NamedDecl *PrevMemberDecl,
AccessSpecifier LexicalAS);

AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
DeclAccessPair FoundDecl);
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
DeclAccessPair FoundDecl);
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
SourceRange PlacementRange,
CXXRecordDecl *NamingClass,
DeclAccessPair FoundDecl,
bool Diagnose = true);
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D,
DeclAccessPair FoundDecl,
const InitializedEntity &Entity,
bool IsCopyBindingRefToTemp = false);
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D,
DeclAccessPair FoundDecl,
const InitializedEntity &Entity,
const PartialDiagnostic &PDiag);
AccessResult CheckDestructorAccess(SourceLocation Loc,
CXXDestructorDecl *Dtor,
const PartialDiagnostic &PDiag,
QualType objectType = QualType());
AccessResult CheckFriendAccess(NamedDecl *D);
AccessResult CheckMemberAccess(SourceLocation UseLoc,
CXXRecordDecl *NamingClass,
DeclAccessPair Found);
AccessResult
CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
CXXRecordDecl *DecomposedClass,
DeclAccessPair Field);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
const SourceRange &,
DeclAccessPair FoundDecl);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
Expr *ArgExpr,
DeclAccessPair FoundDecl);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
ArrayRef<Expr *> ArgExprs,
DeclAccessPair FoundDecl);
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
DeclAccessPair FoundDecl);
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base,
QualType Derived, const CXXBasePath &Path,
unsigned DiagID, bool ForceCheck = false,
bool ForceUnprivileged = false);
void CheckLookupAccess(const LookupResult &R);
bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass,
QualType BaseType);
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
DeclAccessPair Found, QualType ObjectType,
SourceLocation Loc,
const PartialDiagnostic &Diag);
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
DeclAccessPair Found, QualType ObjectType);

void HandleDependentAccessCheck(
const DependentDiagnostic &DD,
const MultiLevelTemplateArgumentList &TemplateArgs);
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
};
} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMAACCESS_H
2 changes: 2 additions & 0 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)),
Expand Down
Loading
Loading