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