1251e1488SMichael Kruse // RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
2251e1488SMichael Kruse // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
3251e1488SMichael Kruse // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
4251e1488SMichael Kruse 
5251e1488SMichael Kruse // RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
6251e1488SMichael Kruse // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
7251e1488SMichael Kruse // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
8251e1488SMichael Kruse // expected-no-diagnostics
9251e1488SMichael Kruse 
10251e1488SMichael Kruse #ifndef HEADER
11251e1488SMichael Kruse #define HEADER
12251e1488SMichael Kruse 
13251e1488SMichael Kruse // CHECK: namespace N1 {
14251e1488SMichael Kruse namespace N1
15251e1488SMichael Kruse {
16251e1488SMichael Kruse // CHECK: class vec {
17251e1488SMichael Kruse class vec {
18251e1488SMichael Kruse public:
19251e1488SMichael Kruse   int len;
20251e1488SMichael Kruse   double *data;
21251e1488SMichael Kruse };
22251e1488SMichael Kruse // CHECK: };
23251e1488SMichael Kruse 
24*888673b6SJonas Devlieghere // CHECK: class vecchild : public N1::vec {
254304e9d1SMichael Kruse class vecchild : public vec {
264304e9d1SMichael Kruse public:
274304e9d1SMichael Kruse   int lenc;
284304e9d1SMichael Kruse };
294304e9d1SMichael Kruse // CHECK: };
304304e9d1SMichael Kruse 
31251e1488SMichael Kruse #pragma omp declare mapper(id: vec v) map(v.len)
32*888673b6SJonas Devlieghere // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}
33251e1488SMichael Kruse };
34251e1488SMichael Kruse // CHECK: }
35251e1488SMichael Kruse // CHECK: ;
36251e1488SMichael Kruse 
37251e1488SMichael Kruse template <class T>
38251e1488SMichael Kruse class dat {
39251e1488SMichael Kruse public:
40251e1488SMichael Kruse   class datin {
41251e1488SMichael Kruse   public:
42251e1488SMichael Kruse     T in;
43251e1488SMichael Kruse   };
44251e1488SMichael Kruse   int i;
45251e1488SMichael Kruse   T d;
46251e1488SMichael Kruse #pragma omp declare mapper(id: N1::vec v) map(v.len)
47251e1488SMichael Kruse #pragma omp declare mapper(id: datin v) map(v.in)
48251e1488SMichael Kruse };
49251e1488SMichael Kruse 
50251e1488SMichael Kruse // CHECK: template <class T> class dat {
51251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}
52*888673b6SJonas Devlieghere // CHECK: #pragma omp declare mapper (id : dat::datin v) map(tofrom: v.in){{$}}
53251e1488SMichael Kruse // CHECK: };
54251e1488SMichael Kruse // CHECK: template<> class dat<double> {
55251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}
56*888673b6SJonas Devlieghere // CHECK: #pragma omp declare mapper (id : dat<double>::datin v) map(tofrom: v.in){{$}}
57251e1488SMichael Kruse // CHECK: };
58251e1488SMichael Kruse 
59827b5c21SAlexey Bataev constexpr int N = 2;
60827b5c21SAlexey Bataev #pragma omp declare mapper(default : N1::vec kk) map(kk.len) map(kk.data[0:N])
61827b5c21SAlexey Bataev // CHECK: #pragma omp declare mapper (default : N1::vec kk) map(tofrom: kk.len) map(tofrom: kk.data[0:N]){{$}}
62251e1488SMichael Kruse #pragma omp declare mapper(dat<double> d) map(to: d.d)
63251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (default : dat<double> d) map(to: d.d){{$}}
64251e1488SMichael Kruse 
65251e1488SMichael Kruse template <typename T>
foo(T a)66251e1488SMichael Kruse T foo(T a) {
674304e9d1SMichael Kruse   struct foodatchild {
684304e9d1SMichael Kruse     T k;
694304e9d1SMichael Kruse   };
70251e1488SMichael Kruse   struct foodat {
71251e1488SMichael Kruse     T a;
724304e9d1SMichael Kruse     struct foodatchild b;
73251e1488SMichael Kruse   };
744304e9d1SMichael Kruse #pragma omp declare mapper(id: struct foodat v) map(v.a)
754304e9d1SMichael Kruse #pragma omp declare mapper(idd: struct foodatchild v) map(v.k)
76251e1488SMichael Kruse #pragma omp declare mapper(id: N1::vec v) map(v.len)
77251e1488SMichael Kruse   {
78251e1488SMichael Kruse #pragma omp declare mapper(id: N1::vec v) map(v.len)
79251e1488SMichael Kruse   }
804304e9d1SMichael Kruse   struct foodat fd;
814304e9d1SMichael Kruse #pragma omp target map(mapper(id) alloc: fd)
824304e9d1SMichael Kruse   { fd.a++; }
834304e9d1SMichael Kruse #pragma omp target map(mapper(idd) alloc: fd.b)
844304e9d1SMichael Kruse   { fd.b.k++; }
8501f670dfSMichael Kruse #pragma omp target update to(mapper(id): fd)
8601f670dfSMichael Kruse #pragma omp target update to(mapper(idd): fd.b)
870336c75cSMichael Kruse #pragma omp target update from(mapper(id): fd)
880336c75cSMichael Kruse #pragma omp target update from(mapper(idd): fd.b)
89251e1488SMichael Kruse   return 0;
90251e1488SMichael Kruse }
91251e1488SMichael Kruse 
92251e1488SMichael Kruse // CHECK: template <typename T> T foo(T a) {
934304e9d1SMichael Kruse // CHECK: #pragma omp declare mapper (id : struct foodat v) map(tofrom: v.a)
944304e9d1SMichael Kruse // CHECK: #pragma omp declare mapper (idd : struct foodatchild v) map(tofrom: v.k)
95251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
96251e1488SMichael Kruse // CHECK: {
97251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
98251e1488SMichael Kruse // CHECK: }
994304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(id),alloc: fd)
1004304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(idd),alloc: fd.b)
10101f670dfSMichael Kruse // CHECK: #pragma omp target update to(mapper(id): fd)
10201f670dfSMichael Kruse // CHECK: #pragma omp target update to(mapper(idd): fd.b)
1030336c75cSMichael Kruse // CHECK: #pragma omp target update from(mapper(id): fd)
1040336c75cSMichael Kruse // CHECK: #pragma omp target update from(mapper(idd): fd.b)
105251e1488SMichael Kruse // CHECK: }
106251e1488SMichael Kruse // CHECK: template<> int foo<int>(int a) {
1074304e9d1SMichael Kruse // CHECK: #pragma omp declare mapper (id : struct foodat v) map(tofrom: v.a)
1084304e9d1SMichael Kruse // CHECK: #pragma omp declare mapper (idd : struct foodatchild v) map(tofrom: v.k)
109251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
110251e1488SMichael Kruse // CHECK: {
111251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
112251e1488SMichael Kruse // CHECK: }
1134304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(id),alloc: fd)
1144304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(idd),alloc: fd.b)
11501f670dfSMichael Kruse // CHECK: #pragma omp target update to(mapper(id): fd)
11601f670dfSMichael Kruse // CHECK: #pragma omp target update to(mapper(idd): fd.b)
1170336c75cSMichael Kruse // CHECK: #pragma omp target update from(mapper(id): fd)
1180336c75cSMichael Kruse // CHECK: #pragma omp target update from(mapper(idd): fd.b)
119251e1488SMichael Kruse // CHECK: }
120251e1488SMichael Kruse 
121251e1488SMichael Kruse // CHECK: int main() {
main()122251e1488SMichael Kruse int main() {
1234304e9d1SMichael Kruse   N1::vec vv, vvv;
1244304e9d1SMichael Kruse   N1::vecchild vc;
1254304e9d1SMichael Kruse   dat<double> dd;
1264304e9d1SMichael Kruse #pragma omp target map(mapper(N1::id) tofrom: vv) map(mapper(dat<double>::id) alloc: vvv)
1274304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(N1::id),tofrom: vv) map(mapper(dat<double>::id),alloc: vvv)
1284304e9d1SMichael Kruse   { vv.len++; }
1294304e9d1SMichael Kruse #pragma omp target map(mapper(N1::id) tofrom: vc)
1304304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(N1::id),tofrom: vc)
1314304e9d1SMichael Kruse   { vc.len++; }
1324304e9d1SMichael Kruse #pragma omp target map(mapper(default) tofrom: dd)
1334304e9d1SMichael Kruse // CHECK: #pragma omp target map(mapper(default),tofrom: dd)
1344304e9d1SMichael Kruse   { dd.d++; }
13501f670dfSMichael Kruse 
13601f670dfSMichael Kruse #pragma omp target update to(mapper(N1::id) : vc)
13701f670dfSMichael Kruse // CHECK: #pragma omp target update to(mapper(N1::id): vc)
13801f670dfSMichael Kruse #pragma omp target update to(mapper(dat<double>::id): vvv)
13901f670dfSMichael Kruse // CHECK: #pragma omp target update to(mapper(dat<double>::id): vvv)
14001f670dfSMichael Kruse 
1410336c75cSMichael Kruse #pragma omp target update from(mapper(N1::id) : vc)
1420336c75cSMichael Kruse // CHECK: #pragma omp target update from(mapper(N1::id): vc)
1430336c75cSMichael Kruse #pragma omp target update from(mapper(dat<double>::id): vvv)
1440336c75cSMichael Kruse // CHECK: #pragma omp target update from(mapper(dat<double>::id): vvv)
1450336c75cSMichael Kruse 
146251e1488SMichael Kruse #pragma omp declare mapper(id: N1::vec v) map(v.len)
147251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
148251e1488SMichael Kruse   {
149251e1488SMichael Kruse #pragma omp declare mapper(id: N1::vec v) map(v.len)
150251e1488SMichael Kruse // CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
151251e1488SMichael Kruse   }
152251e1488SMichael Kruse   return foo<int>(0);
153251e1488SMichael Kruse }
154251e1488SMichael Kruse // CHECK: }
155251e1488SMichael Kruse 
156251e1488SMichael Kruse #endif
157