1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s -ast-print -o - -Wno-source-uses-openmp -Wno-openmp-clauses | FileCheck %s
2 
3 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s -ast-print -o - -Wno-source-uses-openmp -Wno-openmp-clauses | FileCheck %s
4 
5 // expected-no-diagnostics
6 
7 // CHECK: int foo();
8 int foo();
9 
10 // CHECK:      template <typename T> T foofoo() {
11 // CHECK-NEXT: return T();
12 // CHECK-NEXT: }
13 template <typename T>
14 T foofoo() { return T(); }
15 
16 // CHECK:      template<> int foofoo<int>() {
17 // CHECK-NEXT: return int();
18 // CHECK-NEXT: }
19 
20 // CHECK:      #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(5): ibm)}, device={kind(fpga)})
21 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
22 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(0): llvm)}, device={kind(cpu)})
23 // CHECK-NEXT: int bar();
24 #pragma omp declare variant(foofoo <int>) match(xxx = {})
25 #pragma omp declare variant(foofoo <int>) match(xxx = {vvv})
26 #pragma omp declare variant(foofoo <int>) match(implementation = {vendor(score(0): "llvm"), xxx}, device = {kind(cpu)})
27 #pragma omp declare variant(foofoo <int>) match(implementation = {vendor("unknown")})
28 #pragma omp declare variant(foofoo <int>) match(implementation = {vendor(score(5): ibm)}, device = {kind(fpga)})
29 int bar();
30 
31 // CHECK:      #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5): ibm)}, device={kind(cpu, host)})
32 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)})
33 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)}, device={kind(cpu)})
34 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(user={condition(false)})
35 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(user={condition(true)})
36 // CHECK-NEXT: template <typename T, int C> T barbar();
37 #pragma omp declare variant(foofoo <T>) match(xxx = {})
38 #pragma omp declare variant(foofoo <T>) match(xxx = {vvv})
39 #pragma omp declare variant(foofoo <T>) match(user = {score(1 * 1 + 1) : condition(100 > 10 + 2)})
40 #pragma omp declare variant(foofoo <T>) match(user = {score(0) : condition(0)})
41 #pragma omp declare variant(foofoo <T>) match(user = {condition(true)})
42 #pragma omp declare variant(foofoo <T>) match(user = {condition(false)})
43 #pragma omp declare variant(foofoo <T>) match(implementation = {vendor(llvm)}, device = {kind(cpu)})
44 #pragma omp declare variant(foofoo <T>) match(implementation={vendor(unknown)})
45 #pragma omp declare variant(foofoo <T>) match(implementation={vendor(score(C+5): ibm, xxx, ibm)},device={kind(cpu,host)})
46 template <typename T, int C>
47 T barbar();
48 
49 // CHECK:      #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5): ibm)}, device={kind(cpu, host)})
50 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
51 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)}, device={kind(cpu)})
52 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(user={condition(false)})
53 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(user={condition(true)})
54 // CHECK-NEXT: template<> int barbar<int, 3>();
55 
56 // CHECK-NEXT: int baz() {
57 // CHECK-NEXT: return barbar<int, 3>();
58 // CHECK-NEXT: }
59 int baz() {
60   return barbar<int, 3>();
61 }
62 
63 // CHECK:      template <class C> void h_ref(C *hp, C *hp2, C *hq, C *lin) {
64 // CHECK-NEXT: }
65 // CHECK-NEXT: template<> void h_ref<double>(double *hp, double *hp2, double *hq, double *lin) {
66 // CHECK-NEXT: }
67 // CHECK-NEXT: template<> void h_ref<float>(float *hp, float *hp2, float *hq, float *lin)
68 template <class C>
69 void h_ref(C *hp, C *hp2, C *hq, C *lin) {
70 }
71 
72 // CHECK:      #pragma omp declare variant(h_ref<C>) match(implementation={vendor(unknown)}, device={kind(nohost)})
73 // CHECK-NEXT: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(llvm)}, device={kind(gpu)})
74 // CHECK-NEXT: template <class C> void h(C *hp, C *hp2, C *hq, C *lin) {
75 // CHECK-NEXT: }
76 #pragma omp declare variant(h_ref <C>) match(xxx = {})
77 #pragma omp declare variant(h_ref <C>) match(implementation = {vendor(llvm)}, device = {kind(gpu)})
78 #pragma omp declare variant(h_ref <C>) match(implementation = {vendor(unknown)}, device = {kind(nohost)})
79 template <class C>
80 void h(C *hp, C *hp2, C *hq, C *lin) {
81 }
82 
83 // CHECK:      #pragma omp declare variant(h_ref<float>) match(implementation={vendor(unknown)}, device={kind(nohost)})
84 // CHECK-NEXT: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(llvm)}, device={kind(gpu)})
85 // CHECK-NEXT: template<> void h<float>(float *hp, float *hp2, float *hq, float *lin) {
86 // CHECK-NEXT: }
87 
88 // CHECK-NEXT: template<> void h<double>(double *hp, double *hp2, double *hq, double *lin) {
89 // CHECK-NEXT:   h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
90 // CHECK-NEXT: }
91 #pragma omp declare variant(h_ref <double>) match(xxx = {})
92 #pragma omp declare variant(h_ref <double>) match(implementation = {vendor(ibm)}, device = {kind(cpu, gpu)})
93 #pragma omp declare variant(h_ref <double>) match(implementation={vendor(unknown)})
94 template <>
95 void h(double *hp, double *hp2, double *hq, double *lin) {
96   h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
97 }
98 
99 // CHECK: int fn();
100 int fn();
101 // CHECK: int fn(int);
102 int fn(int);
103 // CHECK:      #pragma omp declare variant(fn) match(implementation={vendor(unknown)}, device={kind(cpu, gpu)})
104 // CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(llvm)})
105 // CHECK-NEXT: int overload();
106 #pragma omp declare variant(fn) match(xxx = {})
107 #pragma omp declare variant(fn) match(implementation={vendor(llvm)})
108 #pragma omp declare variant(fn) match(implementation = {vendor(unknown)}, device = {kind(cpu, gpu)})
109 int overload(void);
110 
111 // CHECK:      int fn_deduced_variant() {
112 // CHECK-NEXT: return 0;
113 // CHECK-NEXT: }
114 auto fn_deduced_variant() { return 0; }
115 // CHECK:      #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)}, device={kind(gpu, nohost)})
116 // CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(llvm)}, device={kind(cpu, host)})
117 // CHECK-NEXT: int fn_deduced();
118 #pragma omp declare variant(fn_deduced_variant) match(xxx = {})
119 #pragma omp declare variant(fn_deduced_variant) match(implementation = {vendor(llvm)}, device = {kind(cpu, host)})
120 #pragma omp declare variant(fn_deduced_variant) match(implementation = {vendor(unknown)}, device = {kind(gpu, nohost)})
121 int fn_deduced();
122 
123 // CHECK: int fn_deduced_variant1();
124 int fn_deduced_variant1();
125 // CHECK:      #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)}, device={kind(cpu, host)})
126 // CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}, device={kind(gpu, nohost)})
127 // CHECK-NEXT: int fn_deduced1() {
128 // CHECK-NEXT: return 0;
129 // CHECK-NEXT: }
130 #pragma omp declare variant(fn_deduced_variant1) match(xxx = {})
131 #pragma omp declare variant(fn_deduced_variant1) match(implementation = {vendor(ibm)}, device = {kind(gpu, nohost)})
132 #pragma omp declare variant(fn_deduced_variant1) match(implementation = {vendor(unknown)}, device = {kind(cpu, host)})
133 auto fn_deduced1() { return 0; }
134 
135 // CHECK:      struct SpecialFuncs {
136 // CHECK-NEXT: void vd() {
137 // CHECK-NEXT: }
138 // CHECK-NEXT: SpecialFuncs();
139 // CHECK-NEXT: ~SpecialFuncs() noexcept;
140 // CHECK-NEXT: void baz() {
141 // CHECK-NEXT: }
142 // CHECK-NEXT: void bar() {
143 // CHECK-NEXT: }
144 // CHECK-NEXT: void bar(int) {
145 // CHECK-NEXT: }
146 // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}, device={kind(nohost)})
147 // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}, device={kind(cpu)})
148 // CHECK-NEXT: void foo1() {
149 // CHECK-NEXT: }
150 // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}, device={kind(cpu, host)})
151 // CHECK-NEXT: void xxx();
152 // CHECK-NEXT: } s;
153 struct SpecialFuncs {
154   void vd() {}
155   SpecialFuncs();
156   ~SpecialFuncs();
157 
158   void baz() {}
159   void bar() {}
160   void bar(int) {}
161 #pragma omp declare variant(SpecialFuncs::baz) match(xxx = {})
162 #pragma omp declare variant(SpecialFuncs::bar) match(xxx = {})
163 #pragma omp declare variant(SpecialFuncs::bar) match(implementation = {vendor(ibm)}, device = {kind(cpu)})
164 #pragma omp declare variant(SpecialFuncs::baz) match(implementation = {vendor(unknown)}, device = {kind(nohost)})
165   void foo1() {}
166 #pragma omp declare variant(SpecialFuncs::baz) match(implementation = {vendor(unknown)}, device = {kind(cpu, host)})
167   void xxx();
168 } s;
169 
170 // CHECK:      #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}, device={kind(cpu, host)})
171 // CHECK-NEXT: void SpecialFuncs::xxx() {
172 // CHECK-NEXT: }
173 void SpecialFuncs::xxx() {}
174 
175 // CHECK:      static void static_f_variant() {
176 // CHECK-NEXT: }
177 static void static_f_variant() {}
178 // CHECK:      #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)})
179 // CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(llvm)}, device={kind(fpga)})
180 // CHECK-NEXT: static void static_f() {
181 // CHECK-NEXT: }
182 #pragma omp declare variant(static_f_variant) match(xxx = {})
183 #pragma omp declare variant(static_f_variant) match(implementation = {vendor(llvm)}, device = {kind(fpga)})
184 #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)})
185 static void static_f() {}
186 
187 // CHECK: void bazzzz() {
188 // CHECK-NEXT: s.foo1();
189 // CHECK-NEXT: static_f();
190 // CHECK-NEXT: }
191 void bazzzz() {
192   s.foo1();
193   static_f();
194 }
195 
196 // CHECK: int fn_linkage_variant();
197 // CHECK: extern "C" {
198 // CHECK:     #pragma omp declare variant(fn_linkage_variant) match(implementation={vendor(ti)}, device={kind(cpu, host)})
199 // CHECK:     int fn_linkage();
200 // CHECK: }
201 int fn_linkage_variant();
202 extern "C" {
203 #pragma omp declare variant(fn_linkage_variant) match(implementation = {vendor(ti)}, device = {kind(cpu, host)})
204 int fn_linkage();
205 }
206 
207 // CHECK: extern "C" int fn_linkage_variant1()
208 // CHECK: #pragma omp declare variant(fn_linkage_variant1) match(implementation={vendor(gnu)}, device={kind(cpu, host)})
209 // CHECK: int fn_linkage1();
210 extern "C" int fn_linkage_variant1();
211 #pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(gnu)}, device = {kind(cpu, host)})
212 int fn_linkage1();
213 
214