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// expected-no-diagnostics
5
6#ifndef HEADER
7#define HEADER
8
9#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
10// CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in)
11// CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in)
12
13// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
14
15template <class T>
16class SSS {
17public:
18#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
19  // CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
20};
21
22SSS<int> d;
23
24void init(SSS<int> &lhs, SSS<int> rhs);
25
26#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
27// CHECK: #pragma omp declare reduction (fun : SSS<int> : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
28
29// CHECK: template <typename T = int> int foo(int a) {
30// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
31// CHECK: {
32// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
33// CHECK: }
34// CHECK: return a;
35// CHECK: }
36
37// CHECK: template <typename T> T foo(T a) {
38// CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
39// CHECK: {
40// CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
41// CHECK: }
42// CHECK: return a;
43// CHECK: }
44template <typename T>
45T foo(T a) {
46#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
47  {
48#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
49  }
50  return a;
51}
52
53int main() {
54  int i = 0;
55  SSS<int> sss;
56  // TODO: Add support for scoped reduction identifiers
57  //  #pragma omp parallel reduction(SSS<int>::fun : i)
58  // TODO-CHECK: #pragma omp parallel reduction(SSS<int>::fun: i)
59  {
60    i += 1;
61  }
62  // #pragma omp parallel reduction(::fun:sss)
63  // TODO-CHECK: #pragma omp parallel reduction(::fun: sss)
64  {
65  }
66  return foo(15);
67}
68
69#endif
70