Skip to content

Commit

Permalink
[clang] Introduce SemaSYCL (#88086)
Browse files Browse the repository at this point in the history
This patch moves SYCL-related `Sema` functions into new `SemaSYCL`
class, following the recent example of OpenACC and HLSL. This is a part
of the effort to split `Sema`. Additional context can be found in
#82217, #84184, #87634.
  • Loading branch information
Endilll committed Apr 10, 2024
1 parent 50d368a commit 6b35cbe
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 88 deletions.
55 changes: 7 additions & 48 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class PseudoObjectExpr;
class QualType;
class SemaHLSL;
class SemaOpenACC;
class SemaSYCL;
class StandardConversionSequence;
class Stmt;
class StringLiteral;
Expand Down Expand Up @@ -467,7 +468,6 @@ class Sema final : public SemaBase {
// 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp)
// 38. CUDA (SemaCUDA.cpp)
// 39. OpenMP Directives and Clauses (SemaOpenMP.cpp)
// 40. SYCL Constructs (SemaSYCL.cpp)

/// \name Semantic Analysis
/// Implementations are in Sema.cpp
Expand Down Expand Up @@ -974,6 +974,11 @@ class Sema final : public SemaBase {
return *OpenACCPtr;
}

SemaSYCL &SYCL() {
assert(SYCLPtr);
return *SYCLPtr;
}

protected:
friend class Parser;
friend class InitializationSequence;
Expand Down Expand Up @@ -1006,6 +1011,7 @@ class Sema final : public SemaBase {

std::unique_ptr<SemaHLSL> HLSLPtr;
std::unique_ptr<SemaOpenACC> OpenACCPtr;
std::unique_ptr<SemaSYCL> SYCLPtr;

///@}

Expand Down Expand Up @@ -5455,15 +5461,6 @@ class Sema final : public SemaBase {
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);

ExprResult BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
TypeSourceInfo *TSI);
ExprResult ActOnSYCLUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
ParsedType ParsedTy);

bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);

ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
Expand Down Expand Up @@ -14516,44 +14513,6 @@ class Sema final : public SemaBase {
OpenMPDirectiveKind CancelRegion);

///@}

//
//
// -------------------------------------------------------------------------
//
//

/// \name SYCL Constructs
/// Implementations are in SemaSYCL.cpp
///@{

public:
/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
/// context is "used as device code".
///
/// - If CurLexicalContext is a kernel function or it is known that the
/// function will be emitted for the device, emits the diagnostics
/// immediately.
/// - If CurLexicalContext is a function and we are compiling
/// for the device, but we don't know that this function will be codegen'ed
/// for devive yet, creates a diagnostic which is emitted if and when we
/// realize that the function will be codegen'ed.
///
/// Example usage:
///
/// Diagnose __float128 type usage only from SYCL device code if the current
/// target doesn't support it
/// if (!S.Context.getTargetInfo().hasFloat128Type() &&
/// S.getLangOpts().SYCLIsDevice)
/// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128";
SemaDiagnosticBuilder SYCLDiagIfDeviceCode(SourceLocation Loc,
unsigned DiagID);

void deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
llvm::DenseSet<QualType> Visited,
ValueDecl *DeclToCheck);

///@}
};

DeductionFailureInfo
Expand Down
65 changes: 65 additions & 0 deletions clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//===----- SemaSYCL.h ------- Semantic Analysis for SYCL constructs -------===//
//
// 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 semantic analysis for SYCL constructs.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMASYCL_H
#define LLVM_CLANG_SEMA_SEMASYCL_H

#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseSet.h"

namespace clang {

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

/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
/// context is "used as device code".
///
/// - If CurLexicalContext is a kernel function or it is known that the
/// function will be emitted for the device, emits the diagnostics
/// immediately.
/// - If CurLexicalContext is a function and we are compiling
/// for the device, but we don't know yet that this function will be
/// codegen'ed for the devive, creates a diagnostic which is emitted if and
/// when we realize that the function will be codegen'ed.
///
/// Example usage:
///
/// Diagnose __float128 type usage only from SYCL device code if the current
/// target doesn't support it
/// if (!S.Context.getTargetInfo().hasFloat128Type() &&
/// S.getLangOpts().SYCLIsDevice)
/// DiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128";
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);

void deepTypeCheckForDevice(SourceLocation UsedAt,
llvm::DenseSet<QualType> Visited,
ValueDecl *DeclToCheck);

ExprResult BuildUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
TypeSourceInfo *TSI);
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
ParsedType ParsedTy);
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMASYCL_H
5 changes: 3 additions & 2 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaSYCL.h"
#include "clang/Sema/TypoCorrection.h"
#include "llvm/ADT/SmallVector.h"
#include <optional>
Expand Down Expand Up @@ -2490,8 +2491,8 @@ ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
if (T.consumeClose())
return ExprError();

return Actions.ActOnSYCLUniqueStableNameExpr(OpLoc, T.getOpenLocation(),
T.getCloseLocation(), Ty.get());
return Actions.SYCL().ActOnUniqueStableNameExpr(
OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get());
}

/// Parse a sizeof or alignof expression.
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/SemaSYCL.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "clang/Sema/TypoCorrection.h"
Expand Down Expand Up @@ -201,6 +202,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
CurScope(nullptr), Ident_super(nullptr),
HLSLPtr(std::make_unique<SemaHLSL>(*this)),
OpenACCPtr(std::make_unique<SemaOpenACC>(*this)),
SYCLPtr(std::make_unique<SemaSYCL>(*this)),
MSPointerToMemberRepresentationMethod(
LangOpts.getMSPointerToMemberRepresentationMethod()),
MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()),
Expand Down Expand Up @@ -1903,7 +1905,7 @@ Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
: CUDADiagIfHostCode(Loc, DiagID);

if (getLangOpts().SYCLIsDevice)
return SYCLDiagIfDeviceCode(Loc, DiagID);
return SYCL().DiagIfDeviceCode(Loc, DiagID);

return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc, DiagID,
FD, *this);
Expand All @@ -1919,7 +1921,7 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
// constant byte size like zero length arrays. So, do a deep check for SYCL.
if (D && LangOpts.SYCLIsDevice) {
llvm::DenseSet<QualType> Visited;
deepTypeCheckForSYCLDevice(Loc, Visited, D);
SYCL().deepTypeCheckForDevice(Loc, Visited, D);
}

Decl *C = cast<Decl>(getCurLexicalContext());
Expand Down
22 changes: 0 additions & 22 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3794,28 +3794,6 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
SL);
}

ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
TypeSourceInfo *TSI) {
return SYCLUniqueStableNameExpr::Create(Context, OpLoc, LParen, RParen, TSI);
}

ExprResult Sema::ActOnSYCLUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
ParsedType ParsedTy) {
TypeSourceInfo *TSI = nullptr;
QualType Ty = GetTypeFromParser(ParsedTy, &TSI);

if (Ty.isNull())
return ExprError();
if (!TSI)
TSI = Context.getTrivialTypeSourceInfo(Ty, LParen);

return BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
}

ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
return BuildPredefinedExpr(Loc, getPredefinedExprKind(Kind));
}
Expand Down
52 changes: 39 additions & 13 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// This implements Semantic Analysis for SYCL constructs.
//===----------------------------------------------------------------------===//

#include "clang/Sema/SemaSYCL.h"
#include "clang/AST/Mangle.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
Expand All @@ -18,28 +19,30 @@ using namespace clang;
// SYCL device specific diagnostics implementation
// -----------------------------------------------------------------------------

Sema::SemaDiagnosticBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc,
SemaSYCL::SemaSYCL(Sema &S) : SemaBase(S) {}

Sema::SemaDiagnosticBuilder SemaSYCL::DiagIfDeviceCode(SourceLocation Loc,
unsigned DiagID) {
assert(getLangOpts().SYCLIsDevice &&
"Should only be called during SYCL compilation");
FunctionDecl *FD = dyn_cast<FunctionDecl>(getCurLexicalContext());
FunctionDecl *FD = dyn_cast<FunctionDecl>(SemaRef.getCurLexicalContext());
SemaDiagnosticBuilder::Kind DiagKind = [this, FD] {
if (!FD)
return SemaDiagnosticBuilder::K_Nop;
if (getEmissionStatus(FD) == Sema::FunctionEmissionStatus::Emitted)
if (SemaRef.getEmissionStatus(FD) == Sema::FunctionEmissionStatus::Emitted)
return SemaDiagnosticBuilder::K_ImmediateWithCallStack;
return SemaDiagnosticBuilder::K_Deferred;
}();
return SemaDiagnosticBuilder(DiagKind, Loc, DiagID, FD, *this);
return SemaDiagnosticBuilder(DiagKind, Loc, DiagID, FD, SemaRef);
}

static bool isZeroSizedArray(Sema &SemaRef, QualType Ty) {
if (const auto *CAT = SemaRef.getASTContext().getAsConstantArrayType(Ty))
static bool isZeroSizedArray(SemaSYCL &S, QualType Ty) {
if (const auto *CAT = S.getASTContext().getAsConstantArrayType(Ty))
return CAT->isZeroSize();
return false;
}

void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
void SemaSYCL::deepTypeCheckForDevice(SourceLocation UsedAt,
llvm::DenseSet<QualType> Visited,
ValueDecl *DeclToCheck) {
assert(getLangOpts().SYCLIsDevice &&
Expand All @@ -51,18 +54,18 @@ void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
auto Check = [&](QualType TypeToCheck, const ValueDecl *D) {
bool ErrorFound = false;
if (isZeroSizedArray(*this, TypeToCheck)) {
SYCLDiagIfDeviceCode(UsedAt, diag::err_typecheck_zero_array_size) << 1;
DiagIfDeviceCode(UsedAt, diag::err_typecheck_zero_array_size) << 1;
ErrorFound = true;
}
// Checks for other types can also be done here.
if (ErrorFound) {
if (NeedToEmitNotes) {
if (auto *FD = dyn_cast<FieldDecl>(D))
SYCLDiagIfDeviceCode(FD->getLocation(),
diag::note_illegal_field_declared_here)
DiagIfDeviceCode(FD->getLocation(),
diag::note_illegal_field_declared_here)
<< FD->getType()->isPointerType() << FD->getType();
else
SYCLDiagIfDeviceCode(D->getLocation(), diag::note_declared_at);
DiagIfDeviceCode(D->getLocation(), diag::note_declared_at);
}
}

Expand Down Expand Up @@ -93,8 +96,8 @@ void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
auto EmitHistory = [&]() {
// The first element is always nullptr.
for (uint64_t Index = 1; Index < History.size(); ++Index) {
SYCLDiagIfDeviceCode(History[Index]->getLocation(),
diag::note_within_field_of_type)
DiagIfDeviceCode(History[Index]->getLocation(),
diag::note_within_field_of_type)
<< History[Index]->getType();
}
};
Expand Down Expand Up @@ -130,3 +133,26 @@ void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
}
} while (!StackForRecursion.empty());
}

ExprResult SemaSYCL::BuildUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
TypeSourceInfo *TSI) {
return SYCLUniqueStableNameExpr::Create(getASTContext(), OpLoc, LParen,
RParen, TSI);
}

ExprResult SemaSYCL::ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
ParsedType ParsedTy) {
TypeSourceInfo *TSI = nullptr;
QualType Ty = SemaRef.GetTypeFromParser(ParsedTy, &TSI);

if (Ty.isNull())
return ExprError();
if (!TSI)
TSI = getASTContext().getTrivialTypeSourceInfo(Ty, LParen);

return BuildUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
}
4 changes: 3 additions & 1 deletion clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/SemaSYCL.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
Expand Down Expand Up @@ -2632,7 +2633,8 @@ class TreeTransform {
SourceLocation LParen,
SourceLocation RParen,
TypeSourceInfo *TSI) {
return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
TSI);
}

/// Build a new predefined expression.
Expand Down

0 comments on commit 6b35cbe

Please sign in to comment.