arpith-jacob updated this revision to Diff 45226.
arpith-jacob added a comment.
Addressed comments from similar patch for 'target enter data' directive.
Added comment about 'target exit data'.
Removed parens around 0.
http://reviews.llvm.org/D16279
Files:
include/clang-c/Index.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/AST/StmtOpenMP.h
include/clang/Basic/OpenMPKinds.def
include/clang/Basic/StmtNodes.td
include/clang/Sema/Sema.h
include/clang/Serialization/ASTBitCodes.h
lib/AST/StmtOpenMP.cpp
lib/AST/StmtPrinter.cpp
lib/AST/StmtProfile.cpp
lib/Basic/OpenMPKinds.cpp
lib/CodeGen/CGStmt.cpp
lib/CodeGen/CGStmtOpenMP.cpp
lib/CodeGen/CodeGenFunction.h
lib/Parse/ParseOpenMP.cpp
lib/Sema/SemaOpenMP.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/OpenMP/nesting_of_regions.cpp
test/OpenMP/target_exit_data_ast_print.cpp
test/OpenMP/target_exit_data_device_messages.cpp
test/OpenMP/target_exit_data_if_messages.cpp
test/OpenMP/target_exit_data_map_messages.c
tools/libclang/CIndex.cpp
tools/libclang/CXCursor.cpp
Index: tools/libclang/CXCursor.cpp
===================================================================
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -603,6 +603,9 @@
case Stmt::OMPTargetEnterDataDirectiveClass:
K = CXCursor_OMPTargetEnterDataDirective;
break;
+ case Stmt::OMPTargetExitDataDirectiveClass:
+ K = CXCursor_OMPTargetExitDataDirective;
+ break;
case Stmt::OMPTeamsDirectiveClass:
K = CXCursor_OMPTeamsDirective;
break;
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -1954,6 +1954,7 @@
void VisitOMPTargetDirective(const OMPTargetDirective *D);
void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
+ void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
@@ -2634,6 +2635,11 @@
VisitOMPExecutableDirective(D);
}
+void EnqueueVisitor::VisitOMPTargetExitDataDirective(
+ const OMPTargetExitDataDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
VisitOMPExecutableDirective(D);
}
@@ -4518,6 +4524,8 @@
return cxstring::createRef("OMPTargetDataDirective");
case CXCursor_OMPTargetEnterDataDirective:
return cxstring::createRef("OMPTargetEnterDataDirective");
+ case CXCursor_OMPTargetExitDataDirective:
+ return cxstring::createRef("OMPTargetExitDataDirective");
case CXCursor_OMPTeamsDirective:
return cxstring::createRef("OMPTeamsDirective");
case CXCursor_OMPCancellationPointDirective:
Index: test/OpenMP/target_exit_data_map_messages.c
===================================================================
--- /dev/null
+++ test/OpenMP/target_exit_data_map_messages.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+int main(int argc, char **argv) {
+
+ int r;
+ #pragma omp target exit data // expected-error {{expected at least one map clause for '#pragma omp target exit data'}}
+
+ #pragma omp target exit data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target exit data'}}
+
+ #pragma omp target exit data map(always, from: r)
+ #pragma omp target exit data map(delete: r)
+ #pragma omp target exit data map(release: r)
+ #pragma omp target exit data map(always, alloc: r) // expected-error {{map type 'alloc' is not allowed for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(to: r) // expected-error {{map type 'to' is not allowed for '#pragma omp target exit data'}}
+
+ return 0;
+}
Index: test/OpenMP/target_exit_data_if_messages.cpp
===================================================================
--- /dev/null
+++ test/OpenMP/target_exit_data_if_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target exit data map(from: i) if // expected-error {{expected '(' after 'if'}}
+ #pragma omp target exit data map(from: i) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if () // expected-error {{expected expression}}
+ #pragma omp target exit data map(from: i) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+ #pragma omp target exit data map(from: i) if (argc > 0 ? argv[1] : argv[2])
+ #pragma omp target exit data map(from: i) if (argc + argc)
+ #pragma omp target exit data map(from: i) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'if' clause}}
+ #pragma omp target exit data map(from: i) if (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target exit data map(from: i) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target data : true) // expected-error {{directive name modifier 'target data' is not allowed for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(from: i) if(target exit data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target exit data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc)
+ #pragma omp target exit data map(from: i) if(target exit data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc) if (target exit data:argc) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'if' clause with 'target exit data' name modifier}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+
+ return 0;
+}
Index: test/OpenMP/target_exit_data_device_messages.cpp
===================================================================
--- /dev/null
+++ test/OpenMP/target_exit_data_device_messages.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target exit data map(from: i) device // expected-error {{expected '(' after 'device'}}
+ #pragma omp target exit data map(from: i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) device () // expected-error {{expected expression}}
+ #pragma omp target exit data map(from: i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+#pragma omp target exit data map(from: i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target exit data map(from: i) device (argc + argc)
+ #pragma omp target exit data map(from: i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'device' clause}}
+ #pragma omp target exit data map(from: i) device (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target exit data map(from: i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ #pragma omp target exit data map(from: i) device (-10u)
+ #pragma omp target exit data map(from: i) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ foo();
+
+ return 0;
+}
Index: test/OpenMP/target_exit_data_ast_print.cpp
===================================================================
--- /dev/null
+++ test/OpenMP/target_exit_data_ast_print.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+ T i, j, b, c, d, e, x[20];
+
+ i = argc;
+#pragma omp target exit data map(from: i)
+
+#pragma omp target exit data map(from: i) if (target exit data: j > 0)
+
+#pragma omp target exit data map(from: i) if (b)
+
+#pragma omp target exit data map(from: c)
+
+#pragma omp target exit data map(from: c) if(b>e)
+
+#pragma omp target exit data map(release: x[0:10], c)
+
+#pragma omp target exit data map(from: c) map(release: d)
+
+#pragma omp target exit data map(always,release: e)
+
+ return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target exit data map(from: i)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e)
+// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
+// CHECK-NEXT: char i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target exit data map(from: i)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e)
+// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target exit data map(from: i)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e)
+// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+
+int main (int argc, char **argv) {
+ int b = argc, c, d, e, f, g, x[20];
+ static int a;
+// CHECK: static int a;
+
+#pragma omp target exit data map(from: a)
+// CHECK: #pragma omp target exit data map(from: a)
+ a=2;
+// CHECK-NEXT: a = 2;
+#pragma omp target exit data map(from: a) if (target exit data: b)
+// CHECK: #pragma omp target exit data map(from: a) if(target exit data: b)
+
+#pragma omp target exit data map(from: a) if (b > g)
+// CHECK: #pragma omp target exit data map(from: a) if(b > g)
+
+#pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+
+#pragma omp target exit data map(release: c) if(b>g)
+// CHECK-NEXT: #pragma omp target exit data map(release: c) if(b > g)
+
+#pragma omp target exit data map(from: x[0:10], c)
+// CHECK-NEXT: #pragma omp target exit data map(from: x[0:10],c)
+
+#pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+
+#pragma omp target exit data map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+
+ return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]);
+}
+
+#endif
Index: test/OpenMP/nesting_of_regions.cpp
===================================================================
--- test/OpenMP/nesting_of_regions.cpp
+++ test/OpenMP/nesting_of_regions.cpp
@@ -102,6 +102,11 @@
}
#pragma omp parallel
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -246,6 +251,11 @@
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -413,6 +423,11 @@
}
#pragma omp for
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -557,6 +572,11 @@
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -730,6 +750,10 @@
}
#pragma omp sections
{
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -943,6 +967,14 @@
#pragma omp sections
{
#pragma omp section
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
#pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1102,6 +1134,11 @@
}
#pragma omp single
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp single
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1259,6 +1296,11 @@
}
#pragma omp master
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp master
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1430,6 +1472,11 @@
}
#pragma omp critical
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp critical
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1602,6 +1649,11 @@
}
#pragma omp parallel for
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1774,6 +1826,11 @@
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -1936,6 +1993,10 @@
}
#pragma omp parallel sections
{
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp parallel sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2045,6 +2106,11 @@
}
#pragma omp task
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp task
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2212,6 +2278,11 @@
}
#pragma omp ordered
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp ordered
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2400,6 +2471,13 @@
// expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
// expected-note@+1 {{expected an expression statement}}
{
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
++a;
}
@@ -2540,6 +2618,10 @@
{
#pragma omp target enter data map(to: a)
}
+#pragma omp target
+ {
+#pragma omp target exit data map(from: a)
+ }
// TEAMS DIRECTIVE
#pragma omp target
@@ -2663,6 +2745,12 @@
#pragma omp target
#pragma omp teams
{
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2833,6 +2921,11 @@
}
#pragma omp taskloop
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3034,6 +3127,13 @@
#pragma omp teams
#pragma omp distribute
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3138,6 +3238,11 @@
}
#pragma omp parallel
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3275,6 +3380,11 @@
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -3432,6 +3542,11 @@
}
#pragma omp for
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3569,6 +3684,11 @@
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -3717,6 +3837,10 @@
}
#pragma omp sections
{
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3935,6 +4059,14 @@
{
#pragma omp section
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4087,6 +4219,11 @@
}
#pragma omp single
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp single
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4244,6 +4381,11 @@
}
#pragma omp master
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp master
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4420,6 +4562,11 @@
}
#pragma omp critical
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp critical
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4592,6 +4739,11 @@
}
#pragma omp parallel for
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4764,6 +4916,11 @@
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -4922,6 +5079,10 @@
}
#pragma omp parallel sections
{
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp parallel sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -5030,6 +5191,11 @@
}
#pragma omp task
{
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp task
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -5218,6 +5384,13 @@
// expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
// expected-note@+1 {{expected an expression statement}}
{
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
++a;
}
@@ -5337,6 +5510,10 @@
}
#pragma omp target
{
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp target
+ {
#pragma omp teams
++a;
}
@@ -5480,6 +5657,11 @@
#pragma omp target
#pragma omp teams
{
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}}
+ }
+#pragma omp target
+#pragma omp teams
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -5650,6 +5832,11 @@
}
#pragma omp taskloop
for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -5856,4 +6043,11 @@
#pragma omp target enter data map(to: a)
++a;
}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -831,6 +831,7 @@
case Stmt::OMPTargetDirectiveClass:
case Stmt::OMPTargetDataDirectiveClass:
case Stmt::OMPTargetEnterDataDirectiveClass:
+ case Stmt::OMPTargetExitDataDirectiveClass:
case Stmt::OMPTeamsDirectiveClass:
case Stmt::OMPCancellationPointDirectiveClass:
case Stmt::OMPCancelDirectiveClass:
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -2213,6 +2213,14 @@
Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPTargetExitDataDirective(
+ OMPTargetExitDataDirective *D) {
+ VisitStmt(D);
+ Record.push_back(D->getNumClauses());
+ VisitOMPExecutableDirective(D);
+ Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
+}
+
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -2449,6 +2449,13 @@
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPTargetExitDataDirective(
+ OMPTargetExitDataDirective *D) {
+ VisitStmt(D);
+ ++Idx;
+ VisitOMPExecutableDirective(D);
+}
+
void ASTStmtReader::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
VisitStmt(D);
// The NumClauses field was read in ReadStmtFromStream.
@@ -3097,6 +3104,11 @@
Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
+ case STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE:
+ S = OMPTargetExitDataDirective::CreateEmpty(
+ Context, Record[ASTStmtReader::NumStmtFields], Empty);
+ break;
+
case STMT_OMP_TEAMS_DIRECTIVE:
S = OMPTeamsDirective::CreateEmpty(
Context, Record[ASTStmtReader::NumStmtFields], Empty);
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -7389,6 +7389,17 @@
}
template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
+ OMPTargetExitDataDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName,
+ nullptr, D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
DeclarationNameInfo DirName;
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -1611,6 +1611,7 @@
case OMPD_cancel:
case OMPD_flush:
case OMPD_target_enter_data:
+ case OMPD_target_exit_data:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -1727,6 +1728,8 @@
// | parallel | target | * |
// | parallel | target enter | * |
// | | data | |
+ // | parallel | target exit | * |
+ // | | data | |
// | parallel | teams | + |
// | parallel | cancellation | |
// | | point | ! |
@@ -1758,6 +1761,8 @@
// | for | target | * |
// | for | target enter | * |
// | | data | |
+ // | for | target exit | * |
+ // | | data | |
// | for | teams | + |
// | for | cancellation | |
// | | point | ! |
@@ -1789,6 +1794,8 @@
// | master | target | * |
// | master | target enter | * |
// | | data | |
+ // | master | target exit | * |
+ // | | data | |
// | master | teams | + |
// | master | cancellation | |
// | | point | |
@@ -1819,6 +1826,8 @@
// | critical | target | * |
// | critical | target enter | * |
// | | data | |
+ // | critical | target exit | * |
+ // | | data | |
// | critical | teams | + |
// | critical | cancellation | |
// | | point | |
@@ -1850,6 +1859,8 @@
// | simd | target | |
// | simd | target enter | |
// | | data | |
+ // | simd | target exit | |
+ // | | data | |
// | simd | teams | |
// | simd | cancellation | |
// | | point | |
@@ -1881,6 +1892,8 @@
// | for simd | target | |
// | for simd | target enter | |
// | | data | |
+ // | for simd | target exit | |
+ // | | data | |
// | for simd | teams | |
// | for simd | cancellation | |
// | | point | |
@@ -1912,6 +1925,8 @@
// | parallel for simd| target | |
// | parallel for simd| target enter | |
// | | data | |
+ // | parallel for simd| target exit | |
+ // | | data | |
// | parallel for simd| teams | |
// | parallel for simd| cancellation | |
// | | point | |
@@ -1943,6 +1958,8 @@
// | sections | target | * |
// | sections | target enter | * |
// | | data | |
+ // | sections | target exit | * |
+ // | | data | |
// | sections | teams | + |
// | sections | cancellation | |
// | | point | ! |
@@ -1974,6 +1991,8 @@
// | section | target | * |
// | section | target enter | * |
// | | data | |
+ // | section | target exit | * |
+ // | | data | |
// | section | teams | + |
// | section | cancellation | |
// | | point | ! |
@@ -2005,6 +2024,8 @@
// | single | target | * |
// | single | target enter | * |
// | | data | |
+ // | single | target exit | * |
+ // | | data | |
// | single | teams | + |
// | single | cancellation | |
// | | point | |
@@ -2036,6 +2057,8 @@
// | parallel for | target | * |
// | parallel for | target enter | * |
// | | data | |
+ // | parallel for | target exit | * |
+ // | | data | |
// | parallel for | teams | + |
// | parallel for | cancellation | |
// | | point | ! |
@@ -2067,6 +2090,8 @@
// | parallel sections| target | * |
// | parallel sections| target enter | * |
// | | data | |
+ // | parallel sections| target exit | * |
+ // | | data | |
// | parallel sections| teams | + |
// | parallel sections| cancellation | |
// | | point | ! |
@@ -2098,6 +2123,8 @@
// | task | target | * |
// | task | target enter | * |
// | | data | |
+ // | task | target exit | * |
+ // | | data | |
// | task | teams | + |
// | task | cancellation | |
// | | point | ! |
@@ -2129,6 +2156,8 @@
// | ordered | target | * |
// | ordered | target enter | * |
// | | data | |
+ // | ordered | target exit | * |
+ // | | data | |
// | ordered | teams | + |
// | ordered | cancellation | |
// | | point | |
@@ -2160,6 +2189,8 @@
// | atomic | target | |
// | atomic | target enter | |
// | | data | |
+ // | atomic | target exit | |
+ // | | data | |
// | atomic | teams | |
// | atomic | cancellation | |
// | | point | |
@@ -2191,6 +2222,8 @@
// | target | target | * |
// | target | target enter | * |
// | | data | |
+ // | target | target exit | * |
+ // | | data | |
// | target | teams | * |
// | target | cancellation | |
// | | point | |
@@ -2222,6 +2255,8 @@
// | teams | target | + |
// | teams | target enter | + |
// | | data | |
+ // | teams | target exit | + |
+ // | | data | |
// | teams | teams | + |
// | teams | cancellation | |
// | | point | |
@@ -2253,6 +2288,8 @@
// | taskloop | target | * |
// | taskloop | target enter | * |
// | | data | |
+ // | taskloop | target exit | * |
+ // | | data | |
// | taskloop | teams | + |
// | taskloop | cancellation | |
// | | point | |
@@ -2283,6 +2320,8 @@
// | taskloop simd | target | |
// | taskloop simd | target enter | |
// | | data | |
+ // | taskloop simd | target exit | |
+ // | | data | |
// | taskloop simd | teams | |
// | taskloop simd | cancellation | |
// | | point | |
@@ -2314,6 +2353,8 @@
// | distribute | target | |
// | distribute | target enter | |
// | | data | |
+ // | distribute | target exit | |
+ // | | data | |
// | distribute | teams | |
// | distribute | cancellation | + |
// | | point | |
@@ -2743,6 +2784,11 @@
EndLoc);
AllowedNameModifiers.push_back(OMPD_target_enter_data);
break;
+ case OMPD_target_exit_data:
+ Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
+ EndLoc);
+ AllowedNameModifiers.push_back(OMPD_target_exit_data);
+ break;
case OMPD_taskloop:
Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
EndLoc, VarsWithInheritedDSA);
@@ -5520,6 +5566,20 @@
return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses);
}
+StmtResult Sema::ActOnOpenMPTargetExitDataDirective(
+ ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ // OpenMP [2.10.3, Restrictions, p. 102]
+ // At least one map clause must appear on the directive.
+ if (!HasMapClause(Clauses)) {
+ Diag(StartLoc, diag::err_omp_no_map_for_directive) <<
+ getOpenMPDirectiveName(OMPD_target_exit_data);
+ return StmtError();
+ }
+
+ return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses);
+}
+
StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc) {
@@ -8528,6 +8588,23 @@
// further spurious messages
}
+ // target exit_data
+ // OpenMP [2.10.3, Restrictions, p. 102]
+ // A map-type must be specified in all map clauses and must be either
+ // from, release, or delete.
+ DKind = DSAStack->getCurrentDirective();
+ if (DKind == OMPD_target_exit_data &&
+ !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
+ MapType == OMPC_MAP_delete)) {
+ Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) <<
+ // TODO: Need to determine if map type is implicitly determined
+ 0 <<
+ getOpenMPSimpleClauseTypeName(OMPC_map, MapType) <<
+ getOpenMPDirectiveName(DKind);
+ // Proceed to add the variable in a map clause anyway, to prevent
+ // further spurious messages
+ }
+
Vars.push_back(RE);
MI.RefExpr = RE;
DSAStack->addMapInfoForVar(VD, MI);
Index: lib/Parse/ParseOpenMP.cpp
===================================================================
--- lib/Parse/ParseOpenMP.cpp
+++ lib/Parse/ParseOpenMP.cpp
@@ -38,6 +38,8 @@
OMPD_unknown /*target enter/exit*/},
{OMPD_unknown /*target enter*/, OMPD_unknown /*data*/,
OMPD_target_enter_data},
+ {OMPD_unknown /*target exit*/, OMPD_unknown /*data*/,
+ OMPD_target_exit_data},
{OMPD_for, OMPD_simd, OMPD_for_simd},
{OMPD_parallel, OMPD_for, OMPD_parallel_for},
{OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
@@ -56,7 +58,9 @@
((i == 0) &&
!P.getPreprocessor().getSpelling(Tok).compare("cancellation")) ||
((i == 3) &&
- !P.getPreprocessor().getSpelling(Tok).compare("enter"));
+ !P.getPreprocessor().getSpelling(Tok).compare("enter")) ||
+ ((i == 4) &&
+ !P.getPreprocessor().getSpelling(Tok).compare("exit"));
} else {
TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;
}
@@ -73,10 +77,11 @@
TokenMatched =
((i == 0) &&
!P.getPreprocessor().getSpelling(Tok).compare("point")) ||
- ((i == 1 || i == 3) &&
+ ((i == 1 || i == 3 || i == 4) &&
!P.getPreprocessor().getSpelling(Tok).compare("data")) ||
((i == 2) &&
- !P.getPreprocessor().getSpelling(Tok).compare("enter"));
+ (!P.getPreprocessor().getSpelling(Tok).compare("enter") ||
+ !P.getPreprocessor().getSpelling(Tok).compare("exit")));
} else {
TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;
}
@@ -148,6 +153,7 @@
case OMPD_cancel:
case OMPD_target_data:
case OMPD_target_enter_data:
+ case OMPD_target_exit_data:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_distribute:
@@ -172,7 +178,8 @@
/// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
/// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
/// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' {clause} |
-/// 'distribute' | 'target enter data' | annot_pragma_openmp_end
+/// 'distribute' | 'target enter data' | 'target exit data'
+/// annot_pragma_openmp_end
///
StmtResult
Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
@@ -223,6 +230,7 @@
case OMPD_cancellation_point:
case OMPD_cancel:
case OMPD_target_enter_data:
+ case OMPD_target_exit_data:
if (!StandAloneAllowed) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2336,6 +2336,7 @@
void EmitOMPTargetDirective(const OMPTargetDirective &S);
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S);
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S);
+ void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S);
void EmitOMPTeamsDirective(const OMPTeamsDirective &S);
void
EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S);
Index: lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- lib/CodeGen/CGStmtOpenMP.cpp
+++ lib/CodeGen/CGStmtOpenMP.cpp
@@ -2665,6 +2665,11 @@
// TODO: codegen for target enter data.
}
+void CodeGenFunction::EmitOMPTargetExitDataDirective(
+ const OMPTargetExitDataDirective &S) {
+ // TODO: codegen for target exit data.
+}
+
void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
// emit the code inside the construct for now
auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -259,6 +259,9 @@
case Stmt::OMPTargetEnterDataDirectiveClass:
EmitOMPTargetEnterDataDirective(cast<OMPTargetEnterDataDirective>(*S));
break;
+ case Stmt::OMPTargetExitDataDirectiveClass:
+ EmitOMPTargetExitDataDirective(cast<OMPTargetExitDataDirective>(*S));
+ break;
case Stmt::OMPTaskLoopDirectiveClass:
EmitOMPTaskLoopDirective(cast<OMPTaskLoopDirective>(*S));
break;
Index: lib/Basic/OpenMPKinds.cpp
===================================================================
--- lib/Basic/OpenMPKinds.cpp
+++ lib/Basic/OpenMPKinds.cpp
@@ -408,6 +408,16 @@
break;
}
break;
+ case OMPD_target_exit_data:
+ switch (CKind) {
+#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_teams:
switch (CKind) {
#define OPENMP_TEAMS_CLAUSE(Name) \
Index: lib/AST/StmtProfile.cpp
===================================================================
--- lib/AST/StmtProfile.cpp
+++ lib/AST/StmtProfile.cpp
@@ -589,6 +589,11 @@
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPTargetExitDataDirective(
+ const OMPTargetExitDataDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
VisitOMPExecutableDirective(S);
}
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp
+++ lib/AST/StmtPrinter.cpp
@@ -1057,6 +1057,12 @@
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTargetExitDataDirective(
+ OMPTargetExitDataDirective *Node) {
+ Indent() << "#pragma omp target exit data ";
+ PrintOMPExecutableDirective(Node);
+}
+
void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
Indent() << "#pragma omp teams ";
PrintOMPExecutableDirective(Node);
Index: lib/AST/StmtOpenMP.cpp
===================================================================
--- lib/AST/StmtOpenMP.cpp
+++ lib/AST/StmtOpenMP.cpp
@@ -740,6 +740,28 @@
return new (Mem) OMPTargetEnterDataDirective(N);
}
+OMPTargetExitDataDirective *OMPTargetExitDataDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses) {
+ void *Mem =
+ C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPTargetExitDataDirective),
+ llvm::alignOf<OMPClause *>()) +
+ sizeof(OMPClause *) * Clauses.size());
+ OMPTargetExitDataDirective *Dir =
+ new (Mem) OMPTargetExitDataDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ return Dir;
+}
+
+OMPTargetExitDataDirective *OMPTargetExitDataDirective::CreateEmpty(
+ const ASTContext &C, unsigned N, EmptyShell) {
+ void *Mem =
+ C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPTargetExitDataDirective),
+ llvm::alignOf<OMPClause *>()) +
+ sizeof(OMPClause *) * N);
+ return new (Mem) OMPTargetExitDataDirective(N);
+}
+
OMPTeamsDirective *OMPTeamsDirective::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation EndLoc,
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h
+++ include/clang/Serialization/ASTBitCodes.h
@@ -1446,6 +1446,7 @@
STMT_OMP_TARGET_DIRECTIVE,
STMT_OMP_TARGET_DATA_DIRECTIVE,
STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE,
+ STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE,
STMT_OMP_TEAMS_DIRECTIVE,
STMT_OMP_TASKGROUP_DIRECTIVE,
STMT_OMP_CANCELLATION_POINT_DIRECTIVE,
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -7946,6 +7946,11 @@
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp target exit data' after
+ /// parsing of the associated statement.
+ StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// \brief Called on well-formed '\#pragma omp teams' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Index: include/clang/Basic/StmtNodes.td
===================================================================
--- include/clang/Basic/StmtNodes.td
+++ include/clang/Basic/StmtNodes.td
@@ -217,6 +217,7 @@
def OMPTargetDirective : DStmt<OMPExecutableDirective>;
def OMPTargetDataDirective : DStmt<OMPExecutableDirective>;
def OMPTargetEnterDataDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetExitDataDirective : DStmt<OMPExecutableDirective>;
def OMPTeamsDirective : DStmt<OMPExecutableDirective>;
def OMPCancellationPointDirective : DStmt<OMPExecutableDirective>;
def OMPCancelDirective : DStmt<OMPExecutableDirective>;
Index: include/clang/Basic/OpenMPKinds.def
===================================================================
--- include/clang/Basic/OpenMPKinds.def
+++ include/clang/Basic/OpenMPKinds.def
@@ -63,6 +63,9 @@
#ifndef OPENMP_TARGET_ENTER_DATA_CLAUSE
#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name)
#endif
+#ifndef OPENMP_TARGET_EXIT_DATA_CLAUSE
+#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name)
+#endif
#ifndef OPENMP_TEAMS_CLAUSE
# define OPENMP_TEAMS_CLAUSE(Name)
#endif
@@ -129,6 +132,7 @@
OPENMP_DIRECTIVE(cancel)
OPENMP_DIRECTIVE_EXT(target_data, "target data")
OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data")
+OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd")
OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
@@ -359,6 +363,12 @@
OPENMP_TARGET_ENTER_DATA_CLAUSE(device)
OPENMP_TARGET_ENTER_DATA_CLAUSE(map)
+// Clauses allowed for OpenMP directive 'target exit data'.
+// TODO More clauses for 'target exit data' directive.
+OPENMP_TARGET_EXIT_DATA_CLAUSE(if)
+OPENMP_TARGET_EXIT_DATA_CLAUSE(device)
+OPENMP_TARGET_EXIT_DATA_CLAUSE(map)
+
// Clauses allowed for OpenMP directive 'teams'.
// TODO More clauses for 'teams' directive.
OPENMP_TEAMS_CLAUSE(default)
@@ -454,6 +464,7 @@
#undef OPENMP_TARGET_CLAUSE
#undef OPENMP_TARGET_DATA_CLAUSE
#undef OPENMP_TARGET_ENTER_DATA_CLAUSE
+#undef OPENMP_TARGET_EXIT_DATA_CLAUSE
#undef OPENMP_TEAMS_CLAUSE
#undef OPENMP_SIMD_CLAUSE
#undef OPENMP_FOR_CLAUSE
Index: include/clang/AST/StmtOpenMP.h
===================================================================
--- include/clang/AST/StmtOpenMP.h
+++ include/clang/AST/StmtOpenMP.h
@@ -2098,6 +2098,64 @@
}
};
+/// \brief This represents '#pragma omp target exit data' directive.
+///
+/// \code
+/// #pragma omp target exit data device(0) if(a) map(b[:])
+/// \endcode
+/// In this example directive '#pragma omp target exit data' has clauses
+/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
+/// section 'b[:]'.
+///
+class OMPTargetExitDataDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param NumClauses The number of clauses.
+ ///
+ OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
+ OMPD_target_exit_data, StartLoc, EndLoc,
+ NumClauses, /*NumChildren=*/0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetExitDataDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
+ OMPD_target_exit_data, SourceLocation(),
+ SourceLocation(), NumClauses,
+ /*NumChildren=*/0) {}
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTargetExitDataDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// \brief Creates an empty directive with the place for \a N clauses.
+ ///
+ /// \param C AST context.
+ /// \param N The number of clauses.
+ ///
+ static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
+ unsigned N, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp teams' directive.
///
/// \code
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -2436,6 +2436,9 @@
DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPTeamsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -2278,7 +2278,11 @@
*/
CXCursor_OMPTargetEnterDataDirective = 261,
- CXCursor_LastStmt = CXCursor_OMPTargetEnterDataDirective,
+ /** \brief OpenMP target exit data directive.
+ */
+ CXCursor_OMPTargetExitDataDirective = 262,
+
+ CXCursor_LastStmt = CXCursor_OMPTargetExitDataDirective,
/**
* \brief Cursor that represents the translation unit itself.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits