================
@@ -0,0 +1,541 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only
-fsycl-is-host -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only
-fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only
-fsycl-is-host -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only
-fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only
-fsycl-is-host -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only
-fsycl-is-device -verify %s
+
+// Test overload resolution for implicit calls to sycl_kernel_launch<KN>(...)
+// synthesized for functions declared with the sycl_kernel_entry_point
+// attribute.
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Valid declarations.
+////////////////////////////////////////////////////////////////////////////////
+
+// A unique kernel name type is required for each declared kernel entry point.
+template<int, int = 0> struct KN;
+
+// A generic kernel object type.
+template<int, int = 0>
+struct KT {
+ void operator()() const;
+};
+
+
+// sycl_kernel_launch as function template at namespace scope.
+namespace ok1 {
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts...);
+ [[clang::sycl_kernel_entry_point(KN<1>)]]
+ void skep(KT<1> k) {
+ k();
+ }
+}
+
+// sycl_kernel_launch as function template at namespace scope with default
+// template arguments and default function arguments..
+namespace ok2 {
+ template<typename KN, typename T = int>
+ void sycl_kernel_launch(const char *, KT<2>, T = 2);
+ [[clang::sycl_kernel_entry_point(KN<2>)]]
+ void skep(KT<2> k) {
+ k();
+ }
+}
+
+// sycl_kernel_launch as overload set.
+namespace ok3 {
+ template<typename KN>
+ void sycl_kernel_launch(const char *);
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts...);
+ [[clang::sycl_kernel_entry_point(KN<3>)]]
+ void skep(KT<3> k) {
+ k();
+ }
+}
+
+// sycl_kernel_launch as static member function template.
+namespace ok4 {
+ struct handler {
+ private:
+ template<typename KN, typename... Ts>
+ static void sycl_kernel_launch(const char *, Ts...);
+ public:
+ [[clang::sycl_kernel_entry_point(KN<4,0>)]]
+ static void skep(KT<4,0> k) {
+ k();
+ }
+ [[clang::sycl_kernel_entry_point(KN<4,1>)]]
+ void skep(KT<4,1> k) {
+ k();
+ }
+ };
+}
+
+// sycl_kernel_launch as non-static member function template.
+namespace ok5 {
+ struct handler {
+ private:
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts...);
+ public:
+ [[clang::sycl_kernel_entry_point(KN<5>)]]
+ void skep(KT<5> k) {
+ k();
+ }
+ };
+}
+
+#if __cplusplus >= 202302L
+// sycl_kernel_launch as non-static member function template with explicit
+// object parameter.
+namespace ok6 {
+ struct handler {
+ private:
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(this handler self, const char *, Ts...);
+ public:
+ [[clang::sycl_kernel_entry_point(KN<6>)]]
+ void skep(KT<6> k) {
+ k();
+ }
+ };
+}
+#endif
+
+// sycl_kernel_launch as variable template.
+namespace ok7 {
+ template<typename KN>
+ struct launcher {
+ template<typename... Ts>
+ void operator()(const char *, Ts...);
+ };
+ template<typename KN>
+ launcher<KN> sycl_kernel_launch;
+ [[clang::sycl_kernel_entry_point(KN<7>)]]
+ void skep(KT<7> k) {
+ k();
+ }
+}
+
+#if __cplusplus >= 202302L
+// sycl_kernel_launch as variable template with static call operator template.
+namespace ok8 {
+ template<typename KN>
+ struct launcher {
+ template<typename... Ts>
+ static void operator()(const char *, Ts...);
+ };
+ template<typename KN>
+ launcher<KN> sycl_kernel_launch;
+ [[clang::sycl_kernel_entry_point(KN<8>)]]
+ void skep(KT<8> k) {
+ k();
+ }
+}
+#endif
+
+#if __cplusplus >= 202302L
+// sycl_kernel_launch as variable template with call operator template with
+// explicit object parameter.
+namespace ok9 {
+ template<typename KN>
+ struct launcher {
+ template<typename... Ts>
+ void operator()(this launcher self, const char *, Ts...);
+ };
+ template<typename KN>
+ launcher<KN> sycl_kernel_launch;
+ [[clang::sycl_kernel_entry_point(KN<9>)]]
+ void skep(KT<9> k) {
+ k();
+ }
+}
+#endif
+
+// sycl_kernel_launch as base class non-static member function template.
+namespace ok10 {
+ template<typename Derived>
+ struct base_handler {
+ protected:
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts...);
+ };
+ struct handler : protected base_handler<handler> {
+ public:
+ [[clang::sycl_kernel_entry_point(KN<10>)]]
+ void skep(KT<10> k) {
+ k();
+ }
+ };
+}
+
+// sycl_kernel_launch with non-reference parameters.
+namespace ok11 {
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts...);
+ struct move_only {
+ move_only(move_only&&) = default;
+ };
+ [[clang::sycl_kernel_entry_point(KN<11>)]]
+ void skep(KT<11> k, move_only) {
+ k();
+ }
+}
+
+// sycl_kernel_launch with forward reference parameters.
+namespace ok12 {
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts &&...);
+ struct non_copyable {
+ non_copyable(const non_copyable&) = delete;
+ };
+ struct non_moveable {
+ non_moveable(non_moveable&&) = delete;
+ };
+ struct move_only {
+ move_only(move_only&&) = default;
+ };
+ [[clang::sycl_kernel_entry_point(KN<12>)]]
+ void skep(KT<12> k, non_copyable, non_moveable, move_only) {
+ k();
+ }
+}
+
+// ADL for sycl_kernel_launch.
+namespace ok13 {
+ template<typename KN, typename KT, typename T>
+ [[clang::sycl_kernel_entry_point(KN)]]
+ void skep(KT k, T t) {
+ k();
+ }
+ namespace nested {
+ template<typename KN, typename... Ts>
+ void sycl_kernel_launch(const char *, Ts...);
+ struct S13 {};
+ }
+ template void skep<KN<13>>(KT<13>, nested::S13);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Invalid declarations.
+////////////////////////////////////////////////////////////////////////////////
+
+// A unique kernel name type is required for each declared kernel entry point.
+template<int, int = 0> struct BADKN;
+
+// A generic kernel object type.
+template<int, int = 0>
+struct BADKT {
+ void operator()() const;
+};
+
+
+// Undeclared sycl_kernel_launch identifier from non-template function.
+namespace bad1 {
+ // expected-error@+3 {{use of undeclared identifier 'sycl_kernel_launch'}}
+ // expected-note-re@+1 {{in implicit call to 'sycl_kernel_launch' with
template argument 'BADKN<1>' and function arguments (lvalue of type 'const
char[{{[0-9]*}}]', xvalue of type 'BADKT<1>') required here}}
+ [[clang::sycl_kernel_entry_point(BADKN<1>)]]
+ void skep(BADKT<1> k) {
+ k();
+ }
+}
+
+// Undeclared sycl_kernel_launch identifier from function template.
+namespace bad2 {
+ // expected-error@+4 {{use of undeclared identifier 'sycl_kernel_launch'}}
+ // expected-note-re@+2 {{in implicit call to 'sycl_kernel_launch' with
template argument 'BADKN<2>' and function arguments (lvalue of type 'const
char[{{[0-9]*}}]', xvalue of type 'BADKT<2>') required here}}
+ template<typename KN, typename KT>
+ [[clang::sycl_kernel_entry_point(KN)]]
+ void skep(KT k) {
+ k();
+ }
+ // expected-note@+1 {{in instantiation of function template specialization
'bad2::skep<BADKN<2>, BADKT<2>>' requested here}}
+ template void skep<BADKN<2>>(BADKT<2>);
+}
+
+// No matching function for call to sycl_kernel_launch; not a template.
+namespace bad3 {
+ // expected-note@+1 {{declared as a non-template here}}
+ void sycl_kernel_launch(const char *, BADKT<3>);
+ // expected-error@+3 {{'sycl_kernel_launch' does not refer to a template}}
+ // expected-note@+1 {{in implicit call to 'sycl_kernel_launch' with template
argument 'BADKN<3>' required here}}
+ [[clang::sycl_kernel_entry_point(BADKN<3>)]]
+ void skep(BADKT<3> k) {
+ k();
+ }
+}
+
+// No matching function for call to sycl_kernel_launch; not enough arguments.
+namespace bad4 {
+ // expected-note@+2 {{candidate function template not viable: requires 2
arguments, but 1 was provided}}
+ template<typename KN, typename KT>
+ void sycl_kernel_launch(const char *, KT);
+ // expected-error@+4 {{no matching function for call to
'sycl_kernel_launch'}}
+ // expected-note-re@+2 {{in implicit call to 'sycl_kernel_launch' with
template argument 'BADKN<4>' and function arguments (lvalue of type 'const
char[{{[0-9]*}}]') required here}}
+ template<typename KN>
+ [[clang::sycl_kernel_entry_point(KN)]]
+ void skep() {}
+ // expected-note@+1 {{in instantiation of function template specialization
'bad4::skep<BADKN<4>>' requested here}}
+ template void skep<BADKN<4>>();
+}
+
+// No matching function for call to sycl_kernel_launch; too many arguments.
+namespace bad5 {
+ // expected-note@+2 {{candidate function template not viable: requires 2
arguments, but 3 were provided}}
+ template<typename KN, typename KT>
+ void sycl_kernel_launch(const char *, KT);
+ // expected-error@+4 {{no matching function for call to
'sycl_kernel_launch'}}
+ // expected-note-re@+2 {{in implicit call to 'sycl_kernel_launch' with
template argument 'BADKN<5>' and function arguments (lvalue of type 'const
char[{{[0-9]*}}]', xvalue of type 'BADKT<5>', xvalue of type 'int') required
here}}
----------------
erichkeane wrote:
I'm VERY much not a fan of how this is being displayed/printed here. This is
really kind of an awful way of presenting this information. WE have planty of
ways of printing argument lists, inventing a new one isn't a good idea.
@AaronBallman
https://github.com/llvm/llvm-project/pull/152403
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits