Skip to content

Commit 45194f7

Browse files
idubinovbader
authored andcommitted
[SYCL] Add template template parameter support
Signed-off-by: idubinov <[email protected]>
1 parent 7e6d517 commit 45194f7

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,8 +1382,28 @@ void SYCLIntegrationHeader::emitForwardClassDecls(
13821382
}
13831383
break;
13841384
}
1385-
case TemplateArgument::ArgKind::Template:
1386-
llvm_unreachable("template template arguments not supported");
1385+
case TemplateArgument::ArgKind::Template: {
1386+
// recursion is not required, since the maximum possible nesting level
1387+
// equals two for template argument
1388+
//
1389+
// for example:
1390+
// template <typename T> class Bar;
1391+
// template <template <typename> class> class Baz;
1392+
// template <template <template <typename> class> class T>
1393+
// class Foo;
1394+
//
1395+
// The Baz is a template class. The Baz<Bar> is a class. The class Foo
1396+
// should be specialized with template class, not a class. The correct
1397+
// specialization of template class Foo is Foo<Baz>. The incorrect
1398+
// specialization of template class Foo is Foo<Baz<Bar>>. In this case
1399+
// template class Foo specialized by class Baz<Bar>, not a template
1400+
// class template <template <typename> class> class T as it should.
1401+
TemplateDecl *TD = Arg.getAsTemplate().getAsTemplateDecl();
1402+
if (Printed.insert(TD).second) {
1403+
emitFwdDecl(O, TD);
1404+
}
1405+
break;
1406+
}
13871407
default:
13881408
break; // nop
13891409
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// RUN: %clang -I %S/Inputs --sycl -Xclang -fsycl-int-header=%t.h %s
2+
// RUN: FileCheck -input-file=%t.h %s
3+
4+
#include <sycl.hpp>
5+
6+
using namespace cl::sycl;
7+
8+
template <typename T> class Foo1;
9+
// CHECK: template <typename T> class Foo1;
10+
template <template <typename> class TT> class KernelName1;
11+
// CHECK: template <template <typename> class TT> class KernelName1;
12+
template <template <typename> class TT> void enqueue() {
13+
queue q;
14+
q.submit([&](handler &cgh) {
15+
cgh.single_task<KernelName1<TT>>([](){});
16+
});
17+
}
18+
19+
template <typename TY> class Bar2;
20+
// CHECK: template <typename TY> class Bar2;
21+
template <template <typename> class TT> class Foo2;
22+
// CHECK: template <template <typename> class TT> class Foo2;
23+
template <class TTY> class KernelName2;
24+
// CHECK: template <class TTY> class KernelName2;
25+
template <class Y> void enqueue2() {
26+
queue q;
27+
q.submit([&](handler &cgh) {
28+
cgh.single_task< KernelName2<Y> >([](){});
29+
});
30+
}
31+
32+
template <typename T> class Bar3;
33+
// CHECK: template <typename T> class Bar3;
34+
template <template <typename> class> class Baz3;
35+
// CHECK: template <template <typename> class > class Baz3;
36+
template <template <template <typename> class> class T> class Foo3;
37+
// CHECK: template <template <template <typename> class > class T> class Foo3;
38+
template <typename T , typename... Args> class Mist3;
39+
// CHECK: template <typename T, typename ...Args> class Mist3;
40+
template <typename T, template <typename, typename...> class, typename... Args> class Ice3;
41+
// CHECK: template <typename T, template <typename, typename ...> class , typename ...Args> class Ice3;
42+
43+
int main() {
44+
enqueue<Foo1>();
45+
46+
enqueue2<Foo2<Bar2>>();
47+
48+
queue q;
49+
50+
q.submit([&](handler &cgh) {
51+
cgh.single_task<Bar3<int>>([](){});
52+
});
53+
54+
q.submit([&](handler &cgh) {
55+
cgh.single_task<Baz3<Bar3>>([](){});
56+
});
57+
58+
q.submit([&](handler &cgh) {
59+
cgh.single_task<Foo3<Baz3>>([](){});
60+
});
61+
62+
q.submit([&](handler &cgh) {
63+
cgh.single_task<Mist3<int, float, char, double>>([](){});
64+
});
65+
66+
q.submit([&](handler &cgh) {
67+
cgh.single_task<Ice3<int, Mist3, char, short, float>>([](){});
68+
});
69+
70+
return 0;
71+
}
72+

0 commit comments

Comments
 (0)