Skip to content

Commit 6b35cbe

Browse files
authored
[clang] Introduce SemaSYCL (#88086)
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.
1 parent 50d368a commit 6b35cbe

File tree

7 files changed

+121
-88
lines changed

7 files changed

+121
-88
lines changed

clang/include/clang/Sema/Sema.h

+7-48
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class PseudoObjectExpr;
184184
class QualType;
185185
class SemaHLSL;
186186
class SemaOpenACC;
187+
class SemaSYCL;
187188
class StandardConversionSequence;
188189
class Stmt;
189190
class StringLiteral;
@@ -467,7 +468,6 @@ class Sema final : public SemaBase {
467468
// 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp)
468469
// 38. CUDA (SemaCUDA.cpp)
469470
// 39. OpenMP Directives and Clauses (SemaOpenMP.cpp)
470-
// 40. SYCL Constructs (SemaSYCL.cpp)
471471

472472
/// \name Semantic Analysis
473473
/// Implementations are in Sema.cpp
@@ -974,6 +974,11 @@ class Sema final : public SemaBase {
974974
return *OpenACCPtr;
975975
}
976976

977+
SemaSYCL &SYCL() {
978+
assert(SYCLPtr);
979+
return *SYCLPtr;
980+
}
981+
977982
protected:
978983
friend class Parser;
979984
friend class InitializationSequence;
@@ -1006,6 +1011,7 @@ class Sema final : public SemaBase {
10061011

10071012
std::unique_ptr<SemaHLSL> HLSLPtr;
10081013
std::unique_ptr<SemaOpenACC> OpenACCPtr;
1014+
std::unique_ptr<SemaSYCL> SYCLPtr;
10091015

10101016
///@}
10111017

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

5458-
ExprResult BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
5459-
SourceLocation LParen,
5460-
SourceLocation RParen,
5461-
TypeSourceInfo *TSI);
5462-
ExprResult ActOnSYCLUniqueStableNameExpr(SourceLocation OpLoc,
5463-
SourceLocation LParen,
5464-
SourceLocation RParen,
5465-
ParsedType ParsedTy);
5466-
54675464
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
54685465

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

1451814515
///@}
14519-
14520-
//
14521-
//
14522-
// -------------------------------------------------------------------------
14523-
//
14524-
//
14525-
14526-
/// \name SYCL Constructs
14527-
/// Implementations are in SemaSYCL.cpp
14528-
///@{
14529-
14530-
public:
14531-
/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
14532-
/// context is "used as device code".
14533-
///
14534-
/// - If CurLexicalContext is a kernel function or it is known that the
14535-
/// function will be emitted for the device, emits the diagnostics
14536-
/// immediately.
14537-
/// - If CurLexicalContext is a function and we are compiling
14538-
/// for the device, but we don't know that this function will be codegen'ed
14539-
/// for devive yet, creates a diagnostic which is emitted if and when we
14540-
/// realize that the function will be codegen'ed.
14541-
///
14542-
/// Example usage:
14543-
///
14544-
/// Diagnose __float128 type usage only from SYCL device code if the current
14545-
/// target doesn't support it
14546-
/// if (!S.Context.getTargetInfo().hasFloat128Type() &&
14547-
/// S.getLangOpts().SYCLIsDevice)
14548-
/// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128";
14549-
SemaDiagnosticBuilder SYCLDiagIfDeviceCode(SourceLocation Loc,
14550-
unsigned DiagID);
14551-
14552-
void deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
14553-
llvm::DenseSet<QualType> Visited,
14554-
ValueDecl *DeclToCheck);
14555-
14556-
///@}
1455714516
};
1455814517

1455914518
DeductionFailureInfo

clang/include/clang/Sema/SemaSYCL.h

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===----- SemaSYCL.h ------- Semantic Analysis for SYCL constructs -------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
/// This file declares semantic analysis for SYCL constructs.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_SEMA_SEMASYCL_H
14+
#define LLVM_CLANG_SEMA_SEMASYCL_H
15+
16+
#include "clang/AST/Decl.h"
17+
#include "clang/AST/Type.h"
18+
#include "clang/Basic/SourceLocation.h"
19+
#include "clang/Sema/Ownership.h"
20+
#include "clang/Sema/SemaBase.h"
21+
#include "llvm/ADT/DenseSet.h"
22+
23+
namespace clang {
24+
25+
class SemaSYCL : public SemaBase {
26+
public:
27+
SemaSYCL(Sema &S);
28+
29+
/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
30+
/// context is "used as device code".
31+
///
32+
/// - If CurLexicalContext is a kernel function or it is known that the
33+
/// function will be emitted for the device, emits the diagnostics
34+
/// immediately.
35+
/// - If CurLexicalContext is a function and we are compiling
36+
/// for the device, but we don't know yet that this function will be
37+
/// codegen'ed for the devive, creates a diagnostic which is emitted if and
38+
/// when we realize that the function will be codegen'ed.
39+
///
40+
/// Example usage:
41+
///
42+
/// Diagnose __float128 type usage only from SYCL device code if the current
43+
/// target doesn't support it
44+
/// if (!S.Context.getTargetInfo().hasFloat128Type() &&
45+
/// S.getLangOpts().SYCLIsDevice)
46+
/// DiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128";
47+
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);
48+
49+
void deepTypeCheckForDevice(SourceLocation UsedAt,
50+
llvm::DenseSet<QualType> Visited,
51+
ValueDecl *DeclToCheck);
52+
53+
ExprResult BuildUniqueStableNameExpr(SourceLocation OpLoc,
54+
SourceLocation LParen,
55+
SourceLocation RParen,
56+
TypeSourceInfo *TSI);
57+
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
58+
SourceLocation LParen,
59+
SourceLocation RParen,
60+
ParsedType ParsedTy);
61+
};
62+
63+
} // namespace clang
64+
65+
#endif // LLVM_CLANG_SEMA_SEMASYCL_H

clang/lib/Parse/ParseExpr.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "clang/Sema/EnterExpressionEvaluationContext.h"
3131
#include "clang/Sema/ParsedTemplate.h"
3232
#include "clang/Sema/Scope.h"
33+
#include "clang/Sema/SemaSYCL.h"
3334
#include "clang/Sema/TypoCorrection.h"
3435
#include "llvm/ADT/SmallVector.h"
3536
#include <optional>
@@ -2490,8 +2491,8 @@ ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
24902491
if (T.consumeClose())
24912492
return ExprError();
24922493

2493-
return Actions.ActOnSYCLUniqueStableNameExpr(OpLoc, T.getOpenLocation(),
2494-
T.getCloseLocation(), Ty.get());
2494+
return Actions.SYCL().ActOnUniqueStableNameExpr(
2495+
OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get());
24952496
}
24962497

24972498
/// Parse a sizeof or alignof expression.

clang/lib/Sema/Sema.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "clang/Sema/SemaHLSL.h"
4646
#include "clang/Sema/SemaInternal.h"
4747
#include "clang/Sema/SemaOpenACC.h"
48+
#include "clang/Sema/SemaSYCL.h"
4849
#include "clang/Sema/TemplateDeduction.h"
4950
#include "clang/Sema/TemplateInstCallback.h"
5051
#include "clang/Sema/TypoCorrection.h"
@@ -201,6 +202,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
201202
CurScope(nullptr), Ident_super(nullptr),
202203
HLSLPtr(std::make_unique<SemaHLSL>(*this)),
203204
OpenACCPtr(std::make_unique<SemaOpenACC>(*this)),
205+
SYCLPtr(std::make_unique<SemaSYCL>(*this)),
204206
MSPointerToMemberRepresentationMethod(
205207
LangOpts.getMSPointerToMemberRepresentationMethod()),
206208
MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()),
@@ -1903,7 +1905,7 @@ Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
19031905
: CUDADiagIfHostCode(Loc, DiagID);
19041906

19051907
if (getLangOpts().SYCLIsDevice)
1906-
return SYCLDiagIfDeviceCode(Loc, DiagID);
1908+
return SYCL().DiagIfDeviceCode(Loc, DiagID);
19071909

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

19251927
Decl *C = cast<Decl>(getCurLexicalContext());

clang/lib/Sema/SemaExpr.cpp

-22
Original file line numberDiff line numberDiff line change
@@ -3794,28 +3794,6 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
37943794
SL);
37953795
}
37963796

3797-
ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
3798-
SourceLocation LParen,
3799-
SourceLocation RParen,
3800-
TypeSourceInfo *TSI) {
3801-
return SYCLUniqueStableNameExpr::Create(Context, OpLoc, LParen, RParen, TSI);
3802-
}
3803-
3804-
ExprResult Sema::ActOnSYCLUniqueStableNameExpr(SourceLocation OpLoc,
3805-
SourceLocation LParen,
3806-
SourceLocation RParen,
3807-
ParsedType ParsedTy) {
3808-
TypeSourceInfo *TSI = nullptr;
3809-
QualType Ty = GetTypeFromParser(ParsedTy, &TSI);
3810-
3811-
if (Ty.isNull())
3812-
return ExprError();
3813-
if (!TSI)
3814-
TSI = Context.getTrivialTypeSourceInfo(Ty, LParen);
3815-
3816-
return BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
3817-
}
3818-
38193797
ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
38203798
return BuildPredefinedExpr(Loc, getPredefinedExprKind(Kind));
38213799
}

clang/lib/Sema/SemaSYCL.cpp

+39-13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// This implements Semantic Analysis for SYCL constructs.
99
//===----------------------------------------------------------------------===//
1010

11+
#include "clang/Sema/SemaSYCL.h"
1112
#include "clang/AST/Mangle.h"
1213
#include "clang/Sema/Sema.h"
1314
#include "clang/Sema/SemaDiagnostic.h"
@@ -18,28 +19,30 @@ using namespace clang;
1819
// SYCL device specific diagnostics implementation
1920
// -----------------------------------------------------------------------------
2021

21-
Sema::SemaDiagnosticBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc,
22+
SemaSYCL::SemaSYCL(Sema &S) : SemaBase(S) {}
23+
24+
Sema::SemaDiagnosticBuilder SemaSYCL::DiagIfDeviceCode(SourceLocation Loc,
2225
unsigned DiagID) {
2326
assert(getLangOpts().SYCLIsDevice &&
2427
"Should only be called during SYCL compilation");
25-
FunctionDecl *FD = dyn_cast<FunctionDecl>(getCurLexicalContext());
28+
FunctionDecl *FD = dyn_cast<FunctionDecl>(SemaRef.getCurLexicalContext());
2629
SemaDiagnosticBuilder::Kind DiagKind = [this, FD] {
2730
if (!FD)
2831
return SemaDiagnosticBuilder::K_Nop;
29-
if (getEmissionStatus(FD) == Sema::FunctionEmissionStatus::Emitted)
32+
if (SemaRef.getEmissionStatus(FD) == Sema::FunctionEmissionStatus::Emitted)
3033
return SemaDiagnosticBuilder::K_ImmediateWithCallStack;
3134
return SemaDiagnosticBuilder::K_Deferred;
3235
}();
33-
return SemaDiagnosticBuilder(DiagKind, Loc, DiagID, FD, *this);
36+
return SemaDiagnosticBuilder(DiagKind, Loc, DiagID, FD, SemaRef);
3437
}
3538

36-
static bool isZeroSizedArray(Sema &SemaRef, QualType Ty) {
37-
if (const auto *CAT = SemaRef.getASTContext().getAsConstantArrayType(Ty))
39+
static bool isZeroSizedArray(SemaSYCL &S, QualType Ty) {
40+
if (const auto *CAT = S.getASTContext().getAsConstantArrayType(Ty))
3841
return CAT->isZeroSize();
3942
return false;
4043
}
4144

42-
void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
45+
void SemaSYCL::deepTypeCheckForDevice(SourceLocation UsedAt,
4346
llvm::DenseSet<QualType> Visited,
4447
ValueDecl *DeclToCheck) {
4548
assert(getLangOpts().SYCLIsDevice &&
@@ -51,18 +54,18 @@ void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
5154
auto Check = [&](QualType TypeToCheck, const ValueDecl *D) {
5255
bool ErrorFound = false;
5356
if (isZeroSizedArray(*this, TypeToCheck)) {
54-
SYCLDiagIfDeviceCode(UsedAt, diag::err_typecheck_zero_array_size) << 1;
57+
DiagIfDeviceCode(UsedAt, diag::err_typecheck_zero_array_size) << 1;
5558
ErrorFound = true;
5659
}
5760
// Checks for other types can also be done here.
5861
if (ErrorFound) {
5962
if (NeedToEmitNotes) {
6063
if (auto *FD = dyn_cast<FieldDecl>(D))
61-
SYCLDiagIfDeviceCode(FD->getLocation(),
62-
diag::note_illegal_field_declared_here)
64+
DiagIfDeviceCode(FD->getLocation(),
65+
diag::note_illegal_field_declared_here)
6366
<< FD->getType()->isPointerType() << FD->getType();
6467
else
65-
SYCLDiagIfDeviceCode(D->getLocation(), diag::note_declared_at);
68+
DiagIfDeviceCode(D->getLocation(), diag::note_declared_at);
6669
}
6770
}
6871

@@ -93,8 +96,8 @@ void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
9396
auto EmitHistory = [&]() {
9497
// The first element is always nullptr.
9598
for (uint64_t Index = 1; Index < History.size(); ++Index) {
96-
SYCLDiagIfDeviceCode(History[Index]->getLocation(),
97-
diag::note_within_field_of_type)
99+
DiagIfDeviceCode(History[Index]->getLocation(),
100+
diag::note_within_field_of_type)
98101
<< History[Index]->getType();
99102
}
100103
};
@@ -130,3 +133,26 @@ void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
130133
}
131134
} while (!StackForRecursion.empty());
132135
}
136+
137+
ExprResult SemaSYCL::BuildUniqueStableNameExpr(SourceLocation OpLoc,
138+
SourceLocation LParen,
139+
SourceLocation RParen,
140+
TypeSourceInfo *TSI) {
141+
return SYCLUniqueStableNameExpr::Create(getASTContext(), OpLoc, LParen,
142+
RParen, TSI);
143+
}
144+
145+
ExprResult SemaSYCL::ActOnUniqueStableNameExpr(SourceLocation OpLoc,
146+
SourceLocation LParen,
147+
SourceLocation RParen,
148+
ParsedType ParsedTy) {
149+
TypeSourceInfo *TSI = nullptr;
150+
QualType Ty = SemaRef.GetTypeFromParser(ParsedTy, &TSI);
151+
152+
if (Ty.isNull())
153+
return ExprError();
154+
if (!TSI)
155+
TSI = getASTContext().getTrivialTypeSourceInfo(Ty, LParen);
156+
157+
return BuildUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
158+
}

clang/lib/Sema/TreeTransform.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "clang/Sema/SemaDiagnostic.h"
4141
#include "clang/Sema/SemaInternal.h"
4242
#include "clang/Sema/SemaOpenACC.h"
43+
#include "clang/Sema/SemaSYCL.h"
4344
#include "llvm/ADT/ArrayRef.h"
4445
#include "llvm/Support/ErrorHandling.h"
4546
#include <algorithm>
@@ -2632,7 +2633,8 @@ class TreeTransform {
26322633
SourceLocation LParen,
26332634
SourceLocation RParen,
26342635
TypeSourceInfo *TSI) {
2635-
return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
2636+
return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2637+
TSI);
26362638
}
26372639

26382640
/// Build a new predefined expression.

0 commit comments

Comments
 (0)