blob: ebda94e7d5030776ad1bcf6ae7c7bd24109b0d6f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
// RUN: %clang_cc1 -fsycl-is-host -std=c++17 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsycl-is-device -std=c++17 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsycl-is-host -std=c++20 -fsyntax-only -verify -DCPP20 %s
// RUN: %clang_cc1 -fsycl-is-device -std=c++20 -fsyntax-only -verify -DCPP20 %s
// Semantic tests for the sycl_external attribute.
// expected-error@+1{{'clang::sycl_external' can only be applied to functions with external linkage}}
[[clang::sycl_external]]
static void func1() {}
// expected-error@+2{{'clang::sycl_external' can only be applied to functions with external linkage}}
namespace {
[[clang::sycl_external]]
void func2() {}
}
// expected-error@+2{{'clang::sycl_external' can only be applied to functions with external linkage}}
namespace { struct S4 {}; }
[[clang::sycl_external]] void func4(S4) {}
// expected-error@+3{{'clang::sycl_external' can only be applied to functions with external linkage}}
namespace { struct S5 {}; }
template<typename> [[clang::sycl_external]] void func5();
template<> [[clang::sycl_external]] void func5<S5>() {}
namespace { struct S6 {}; }
template<typename>
[[clang::sycl_external]] void func6() {}
template void func6<S6>();
// FIXME: C++23 [temp.expl.spec]p12 states:
// ... Similarly, attributes appearing in the declaration of a template
// have no effect on an explicit specialization of that template.
// Clang currently instantiates and propagates attributes from a function
// template to its explicit specializations resulting in the following
// spurious error.
// expected-error@+3{{'clang::sycl_external' can only be applied to functions with external linkage}}
namespace { struct S7 {}; }
template<typename>
[[clang::sycl_external]] void func7();
template<> void func7<S7>() {}
// FIXME: The explicit function template specialization appears to trigger
// instantiation of a declaration from the primary template without the
// attribute leading to a spurious diagnostic that the sycl_external
// attribute is not present on the first declaration.
namespace { struct S8 {}; }
template<typename>
void func8();
template<> [[clang::sycl_external]] void func8<S8>() {}
// expected-warning@-1{{'clang::sycl_external' attribute does not appear on the first declaration}}
// expected-error@-2{{'clang::sycl_external' can only be applied to functions with external linkage}}
// expected-note@-3{{previous declaration is here}}
namespace { struct S9 {}; }
struct T9 {
using type = S9;
};
template<typename>
[[clang::sycl_external]] void func9() {}
template<typename T>
[[clang::sycl_external]] void test_func9() {
func9<typename T::type>();
}
template void test_func9<T9>();
// The first declaration of a SYCL external function is required to have this attribute.
// expected-note@+1{{previous declaration is here}}
int foo();
// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}
[[clang::sycl_external]] int foo();
// expected-note@+1{{previous declaration is here}}
void goo();
// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}
[[clang::sycl_external]] void goo();
void goo() {}
// expected-note@+1{{previous declaration is here}}
void hoo() {}
// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}
[[clang::sycl_external]] void hoo();
// expected-note@+1{{previous declaration is here}}
void joo();
void use_joo() {
joo();
}
// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}
[[clang::sycl_external]] void joo();
// Subsequent declarations of a SYCL external function may optionally specify this attribute.
[[clang::sycl_external]] int boo();
[[clang::sycl_external]] int boo(); // OK
int boo(); // OK
class C {
[[clang::sycl_external]] void member();
};
// expected-error@+1{{'clang::sycl_external' cannot be applied to the 'main' function}}
[[clang::sycl_external]] int main()
{
return 0;
}
// expected-error@+2{{'clang::sycl_external' cannot be applied to an explicitly deleted function}}
class D {
[[clang::sycl_external]] void mdel() = delete;
};
// expected-error@+1{{'clang::sycl_external' cannot be applied to an explicitly deleted function}}
[[clang::sycl_external]] void del() = delete;
struct NonCopyable {
~NonCopyable() = delete;
[[clang::sycl_external]] NonCopyable(const NonCopyable&) = default;
};
class A {
[[clang::sycl_external]]
A() {}
[[clang::sycl_external]] void mf() {}
[[clang::sycl_external]] static void smf();
};
class B {
public:
[[clang::sycl_external]] virtual void foo() {}
[[clang::sycl_external]] virtual void bar() = 0;
};
[[clang::sycl_external]] void B::bar() {}
[[clang::sycl_external]] constexpr int square(int x);
// Devices that do not support the generic address space shall not specify
// a raw pointer or reference type as the return type or as a parameter type.
[[clang::sycl_external]] int *fun0();
[[clang::sycl_external]] int &fun1();
[[clang::sycl_external]] int &&fun2();
[[clang::sycl_external]] void fun3(int *);
[[clang::sycl_external]] void fun4(int &);
[[clang::sycl_external]] void fun5(int &&);
template<typename T>
[[clang::sycl_external]] void fun6(T) {}
template void fun6(int *);
template<> [[clang::sycl_external]] void fun6<long*>(long *) {}
#if CPP20
[[clang::sycl_external]] consteval int func();
#endif
|