1 | // RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s |
2 | // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s |
3 | // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s |
4 | |
5 | // RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s |
6 | // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s |
7 | // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s |
8 | // expected-no-diagnostics |
9 | |
10 | #ifndef HEADER |
11 | #define HEADER |
12 | |
13 | template <typename T> |
14 | void bar(T &x, T &y) { x.a += y.a; } |
15 | |
16 | namespace N1 |
17 | { |
18 | struct A { int a; A() : a(0) {} }; |
19 | #pragma omp declare reduction(+: A : bar(omp_out, omp_in)) |
20 | }; |
21 | |
22 | #pragma omp declare reduction(+ : int, char : omp_out *= omp_in) |
23 | // CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in){{$}} |
24 | // CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in) |
25 | |
26 | template <class T> |
27 | class SSS { |
28 | public: |
29 | #pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) |
30 | // CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) |
31 | // CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) |
32 | }; |
33 | |
34 | SSS<int> d; |
35 | |
36 | void init(SSS<int> &lhs, SSS<int> rhs); |
37 | |
38 | #pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) |
39 | // CHECK: #pragma omp declare reduction (fun : SSS<int> : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) |
40 | |
41 | // CHECK: template <typename T> T foo(T a) { |
42 | // CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); |
43 | // CHECK: { |
44 | // CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); |
45 | // CHECK: } |
46 | // CHECK: return a; |
47 | // CHECK: } |
48 | |
49 | // CHECK: template<> int foo<int>(int a) { |
50 | // CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); |
51 | // CHECK: { |
52 | // CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); |
53 | // CHECK: } |
54 | // CHECK: return a; |
55 | // CHECK: } |
56 | template <typename T> |
57 | T foo(T a) { |
58 | #pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) |
59 | { |
60 | #pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) |
61 | } |
62 | return a; |
63 | } |
64 | |
65 | int main() { |
66 | int i = 0; |
67 | SSS<int> sss; |
68 | // TODO: Add support for scoped reduction identifiers |
69 | // #pragma omp parallel reduction(SSS<int>::fun : i) |
70 | // TODO-CHECK: #pragma omp parallel reduction(SSS<int>::fun: i) |
71 | { |
72 | i += 1; |
73 | } |
74 | // #pragma omp parallel reduction(::fun:sss) |
75 | // TODO-CHECK: #pragma omp parallel reduction(::fun: sss) |
76 | { |
77 | } |
78 | N1::A a; |
79 | // CHECK: #pragma omp parallel reduction(+: a) |
80 | #pragma omp parallel reduction(+: a) |
81 | { |
82 | } |
83 | return foo(15); |
84 | } |
85 | |
86 | #endif |
87 | |