From 77ca687869b3adaa82d774d6c3c3bc5e4598555c Mon Sep 17 00:00:00 2001
From: Carlo Bertolli <cbertol@us.ibm.com>
Date: Tue, 19 Jan 2016 16:53:55 +0000
Subject: [PATCH] Activate OpenMP private clause for target construct and a
 regression test.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@258140 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/OpenMPKinds.def     |   1 +
 lib/Sema/SemaOpenMP.cpp                 |   2 +-
 test/OpenMP/target_private_messages.cpp | 121 ++++++++++++++++++++++++
 3 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 test/OpenMP/target_private_messages.cpp

diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index a32e310486d..c388be3991a 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -346,6 +346,7 @@ OPENMP_ATOMIC_CLAUSE(seq_cst)
 OPENMP_TARGET_CLAUSE(if)
 OPENMP_TARGET_CLAUSE(device)
 OPENMP_TARGET_CLAUSE(map)
+OPENMP_TARGET_CLAUSE(private)
 
 // Clauses allowed for OpenMP directive 'target data'.
 // TODO More clauses for 'target data' directive.
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 4d0d3137bc0..acc54c1f9c1 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -6475,7 +6475,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
     }
 
     SourceLocation ELoc = RefExpr->getExprLoc();
-    // OpenMP [2.1, C/C++]
+    // OpenMP [3.1, C/C++]
     //  A list item is a variable name.
     // OpenMP  [2.9.3.3, Restrictions, p.1]
     //  A variable that is part of another variable (as an array or
diff --git a/test/OpenMP/target_private_messages.cpp b/test/OpenMP/target_private_messages.cpp
new file mode 100644
index 00000000000..eb3b604feca
--- /dev/null
+++ b/test/OpenMP/target_private_messages.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;
+#pragma omp target private // expected-error {{expected '(' after 'private'}}
+#pragma omp target private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target private() // expected-error {{expected expression}}
+#pragma omp target private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp target private(argc)
+#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+#pragma omp target private(argv[1]) // expected-error {{expected variable name}}
+#pragma omp target private(e, g)
+#pragma omp target private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}}
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp target private(i)
+    {}
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target private(j)
+#pragma omp target private(i)
+  {}
+  return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp parallel
+#pragma omp target private(a)
+  {}
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+#pragma omp target private // expected-error {{expected '(' after 'private'}}
+#pragma omp target private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target private() // expected-error {{expected expression}}
+#pragma omp target private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp target private(argc)
+#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+#pragma omp target private(argv[1]) // expected-error {{expected variable name}}
+#pragma omp target private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp target private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+#pragma omp target private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}}
+#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}}
+#pragma omp parallel
+  {
+    int i;
+#pragma omp target private(i)
+    {}
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target private(j)
+#pragma omp target private(i)
+  {}
+  static int si;
+#pragma omp target private(si) // OK
+  {}
+  return 0;
+}
+
-- 
GitLab