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