1 // RUN: %clang_cc1 -triple=x86_64-pc-win32 -fopenmp -fopenmp-version=51     \
2 // RUN:   -fsyntax-only -verify %s
3 
4 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
5 // RUN:   -fsyntax-only -verify %s
6 
7 // expected-no-diagnostics
8 
9 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
10 // RUN:   -ast-print %s | FileCheck %s --check-prefix=PRINT
11 
12 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
13 // RUN:   -ast-dump  %s | FileCheck %s --check-prefix=DUMP
14 
15 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
16 // RUN:   -emit-pch -o %t %s
17 
18 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
19 // RUN:   -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP
20 
21 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
22 // RUN:   -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT
23 
24 #ifndef HEADER
25 #define HEADER
26 
foo_gpu(int A,int * B)27 int foo_gpu(int A, int *B) { return 0;}
28 //PRINT: #pragma omp declare variant(foo_gpu)
29 //DUMP: FunctionDecl{{.*}} foo
30 //DUMP: OMPDeclareVariantAttr {{.*}}Implicit construct{{.*}}
31 #pragma omp declare variant(foo_gpu) \
32     match(construct={dispatch}, device={arch(arm)})
33 int foo(int, int*);
34 
35 template <typename T, typename TP>
fooTemp()36 void fooTemp() {
37   T a;
38   TP b;
39   //PRINT: #pragma omp dispatch nowait
40   //DUMP: OMPDispatchDirective
41   //DUMP: OMPNowaitClause
42   #pragma omp dispatch nowait
43   foo(a, b);
44 }
45 
46 int *get_device_ptr();
47 int get_device();
48 int other();
49 
50 //DUMP: FunctionDecl{{.*}} test_one
test_one()51 void test_one()
52 {
53   int aaa, bbb, var;
54   //PRINT: #pragma omp dispatch depend(in : var) nowait novariants(aaa > 5) nocontext(bbb > 5)
55   //DUMP: OMPDispatchDirective
56   //DUMP: OMPDependClause
57   //DUMP: OMPNowaitClause
58   //DUMP: OMPNovariantsClause
59   //DUMP: DeclRefExpr {{.*}} 'bool' lvalue OMPCapturedExpr
60   //DUMP: OMPNocontextClause
61   //DUMP: DeclRefExpr {{.*}} 'bool' lvalue OMPCapturedExpr
62   #pragma omp dispatch depend(in:var) nowait novariants(aaa > 5) nocontext(bbb > 5)
63   foo(aaa, &bbb);
64 
65   int *dp = get_device_ptr();
66   int dev = get_device();
67   //PRINT: #pragma omp dispatch device(dev) is_device_ptr(dp) novariants(dev > 10) nocontext(dev > 5)
68   //DUMP: OMPDispatchDirective
69   //DUMP: OMPDeviceClause
70   //DUMP: OMPIs_device_ptrClause
71   //DUMP: OMPNovariantsClause
72   //DUMP: DeclRefExpr {{.*}} 'bool' lvalue OMPCapturedExpr
73   //DUMP: OMPNocontextClause
74   //DUMP: DeclRefExpr {{.*}} 'bool' lvalue OMPCapturedExpr
75   #pragma omp dispatch device(dev) is_device_ptr(dp) novariants(dev > 10) nocontext(dev > 5)
76   foo(aaa, dp);
77 
78   //PRINT: #pragma omp dispatch
79   //PRINT: foo(other(), &bbb);
80   //DUMP: OMPDispatchDirective
81   #pragma omp dispatch
82   foo(other(), &bbb);
83 
84   fooTemp<int, int*>();
85 }
86 
87 struct Obj {
88   Obj();
89   ~Obj();
90   int disp_method_variant1();
91   #pragma omp declare variant(disp_method_variant1)                            \
92     match(construct={dispatch}, device={arch(arm)})
93   int disp_method1();
94 
disp_method_variant2Obj95   static int disp_method_variant2() { return 1; }
96   #pragma omp declare variant(disp_method_variant2)                            \
97     match(construct={dispatch}, device={arch(arm)})
disp_method2Obj98   static int disp_method2() { return 2; }
99 };
100 
101 Obj foo_vari();
102 #pragma omp declare variant(foo_vari) \
103   match(construct={dispatch}, device={arch(arm)})
104 Obj foo_obj();
105 
106 //DUMP: FunctionDecl{{.*}} test_two
test_two(Obj o1,Obj & o2,Obj * o3)107 void test_two(Obj o1, Obj &o2, Obj *o3)
108 {
109   //PRINT: #pragma omp dispatch
110   //PRINT: o1.disp_method1();
111   //DUMP: OMPDispatchDirective
112   #pragma omp dispatch
113   o1.disp_method1();
114 
115   //PRINT: #pragma omp dispatch
116   //PRINT: o2.disp_method1();
117   //DUMP: OMPDispatchDirective
118   #pragma omp dispatch
119   o2.disp_method1();
120 
121   //PRINT: #pragma omp dispatch
122   //PRINT: o3->disp_method1();
123   //DUMP: OMPDispatchDirective
124   #pragma omp dispatch
125   o3->disp_method1();
126 
127   //PRINT: #pragma omp dispatch
128   //PRINT: Obj::disp_method2();
129   //DUMP: OMPDispatchDirective
130   #pragma omp dispatch
131   Obj::disp_method2();
132 
133   int ret;
134   //PRINT: #pragma omp dispatch
135   //PRINT: ret = o1.disp_method1();
136   //DUMP: OMPDispatchDirective
137   #pragma omp dispatch
138   ret = o1.disp_method1();
139 
140   //PRINT: #pragma omp dispatch
141   //PRINT: ret = o2.disp_method1();
142   //DUMP: OMPDispatchDirective
143   #pragma omp dispatch
144   ret = o2.disp_method1();
145 
146   //PRINT: #pragma omp dispatch
147   //PRINT: ret = o3->disp_method1();
148   //DUMP: OMPDispatchDirective
149   #pragma omp dispatch
150   ret = o3->disp_method1();
151 
152   //PRINT: #pragma omp dispatch
153   //PRINT: ret = Obj::disp_method2();
154   //DUMP: OMPDispatchDirective
155   #pragma omp dispatch
156   ret = Obj::disp_method2();
157 
158   //PRINT: #pragma omp dispatch
159   //PRINT: (void)Obj::disp_method2();
160   //DUMP: OMPDispatchDirective
161   #pragma omp dispatch
162   (void)Obj::disp_method2();
163 
164   // Full C++ operator= case with temps and EH.
165   Obj o;
166   //PRINT: #pragma omp dispatch
167   //PRINT: o = foo_obj();
168   //DUMP: OMPDispatchDirective
169   #pragma omp dispatch
170   o = foo_obj();
171 }
172 
173 struct A {
174   A& disp_operator(A other);
175   #pragma omp declare variant(disp_operator)                            \
176     match(construct={dispatch}, device={arch(arm)})
177   A& operator=(A other);
178 };
179 
180 struct Obj2 {
181   A xx;
182   Obj2& disp_operator(Obj2 other);
183   #pragma omp declare variant(disp_operator)                            \
184     match(construct={dispatch}, device={arch(arm)})
185   Obj2& operator=(Obj2 other);
186 
fooObj2187   void foo() {
188     Obj2 z;
189     //PRINT: #pragma omp dispatch
190     //PRINT: z = z;
191     //DUMP: OMPDispatchDirective
192     #pragma omp dispatch
193     z = z;
194     //PRINT: #pragma omp dispatch
195     //PRINT: z.operator=(z);
196     //DUMP: OMPDispatchDirective
197     #pragma omp dispatch
198     z.operator=(z);
199   }
barObj2200   void bar() {
201     Obj2 j;
202     //PRINT: #pragma omp dispatch
203     //PRINT: j = {this->xx};
204     //DUMP: OMPDispatchDirective
205     #pragma omp dispatch
206     j = {this->xx};
207     //PRINT: #pragma omp dispatch
208     //PRINT: j.operator=({this->xx});
209     //DUMP: OMPDispatchDirective
210     #pragma omp dispatch
211     j.operator=({this->xx});
212   }
213 };
214 
test_three()215 void test_three()
216 {
217   Obj2 z1, z;
218   #pragma omp dispatch
219   z1 = z;
220   #pragma omp dispatch
221   z1.operator=(z);
222 }
223 #endif // HEADER
224