Index: include/clang/Basic/OpenMPKinds.def =================================================================== --- include/clang/Basic/OpenMPKinds.def +++ include/clang/Basic/OpenMPKinds.def @@ -748,6 +748,7 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) +OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) // Clauses allowed for OpenMP directive 'target teams'. OPENMP_TARGET_TEAMS_CLAUSE(if) Index: test/OpenMP/teams_distribute_parallel_for_ast_print.cpp =================================================================== --- test/OpenMP/teams_distribute_parallel_for_ast_print.cpp +++ test/OpenMP/teams_distribute_parallel_for_ast_print.cpp @@ -8,6 +8,9 @@ void foo() {} +int x; +#pragma omp threadprivate(x) + struct S { S(): a(0) {} S(int v) : a(v) {} @@ -40,7 +43,7 @@ void foo() { int b, argv, d, c, e, f; #pragma omp target -#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) +#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) copyin(x) for (int k = 0; k < a.a; ++k) ++a.a; } @@ -50,7 +53,7 @@ // CHECK: #pragma omp target // CHECK-NEXT: #pragma omp teams distribute parallel for private(this->a) private(this->a) // CHECK: #pragma omp target -// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) +// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) copyin(x) class S8 : public S7 { S8() {} @@ -74,7 +77,7 @@ void bar() { int b, argv, d, c, e, f8; #pragma omp target -#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d) +#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d) copyin(x) for (int k = 0; k < a.a; ++k) ++a.a; } @@ -86,7 +89,7 @@ // CHECK: #pragma omp target // CHECK-NEXT: #pragma omp teams distribute parallel for private(this->a) private(this->a) // CHECK: #pragma omp target -// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d) +// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d) copyin(x) template T tmain(T argc) { @@ -127,11 +130,11 @@ // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); #pragma omp target -#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) +#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) copyin(x) for (int k = 0; k < 10; ++k) e += d + argc; // CHECK: #pragma omp target -// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) +// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) copyin(x) // CHECK-NEXT: for (int k = 0; k < 10; ++k) // CHECK-NEXT: e += d + argc; #pragma omp target @@ -182,11 +185,11 @@ // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); #pragma omp target -#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) +#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) copyin(x) for (int k = 0; k < 10; ++k) e += d + argc; // CHECK: #pragma omp target -// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) +// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) copyin(x) // CHECK-NEXT: for (int k = 0; k < 10; ++k) // CHECK-NEXT: e += d + argc; #pragma omp target Index: test/OpenMP/teams_distribute_parallel_for_copyin_messages.cpp =================================================================== --- /dev/null +++ test/OpenMP/teams_distribute_parallel_for_copyin_messages.cpp @@ -0,0 +1,113 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2 &operator=(S2 &s2) { return *this; } +}; +class S3 { + int a; + +public: + S3() : a(0) {} + S3 &operator=(S3 &s3) { return *this; } +}; +class S4 { + int a; + S4(); + S4 &operator=(const S4 &s4); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} + S5 &operator=(const S5 &s5) { return *this; } // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; +template +class ST { +public: + static T s; +}; + +S2 k; +S3 h; +S4 l(3); +S5 m(4); +#pragma omp threadprivate(h, k, l, m) + +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams distribute parallel for copyin // expected-error {{expected '(' after 'copyin'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(l) // expected-error {{'operator=' is a private member of 'S4'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams distribute parallel for copyin(ST::s, B::x) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); + + return 0; +}