blob: f62b1292732179a4fdecc81891ac25e6fe5e9f89 [file]
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++20 -fsyntax-only -fsycl-is-host -fms-compatibility -fcxx-exceptions -verify=host,expected %s
// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -fms-compatibility -verify=device,expected %s
// Test Microsoft extensions for lookup of a sycl_kernel_launch member template
// in a dependent base class.
////////////////////////////////////////////////////////////////////////////////
// Valid declarations.
////////////////////////////////////////////////////////////////////////////////
// A unique kernel name type is required for each declared kernel entry point.
template<int> struct KN;
// A generic kernel object type.
template<int>
struct KT {
void operator()() const;
};
namespace ok1 {
template<typename Derived>
struct base_handler {
protected:
// expected-note@+2 {{must qualify identifier to find this declaration in dependent base class}}
template<typename KN, typename... Ts>
void sycl_kernel_launch(const char *, Ts...);
};
template<int N>
struct handler : protected base_handler<handler<N>> {
// A warning is issued because, in standard C++, unqualified lookup for
// sycl_kernel_launch would not consider dependent base classes. Such
// lookups are allowed as a Microsoft compatible extension.
// expected-warning@+4 {{use of member 'sycl_kernel_launch' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
// expected-note@+2 {{this indicates a problem with the SYCL runtime header files; please consider reporting this to your SYCL runtime provider}}
// expected-note-re@+1 {{in implicit call to 'sycl_kernel_launch' with template argument 'KN<1>' and function arguments (lvalue of type 'const char[{{[0-9]*}}]', xvalue of type 'KT<1>') required here}}
[[clang::sycl_kernel_entry_point(KN<1>)]]
void skep(KT<1> k) {
k();
}
};
// expected-note@+1 {{in instantiation of member function 'ok1::handler<1>::skep' requested here}}
template void handler<1>::skep(KT<1>);
}
////////////////////////////////////////////////////////////////////////////////
// Invalid declarations.
////////////////////////////////////////////////////////////////////////////////
// A unique kernel name type is required for each declared kernel entry point.
template<int> struct BADKN;
// A generic kernel object type.
template<int>
struct BADKT {
void operator()() const;
};
namespace bad1 {
template<typename Derived>
struct base_handler {
private:
// expected-note@+3 {{must qualify identifier to find this declaration in dependent base class}}
// expected-note@+2 {{declared private here}}
template<typename KN, typename... Ts>
void sycl_kernel_launch(const char *, Ts...);
};
template<int N>
struct handler : protected base_handler<handler<N>> {
// In standard C++, unqualified lookup for sycl_kernel_launch would not
// consider dependent base classes. Such lookups are allowed as a Microsoft
// compatible extension, but access checks are still performed which makes
// this case an error.
// expected-warning@+5 {{use of member 'sycl_kernel_launch' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
// expected-note@+3 {{this indicates a problem with the SYCL runtime header files; please consider reporting this to your SYCL runtime provider}}
// expected-note-re@+2 {{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}}
// expected-error@+2 {{'sycl_kernel_launch' is a private member of 'bad1::base_handler<bad1::handler<1>>'}}
[[clang::sycl_kernel_entry_point(BADKN<1>)]]
void skep(BADKT<1> k) {
k();
}
};
// expected-note@+1 {{in instantiation of member function 'bad1::handler<1>::skep' requested here}}
template void handler<1>::skep(BADKT<1>);
}