Skip to content

Commit bea9b4d

Browse files
author
iclsrc
committed
Merge from 'sycl' to 'sycl-web' (#2)
2 parents 3a65b4c + b80f13e commit bea9b4d

12 files changed

+225
-224
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

+8-5
Original file line numberDiff line numberDiff line change
@@ -11220,12 +11220,15 @@ def err_esimd_glob_cant_init : Error<
1122011220
def err_esimd_global_in_sycl_context : Error<
1122111221
"ESIMD globals cannot be used in a SYCL context">;
1122211222

11223-
def err_sycl_kernel_incorrectly_named : Error<"%0 is an invalid kernel name type">;
11224-
def note_invalid_type_in_sycl_kernel : Note<
11225-
"%select{%1 should be globally-visible"
11223+
def err_nullptr_t_type_in_sycl_kernel : Error<"%0 is an invalid kernel name, "
11224+
"'std::nullptr_t' is declared in the 'std' namespace ">;
11225+
def err_invalid_std_type_in_sycl_kernel : Error<"%0 is an invalid kernel name, "
11226+
"%q1 is declared in the 'std' namespace ">;
11227+
11228+
def err_sycl_kernel_incorrectly_named : Error<
11229+
"%select{%1 should be globally visible"
1122611230
"|unscoped enum %1 requires fixed underlying type"
11227-
"|type %1 cannot be in the \"std\" namespace"
11228-
"|unnamed type used in a SYCL kernel name"
11231+
"|unnamed lambda %1 used"
1122911232
"}0">;
1123011233

1123111234
def err_sycl_kernel_not_function_object

clang/lib/Sema/SemaSYCL.cpp

+89-54
Original file line numberDiff line numberDiff line change
@@ -3130,21 +3130,14 @@ class SYCLKernelNameTypeVisitor
31303130
void Visit(QualType T) {
31313131
if (T.isNull())
31323132
return;
3133+
31333134
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
3134-
if (!RD) {
3135-
if (T->isNullPtrType()) {
3136-
S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named)
3137-
<< KernelNameType;
3138-
S.Diag(KernelInvocationFuncLoc, diag::note_invalid_type_in_sycl_kernel)
3139-
<< /* kernel name cannot be a type in the std namespace */ 2 << T;
3140-
IsInvalid = true;
3141-
}
3142-
return;
3143-
}
31443135
// If KernelNameType has template args visit each template arg via
31453136
// ConstTemplateArgumentVisitor
3146-
if (const auto *TSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
3137+
if (const auto *TSD =
3138+
dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) {
31473139
ArrayRef<TemplateArgument> Args = TSD->getTemplateArgs().asArray();
3140+
31483141
VisitTemplateArgs(Args);
31493142
} else {
31503143
InnerTypeVisitor::Visit(T.getTypePtr());
@@ -3157,62 +3150,104 @@ class SYCLKernelNameTypeVisitor
31573150
InnerTemplArgVisitor::Visit(TA);
31583151
}
31593152

3160-
void VisitEnumType(const EnumType *T) {
3161-
const EnumDecl *ED = T->getDecl();
3162-
if (!ED->isScoped() && !ED->isFixed()) {
3163-
S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named)
3153+
void VisitBuiltinType(const BuiltinType *TT) {
3154+
if (TT->isNullPtrType()) {
3155+
S.Diag(KernelInvocationFuncLoc, diag::err_nullptr_t_type_in_sycl_kernel)
31643156
<< KernelNameType;
3165-
S.Diag(KernelInvocationFuncLoc, diag::note_invalid_type_in_sycl_kernel)
3166-
<< /* Unscoped enum requires fixed underlying type */ 1
3167-
<< QualType(ED->getTypeForDecl(), 0);
3157+
31683158
IsInvalid = true;
31693159
}
3160+
return;
31703161
}
31713162

3172-
void VisitRecordType(const RecordType *T) {
3173-
return VisitTagDecl(T->getDecl());
3174-
}
3163+
void VisitTagType(const TagType *TT) {
3164+
return DiagnoseKernelNameType(TT->getDecl());
3165+
}
3166+
3167+
void DiagnoseKernelNameType(const NamedDecl *DeclNamed) {
3168+
/*
3169+
This is a helper function which throws an error if the kernel name
3170+
declaration is:
3171+
* declared within namespace 'std' (at any level)
3172+
e.g., namespace std { namespace literals { class Whatever; } }
3173+
h.single_task<std::literals::Whatever>([]() {});
3174+
* declared within an anonymous namespace (at any level)
3175+
e.g., namespace foo { namespace { class Whatever; } }
3176+
h.single_task<foo::Whatever>([]() {});
3177+
* declared within a function
3178+
e.g., void foo() { struct S { int i; };
3179+
h.single_task<S>([]() {}); }
3180+
* declared within another tag
3181+
e.g., struct S { struct T { int i } t; };
3182+
h.single_task<S::T>([]() {});
3183+
*/
3184+
3185+
if (const auto *ED = dyn_cast<EnumDecl>(DeclNamed)) {
3186+
if (!ED->isScoped() && !ED->isFixed()) {
3187+
S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named)
3188+
<< /* unscoped enum requires fixed underlying type */ 1
3189+
<< DeclNamed;
3190+
IsInvalid = true;
3191+
}
3192+
}
31753193

3176-
void VisitTagDecl(const TagDecl *Tag) {
31773194
bool UnnamedLambdaEnabled =
31783195
S.getASTContext().getLangOpts().SYCLUnnamedLambda;
3179-
const DeclContext *DeclCtx = Tag->getDeclContext();
3196+
const DeclContext *DeclCtx = DeclNamed->getDeclContext();
31803197
if (DeclCtx && !UnnamedLambdaEnabled) {
3181-
auto *NameSpace = dyn_cast_or_null<NamespaceDecl>(DeclCtx);
3182-
if (NameSpace && NameSpace->isStdNamespace()) {
3183-
S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named)
3184-
<< KernelNameType;
3185-
S.Diag(KernelInvocationFuncLoc, diag::note_invalid_type_in_sycl_kernel)
3186-
<< /* kernel name cannot be a type in the std namespace */ 2
3187-
<< QualType(Tag->getTypeForDecl(), 0);
3188-
IsInvalid = true;
3189-
return;
3190-
}
3191-
if (!DeclCtx->isTranslationUnit() && !isa<NamespaceDecl>(DeclCtx)) {
3192-
const bool KernelNameIsMissing = Tag->getName().empty();
3193-
if (KernelNameIsMissing) {
3194-
S.Diag(KernelInvocationFuncLoc,
3195-
diag::err_sycl_kernel_incorrectly_named)
3196-
<< KernelNameType;
3198+
3199+
// Check if the kernel name declaration is declared within namespace
3200+
// "std" or "anonymous" namespace (at any level).
3201+
while (!DeclCtx->isTranslationUnit() && isa<NamespaceDecl>(DeclCtx)) {
3202+
const auto *NSDecl = cast<NamespaceDecl>(DeclCtx);
3203+
if (NSDecl->isStdNamespace()) {
31973204
S.Diag(KernelInvocationFuncLoc,
3198-
diag::note_invalid_type_in_sycl_kernel)
3199-
<< /* unnamed type used in a SYCL kernel name */ 3;
3205+
diag::err_invalid_std_type_in_sycl_kernel)
3206+
<< KernelNameType << DeclNamed;
32003207
IsInvalid = true;
32013208
return;
32023209
}
3203-
if (Tag->isCompleteDefinition()) {
3210+
if (NSDecl->isAnonymousNamespace()) {
32043211
S.Diag(KernelInvocationFuncLoc,
32053212
diag::err_sycl_kernel_incorrectly_named)
3213+
<< /* kernel name should be globally visible */ 0
32063214
<< KernelNameType;
3207-
S.Diag(KernelInvocationFuncLoc,
3208-
diag::note_invalid_type_in_sycl_kernel)
3209-
<< /* kernel name is not globally-visible */ 0
3210-
<< QualType(Tag->getTypeForDecl(), 0);
32113215
IsInvalid = true;
3212-
} else {
3213-
S.Diag(KernelInvocationFuncLoc, diag::warn_sycl_implicit_decl);
3214-
S.Diag(Tag->getSourceRange().getBegin(), diag::note_previous_decl)
3215-
<< Tag->getName();
3216+
return;
3217+
}
3218+
DeclCtx = DeclCtx->getParent();
3219+
}
3220+
3221+
// Check if the kernel name is a Tag declaration
3222+
// local to a non-namespace scope (i.e. Inside a function or within
3223+
// another Tag etc).
3224+
if (!DeclCtx->isTranslationUnit() && !isa<NamespaceDecl>(DeclCtx)) {
3225+
if (const auto *Tag = dyn_cast<TagDecl>(DeclNamed)) {
3226+
bool UnnamedLambdaUsed = Tag->getIdentifier() == nullptr;
3227+
3228+
if (UnnamedLambdaUsed) {
3229+
S.Diag(KernelInvocationFuncLoc,
3230+
diag::err_sycl_kernel_incorrectly_named)
3231+
<< /* unnamed lambda used */ 2 << KernelNameType;
3232+
3233+
IsInvalid = true;
3234+
return;
3235+
}
3236+
// Check if the declaration is completely defined within a
3237+
// function or class/struct.
3238+
3239+
if (Tag->isCompleteDefinition()) {
3240+
S.Diag(KernelInvocationFuncLoc,
3241+
diag::err_sycl_kernel_incorrectly_named)
3242+
<< /* kernel name should be globally visible */ 0
3243+
<< KernelNameType;
3244+
3245+
IsInvalid = true;
3246+
} else {
3247+
S.Diag(KernelInvocationFuncLoc, diag::warn_sycl_implicit_decl);
3248+
S.Diag(DeclNamed->getLocation(), diag::note_previous_decl)
3249+
<< DeclNamed->getName();
3250+
}
32163251
}
32173252
}
32183253
}
@@ -3221,15 +3256,15 @@ class SYCLKernelNameTypeVisitor
32213256
void VisitTypeTemplateArgument(const TemplateArgument &TA) {
32223257
QualType T = TA.getAsType();
32233258
if (const auto *ET = T->getAs<EnumType>())
3224-
VisitEnumType(ET);
3259+
VisitTagType(ET);
32253260
else
32263261
Visit(T);
32273262
}
32283263

32293264
void VisitIntegralTemplateArgument(const TemplateArgument &TA) {
32303265
QualType T = TA.getIntegralType();
32313266
if (const EnumType *ET = T->getAs<EnumType>())
3232-
VisitEnumType(ET);
3267+
VisitTagType(ET);
32333268
}
32343269

32353270
void VisitTemplateTemplateArgument(const TemplateArgument &TA) {
@@ -3240,7 +3275,7 @@ class SYCLKernelNameTypeVisitor
32403275
if (NonTypeTemplateParmDecl *TemplateParam =
32413276
dyn_cast<NonTypeTemplateParmDecl>(P))
32423277
if (const EnumType *ET = TemplateParam->getType()->getAs<EnumType>())
3243-
VisitEnumType(ET);
3278+
VisitTagType(ET);
32443279
}
32453280
}
32463281

@@ -3301,7 +3336,7 @@ void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc,
33013336

33023337
// Emit diagnostics for SYCL device kernels only
33033338
if (LangOpts.SYCLIsDevice)
3304-
KernelNameTypeVisitor.Visit(KernelNameType);
3339+
KernelNameTypeVisitor.Visit(KernelNameType.getCanonicalType());
33053340
Visitor.VisitRecordBases(KernelObj, FieldChecker, UnionChecker, DecompMarker);
33063341
Visitor.VisitRecordFields(KernelObj, FieldChecker, UnionChecker,
33073342
DecompMarker);

clang/test/CodeGenSYCL/int_header1.cpp

+2-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsycl-is-device -fsycl-int-header=%t.h %s -o %t.out
1+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -sycl-std=2020 -fsycl-int-header=%t.h %s -o %t.out
22
// RUN: FileCheck -input-file=%t.h %s
33

44
// CHECK:template <> struct KernelInfo<class KernelName> {
@@ -8,18 +8,15 @@
88
// CHECK:template <> struct KernelInfo<::nm1::KernelName3<::nm1::KernelName1>> {
99
// CHECK:template <> struct KernelInfo<::nm1::KernelName4<::nm1::nm2::KernelName0>> {
1010
// CHECK:template <> struct KernelInfo<::nm1::KernelName4<::nm1::KernelName1>> {
11-
// CHECK:template <> struct KernelInfo<::nm1::KernelName3<KernelName5>> {
12-
// CHECK:template <> struct KernelInfo<::nm1::KernelName4<KernelName7>> {
1311
// CHECK:template <> struct KernelInfo<::nm1::KernelName8<::nm1::nm2::C>> {
14-
// CHECK:template <> struct KernelInfo<::TmplClassInAnonNS<ClassInAnonNS>> {
1512
// CHECK:template <> struct KernelInfo<::nm1::KernelName9<char>> {
1613
// CHECK:template <> struct KernelInfo<::nm1::KernelName3<const volatile ::nm1::KernelName3<const volatile char>>> {
1714

1815
// This test checks if the SYCL device compiler is able to generate correct
1916
// integration header when the kernel name class is expressed in different
2017
// forms.
2118

22-
#include "Inputs/sycl.hpp"
19+
#include "sycl.hpp"
2320

2421
template <typename KernelName, typename KernelType>
2522
__attribute__((sycl_kernel)) void kernel_single_task(const KernelType &kernelFunc) {
@@ -110,29 +107,12 @@ struct MyWrapper {
110107
kernel_single_task<nm1::KernelName4<nm1::KernelName1>>(
111108
[=]() { acc.use(); });
112109

113-
// TIPI
114-
// an incomplete template specialization class with incomplete class as
115-
// argument forward-declared "in-place"
116-
kernel_single_task<nm1::KernelName3<class KernelName5>>(
117-
[=]() { acc.use(); });
118-
119-
// TDPI
120-
// a defined template specialization class with incomplete class as
121-
// argument forward-declared "in-place"
122-
kernel_single_task<nm1::KernelName4<class KernelName7>>(
123-
[=]() { acc.use(); });
124-
125110
// TPITD
126111
// a defined template pack specialization class with defined class
127112
// as argument declared in a namespace at translation unit scope
128113
kernel_single_task<nm1::KernelName8<nm1::nm2::C>>(
129114
[=]() { acc.use(); });
130115

131-
// kernel name type is a templated class, both the top-level class and the
132-
// template argument are declared in the anonymous namespace
133-
kernel_single_task<TmplClassInAnonNS<class ClassInAnonNS>>(
134-
[=]() { acc.use(); });
135-
136116
// Kernel name type is a templated specialization class with empty template pack argument
137117
kernel_single_task<nm1::KernelName9<char>>(
138118
[=]() { acc.use(); });

clang/test/CodeGenSYCL/integration_header.cpp

+1-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -fsycl-int-header=%t.h %s -emit-llvm -o %t.ll
1+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -sycl-std=2020 -fsycl-int-header=%t.h %s -emit-llvm -o %t.ll
22
// RUN: FileCheck -input-file=%t.h %s
33
//
44
// CHECK: #include <CL/sycl/detail/kernel_desc.hpp>
@@ -7,9 +7,6 @@
77
// CHECK-NEXT: namespace second_namespace {
88
// CHECK-NEXT: template <typename T> class second_kernel;
99
// CHECK-NEXT: }
10-
// CHECK-NEXT: struct X;
11-
// CHECK-NEXT: template <typename T> struct point;
12-
// CHECK-NEXT: template <int a, typename T1, typename T2> class third_kernel;
1310
// CHECK-NEXT: namespace template_arg_ns {
1411
// CHECK-NEXT: template <int DimX> struct namespaced_arg;
1512
// CHECK-NEXT: }
@@ -19,7 +16,6 @@
1916
// CHECK-NEXT: const char* const kernel_names[] = {
2017
// CHECK-NEXT: "_ZTSZ4mainE12first_kernel",
2118
// CHECK-NEXT: "_ZTSN16second_namespace13second_kernelIcEE",
22-
// CHECK-NEXT: "_ZTS12third_kernelILi1Ei5pointIZ4mainE1XEE"
2319
// CHECK-NEXT: "_ZTS13fourth_kernelIJN15template_arg_ns14namespaced_argILi1EEEEE"
2420
// CHECK-NEXT: "_ZTSZ4mainE16accessor_in_base"
2521
// CHECK-NEXT: };
@@ -38,11 +34,6 @@
3834
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 4 },
3935
// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 16 },
4036
// CHECK-EMPTY:
41-
// CHECK-NEXT: //--- _ZTS12third_kernelILi1Ei5pointIZ4mainE1XEE
42-
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 },
43-
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 4 },
44-
// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 16 },
45-
// CHECK-EMPTY:
4637
// CHECK-NEXT: //--- _ZTS13fourth_kernelIJN15template_arg_ns14namespaced_argILi1EEEEE
4738
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 },
4839
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 4 },
@@ -61,7 +52,6 @@
6152
//
6253
// CHECK: template <> struct KernelInfo<class first_kernel> {
6354
// CHECK: template <> struct KernelInfo<::second_namespace::second_kernel<char>> {
64-
// CHECK: template <> struct KernelInfo<::third_kernel<1, int, ::point<X>>> {
6555
// CHECK: template <> struct KernelInfo<::fourth_kernel<::template_arg_ns::namespaced_arg<1>>> {
6656

6757
#include "Inputs/sycl.hpp"
@@ -140,12 +130,6 @@ int main() {
140130
smplr.use();
141131
}
142132
});
143-
kernel_single_task<class third_kernel<1, int,point<struct X>>>([=]() {
144-
if (i == 13) {
145-
acc2.use();
146-
smplr.use();
147-
}
148-
});
149133

150134
kernel_single_task<class fourth_kernel<template_arg_ns::namespaced_arg<1>>>([=]() {
151135
if (i == 13) {

0 commit comments

Comments
 (0)