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 
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>
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
51 void test_one()
52 {
53   int aaa, bbb, var;
54   //PRINT: #pragma omp dispatch depend(in : var) nowait
55   //DUMP: OMPDispatchDirective
56   //DUMP: OMPDependClause
57   //DUMP: OMPNowaitClause
58   #pragma omp dispatch depend(in:var) nowait
59   foo(aaa, &bbb);
60 
61   int *dp = get_device_ptr();
62   int dev = get_device();
63   //PRINT: #pragma omp dispatch device(dev) is_device_ptr(dp)
64   //DUMP: OMPDispatchDirective
65   //DUMP: OMPDeviceClause
66   //DUMP: OMPIs_device_ptrClause
67   #pragma omp dispatch device(dev) is_device_ptr(dp)
68   foo(aaa, dp);
69 
70   //PRINT: #pragma omp dispatch
71   //PRINT: foo(other(), &bbb);
72   //DUMP: OMPDispatchDirective
73   #pragma omp dispatch
74   foo(other(), &bbb);
75 
76   fooTemp<int, int*>();
77 }
78 
79 struct Obj {
80   Obj();
81   ~Obj();
82   int disp_method_variant1();
83   #pragma omp declare variant(disp_method_variant1)                            \
84     match(construct={dispatch}, device={arch(arm)})
85   int disp_method1();
86 
87   static int disp_method_variant2() { return 1; }
88   #pragma omp declare variant(disp_method_variant2)                            \
89     match(construct={dispatch}, device={arch(arm)})
90   static int disp_method2() { return 2; }
91 };
92 
93 Obj foo_vari();
94 #pragma omp declare variant(foo_vari) \
95   match(construct={dispatch}, device={arch(arm)})
96 Obj foo_obj();
97 
98 //DUMP: FunctionDecl{{.*}} test_two
99 void test_two(Obj o1, Obj &o2, Obj *o3)
100 {
101   //PRINT: #pragma omp dispatch
102   //PRINT: o1.disp_method1();
103   //DUMP: OMPDispatchDirective
104   #pragma omp dispatch
105   o1.disp_method1();
106 
107   //PRINT: #pragma omp dispatch
108   //PRINT: o2.disp_method1();
109   //DUMP: OMPDispatchDirective
110   #pragma omp dispatch
111   o2.disp_method1();
112 
113   //PRINT: #pragma omp dispatch
114   //PRINT: o3->disp_method1();
115   //DUMP: OMPDispatchDirective
116   #pragma omp dispatch
117   o3->disp_method1();
118 
119   //PRINT: #pragma omp dispatch
120   //PRINT: Obj::disp_method2();
121   //DUMP: OMPDispatchDirective
122   #pragma omp dispatch
123   Obj::disp_method2();
124 
125   int ret;
126   //PRINT: #pragma omp dispatch
127   //PRINT: ret = o1.disp_method1();
128   //DUMP: OMPDispatchDirective
129   #pragma omp dispatch
130   ret = o1.disp_method1();
131 
132   //PRINT: #pragma omp dispatch
133   //PRINT: ret = o2.disp_method1();
134   //DUMP: OMPDispatchDirective
135   #pragma omp dispatch
136   ret = o2.disp_method1();
137 
138   //PRINT: #pragma omp dispatch
139   //PRINT: ret = o3->disp_method1();
140   //DUMP: OMPDispatchDirective
141   #pragma omp dispatch
142   ret = o3->disp_method1();
143 
144   //PRINT: #pragma omp dispatch
145   //PRINT: ret = Obj::disp_method2();
146   //DUMP: OMPDispatchDirective
147   #pragma omp dispatch
148   ret = Obj::disp_method2();
149 
150   //PRINT: #pragma omp dispatch
151   //PRINT: (void)Obj::disp_method2();
152   //DUMP: OMPDispatchDirective
153   #pragma omp dispatch
154   (void)Obj::disp_method2();
155 
156   // Full C++ operator= case with temps and EH.
157   Obj o;
158   //PRINT: #pragma omp dispatch
159   //PRINT: o = foo_obj();
160   //DUMP: OMPDispatchDirective
161   #pragma omp dispatch
162   o = foo_obj();
163 }
164 
165 struct A {
166   A& disp_operator(A other);
167   #pragma omp declare variant(disp_operator)                            \
168     match(construct={dispatch}, device={arch(arm)})
169   A& operator=(A other);
170 };
171 
172 struct Obj2 {
173   A xx;
174   Obj2& disp_operator(Obj2 other);
175   #pragma omp declare variant(disp_operator)                            \
176     match(construct={dispatch}, device={arch(arm)})
177   Obj2& operator=(Obj2 other);
178 
179   void foo() {
180     Obj2 z;
181     //PRINT: #pragma omp dispatch
182     //PRINT: z = z;
183     //DUMP: OMPDispatchDirective
184     #pragma omp dispatch
185     z = z;
186     //PRINT: #pragma omp dispatch
187     //PRINT: z.operator=(z);
188     //DUMP: OMPDispatchDirective
189     #pragma omp dispatch
190     z.operator=(z);
191   }
192   void bar() {
193     Obj2 j;
194     //PRINT: #pragma omp dispatch
195     //PRINT: j = {this->xx};
196     //DUMP: OMPDispatchDirective
197     #pragma omp dispatch
198     j = {this->xx};
199     //PRINT: #pragma omp dispatch
200     //PRINT: j.operator=({this->xx});
201     //DUMP: OMPDispatchDirective
202     #pragma omp dispatch
203     j.operator=({this->xx});
204   }
205 };
206 
207 void test_three()
208 {
209   Obj2 z1, z;
210   #pragma omp dispatch
211   z1 = z;
212   #pragma omp dispatch
213   z1.operator=(z);
214 }
215 #endif // HEADER
216