sfantao updated this revision to Diff 58469. sfantao marked an inline comment as done. sfantao added a comment.
- Add nestings test. http://reviews.llvm.org/D15944 Files: include/clang-c/Index.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/StmtOpenMP.h include/clang/Basic/DiagnosticSemaKinds.td 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_update_device_messages.cpp test/OpenMP/target_update_if_messages.cpp test/OpenMP/target_update_messages.cpp tools/libclang/CIndex.cpp tools/libclang/CXCursor.cpp
Index: tools/libclang/CXCursor.cpp =================================================================== --- tools/libclang/CXCursor.cpp +++ tools/libclang/CXCursor.cpp @@ -612,6 +612,9 @@ case Stmt::OMPTargetParallelForDirectiveClass: K = CXCursor_OMPTargetParallelForDirective; break; + case Stmt::OMPTargetUpdateDirectiveClass: + K = CXCursor_OMPTargetUpdateDirective; + break; case Stmt::OMPTeamsDirectiveClass: K = CXCursor_OMPTeamsDirective; break; Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -4798,6 +4798,8 @@ return cxstring::createRef("OMPTargetParallelDirective"); case CXCursor_OMPTargetParallelForDirective: return cxstring::createRef("OMPTargetParallelForDirective"); + case CXCursor_OMPTargetUpdateDirective: + return cxstring::createRef("OMPTargetUpdateDirective"); case CXCursor_OMPTeamsDirective: return cxstring::createRef("OMPTeamsDirective"); case CXCursor_OMPCancellationPointDirective: Index: test/OpenMP/target_update_messages.cpp =================================================================== --- /dev/null +++ test/OpenMP/target_update_messages.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // Aexpected-note {{declared here}} + +template <class T, class S> // Aexpected-note {{declared here}} +int tmain(T argc, S **argv) { + int n; + return 0; +} + +int main(int argc, char **argv) { + int m; + #pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update { // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update ( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update [ // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + #pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + { + foo(); + } + return tmain(argc, argv); +} Index: test/OpenMP/target_update_if_messages.cpp =================================================================== --- /dev/null +++ test/OpenMP/target_update_if_messages.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + int n; +#pragma omp target update if // expected-error {{expected '(' after 'if'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (S) // expected-error {{'S' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + return 0; +} + +int main(int argc, char **argv) { + int m; +#pragma omp target update if // expected-error {{expected '(' after 'if'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + return tmain(argc, argv); +} Index: test/OpenMP/target_update_device_messages.cpp =================================================================== --- /dev/null +++ test/OpenMP/target_update_device_messages.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} + +template <class T, class S> +int tmain(T argc, S **argv) { + int i; +#pragma omp target update device // expected-error {{expected '(' after 'device'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc + argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +} + +int main(int argc, char **argv) { + int j; +#pragma omp target update device // expected-error {{expected '(' after 'device'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc + argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + return tmain(argc, argv); +} Index: test/OpenMP/nesting_of_regions.cpp =================================================================== --- test/OpenMP/nesting_of_regions.cpp +++ test/OpenMP/nesting_of_regions.cpp @@ -133,6 +133,10 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // SIMD DIRECTIVE #pragma omp simd @@ -293,6 +297,10 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}} + } // FOR DIRECTIVE #pragma omp for @@ -476,6 +484,10 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // FOR SIMD DIRECTIVE #pragma omp for simd @@ -636,6 +648,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } // SECTIONS DIRECTIVE #pragma omp sections @@ -824,6 +841,10 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // SECTION DIRECTIVE #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} @@ -1062,6 +1083,14 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp section + { + bar(); +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } + } // SINGLE DIRECTIVE #pragma omp single @@ -1235,6 +1264,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp single + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + bar(); + } // MASTER DIRECTIVE #pragma omp master @@ -1408,6 +1442,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp master + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + bar(); + } // CRITICAL DIRECTIVE #pragma omp critical @@ -1595,6 +1634,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp critical + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + bar(); + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -1783,6 +1827,10 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update //expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // PARALLEL FOR SIMD DIRECTIVE #pragma omp parallel for simd @@ -1971,6 +2019,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -2148,6 +2201,10 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel sections + { +#pragma omp target update //expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // TASK DIRECTIVE #pragma omp task @@ -2271,6 +2328,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp task + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + bar(); + } // ORDERED DIRECTIVE #pragma omp ordered @@ -2464,6 +2526,12 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp ordered + { + bar(); +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + bar(); + } // ATOMIC DIRECTIVE #pragma omp atomic @@ -2678,6 +2746,13 @@ for (int i = 0; i < 10; ++i) ; } +#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 target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } // TARGET DIRECTIVE #pragma omp target @@ -2812,6 +2887,10 @@ { #pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} } +#pragma omp target + { +#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}} + } // TARGET PARALLEL DIRECTIVE #pragma omp target parallel @@ -2946,6 +3025,10 @@ { #pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}} } +#pragma omp target parallel + { +#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel' region}} + } // TARGET PARALLEL FOR DIRECTIVE #pragma omp target parallel for @@ -3134,6 +3217,10 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel for' region}} + } // TEAMS DIRECTIVE #pragma omp target @@ -3297,6 +3384,11 @@ #pragma omp distribute for (int j = 0; j < 10; ++j) ; +#pragma omp target +#pragma omp teams + { +#pragma omp target update // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}} + } // TASKLOOP DIRECTIVE #pragma omp taskloop @@ -3469,6 +3561,13 @@ for (int i = 0; i < 10; ++i) ++a; } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + bar(); + } + + // DISTRIBUTE DIRECTIVE #pragma omp target #pragma omp teams @@ -3686,6 +3785,13 @@ #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; } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } } void foo() { @@ -3816,6 +3922,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + a++; + } // SIMD DIRECTIVE #pragma omp simd @@ -3969,6 +4080,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}} + a++; + } // FOR DIRECTIVE #pragma omp for @@ -4142,6 +4258,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + ++a; + } // FOR SIMD DIRECTIVE #pragma omp for simd @@ -4295,6 +4416,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // SECTIONS DIRECTIVE #pragma omp sections @@ -4458,6 +4584,10 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // SECTION DIRECTIVE #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} @@ -4706,6 +4836,14 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + a++; + } + } // SINGLE DIRECTIVE #pragma omp single @@ -4869,6 +5007,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp single + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + a++; + } // MASTER DIRECTIVE #pragma omp master @@ -5042,6 +5185,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp master + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + ++a; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -5234,6 +5382,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp critical + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + a++; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -5422,6 +5575,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + a++; + } // PARALLEL FOR SIMD DIRECTIVE #pragma omp parallel for simd @@ -5610,6 +5768,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}} + a++; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -5783,6 +5946,10 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel sections + { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + } // TASK DIRECTIVE #pragma omp task @@ -5905,6 +6072,11 @@ for (int i = 0; i < 10; ++i) ; } +#pragma omp task + { +#pragma omp target update // // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + a++; + } // ATOMIC DIRECTIVE #pragma omp atomic @@ -6119,6 +6291,12 @@ for (int i = 0; i < 10; ++i) ; } +#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 target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + } // TARGET DIRECTIVE #pragma omp target @@ -6253,6 +6431,13 @@ for (int i = 0; i < 10; ++i) ; } +#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 target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + a++; + } // TARGET PARALLEL DIRECTIVE #pragma omp target parallel @@ -6387,6 +6572,11 @@ { #pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}} } +#pragma omp target parallel + { +#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel' region}} + } + // TARGET PARALLEL FOR DIRECTIVE #pragma omp target parallel for @@ -6575,6 +6765,11 @@ for (int j = 0; j < 10; ++j) ; } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel for' region}} + a++; + } // TEAMS DIRECTIVE #pragma omp target @@ -6736,6 +6931,12 @@ #pragma omp distribute for (int j = 0; j < 10; ++j) ; +#pragma omp target +#pragma omp teams + { +#pragma omp target update // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}} + ++a; + } // TASKLOOP DIRECTIVE #pragma omp taskloop @@ -6908,6 +7109,11 @@ for (int i = 0; i < 10; ++i) ++a; } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + ++a; + } // DISTRIBUTE DIRECTIVE #pragma omp target @@ -7127,4 +7333,11 @@ #pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} ++a; } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } } Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -835,6 +835,7 @@ case Stmt::OMPTargetExitDataDirectiveClass: case Stmt::OMPTargetParallelDirectiveClass: case Stmt::OMPTargetParallelForDirectiveClass: + case Stmt::OMPTargetUpdateDirectiveClass: case Stmt::OMPTeamsDirectiveClass: case Stmt::OMPCancellationPointDirectiveClass: case Stmt::OMPCancelDirectiveClass: Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -2368,6 +2368,13 @@ Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE; } +void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -2588,6 +2588,12 @@ VisitOMPLoopDirective(D); } +void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) { + VisitStmt(D); + ++Idx; + VisitOMPExecutableDirective(D); +} + //===----------------------------------------------------------------------===// // ASTReader Implementation //===----------------------------------------------------------------------===// @@ -3220,6 +3226,11 @@ break; } + case STMT_OMP_TARGET_UPDATE_DIRECTIVE: + S = OMPTargetUpdateDirective::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 @@ -7477,6 +7477,17 @@ } template <typename Derived> +StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective( + OMPTargetUpdateDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, 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 @@ -1802,6 +1802,7 @@ case OMPD_declare_simd: case OMPD_declare_target: case OMPD_end_declare_target: + case OMPD_target_update: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: llvm_unreachable("Unknown OpenMP directive"); @@ -3251,6 +3252,12 @@ Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); break; + case OMPD_target_update: + assert(!AStmt && "Statement is not allowed for target update"); + Res = + ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_target_update); + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_threadprivate: @@ -6438,6 +6445,20 @@ return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); } +StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc) { + // TODO: Set this flag accordingly when we add support for the 'to' and 'from' + // clauses. + bool seenMotionClause = false; + + if (!seenMotionClause) { + Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); + return StmtError(); + } + return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses); +} + StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { @@ -10329,7 +10350,7 @@ // Save the components and declaration to create the clause. For purposes of // the clause creation, any component list that has has base 'this' uses - // null has + // null as base declaration. ClauseComponents.resize(ClauseComponents.size() + 1); ClauseComponents.back().append(CurComponents.begin(), CurComponents.end()); ClauseBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr Index: lib/Parse/ParseOpenMP.cpp =================================================================== --- lib/Parse/ParseOpenMP.cpp +++ lib/Parse/ParseOpenMP.cpp @@ -38,7 +38,8 @@ OMPD_point, OMPD_reduction, OMPD_target_enter, - OMPD_target_exit + OMPD_target_exit, + OMPD_update, }; class ThreadprivateListParserHelper final { @@ -73,6 +74,7 @@ .Case("exit", OMPD_exit) .Case("point", OMPD_point) .Case("reduction", OMPD_reduction) + .Case("update", OMPD_update) .Default(OMPD_unknown); } @@ -90,6 +92,7 @@ { OMPD_target, OMPD_data, OMPD_target_data }, { OMPD_target, OMPD_enter, OMPD_target_enter }, { OMPD_target, OMPD_exit, OMPD_target_exit }, + { OMPD_target, OMPD_update, OMPD_target_update }, { OMPD_target_enter, OMPD_data, OMPD_target_enter_data }, { OMPD_target_exit, OMPD_data, OMPD_target_exit_data }, { OMPD_for, OMPD_simd, OMPD_for_simd }, @@ -726,6 +729,7 @@ case OMPD_taskloop_simd: case OMPD_distribute: case OMPD_end_declare_target: + case OMPD_target_update: Diag(Tok, diag::err_omp_unexpected_directive) << getOpenMPDirectiveName(DKind); break; @@ -756,7 +760,8 @@ /// 'for simd' | 'parallel for simd' | 'target' | 'target data' | /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' | /// 'distribute' | 'target enter data' | 'target exit data' | -/// 'target parallel' | 'target parallel for' {clause} +/// 'target parallel' | 'target parallel for' | +/// 'target update' {clause} /// annot_pragma_openmp_end /// StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( @@ -830,6 +835,7 @@ case OMPD_cancel: case OMPD_target_enter_data: case OMPD_target_exit_data: + case OMPD_target_update: if (Allowed == ACK_StatementsOpenMPNonStandalone) { Diag(Tok, diag::err_omp_immediate_directive) << getOpenMPDirectiveName(DKind) << 0; Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2380,6 +2380,7 @@ void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S); void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S); void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S); + void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S); void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S); void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S); Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -3534,3 +3534,9 @@ const OMPTaskLoopSimdDirective &S) { EmitOMPTaskLoopBasedDirective(S); } + +// Generate the instructions for '#pragma omp target update' directive. +void CodeGenFunction::EmitOMPTargetUpdateDirective( + const OMPTargetUpdateDirective &S) { + // TODO: codegen for target update +} Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -277,6 +277,9 @@ case Stmt::OMPDistributeDirectiveClass: EmitOMPDistributeDirective(cast<OMPDistributeDirective>(*S)); break; + case Stmt::OMPTargetUpdateDirectiveClass: + EmitOMPTargetUpdateDirective(cast<OMPTargetUpdateDirective>(*S)); + break; } } Index: lib/Basic/OpenMPKinds.cpp =================================================================== --- lib/Basic/OpenMPKinds.cpp +++ lib/Basic/OpenMPKinds.cpp @@ -480,6 +480,16 @@ break; } break; + case OMPD_target_update: + switch (CKind) { +#define OPENMP_TARGET_UPDATE_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) \ @@ -605,7 +615,7 @@ bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { // TODO add target update directive check. return DKind == OMPD_target_data || DKind == OMPD_target_enter_data || - DKind == OMPD_target_exit_data; + DKind == OMPD_target_exit_data || DKind == OMPD_target_update; } bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { Index: lib/AST/StmtProfile.cpp =================================================================== --- lib/AST/StmtProfile.cpp +++ lib/AST/StmtProfile.cpp @@ -656,6 +656,11 @@ void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {} +void StmtProfiler::VisitOMPTargetUpdateDirective( + const OMPTargetUpdateDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } Index: lib/AST/StmtPrinter.cpp =================================================================== --- lib/AST/StmtPrinter.cpp +++ lib/AST/StmtPrinter.cpp @@ -1131,6 +1131,12 @@ PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPTargetUpdateDirective( + OMPTargetUpdateDirective *Node) { + Indent() << "#pragma omp target update "; + PrintOMPExecutableDirective(Node); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// Index: lib/AST/StmtOpenMP.cpp =================================================================== --- lib/AST/StmtOpenMP.cpp +++ lib/AST/StmtOpenMP.cpp @@ -1004,3 +1004,25 @@ numLoopChildren(CollapsedNum, OMPD_distribute)); return new (Mem) OMPDistributeDirective(CollapsedNum, NumClauses); } + +OMPTargetUpdateDirective * +OMPTargetUpdateDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetUpdateDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size()); + OMPTargetUpdateDirective *Dir = + new (Mem) OMPTargetUpdateDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + return Dir; +} + +OMPTargetUpdateDirective * +OMPTargetUpdateDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, + EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetUpdateDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses); + return new (Mem) OMPTargetUpdateDirective(NumClauses); +} Index: include/clang/Serialization/ASTBitCodes.h =================================================================== --- include/clang/Serialization/ASTBitCodes.h +++ include/clang/Serialization/ASTBitCodes.h @@ -1465,6 +1465,7 @@ STMT_OMP_TASKLOOP_DIRECTIVE, STMT_OMP_TASKLOOP_SIMD_DIRECTIVE, STMT_OMP_DISTRIBUTE_DIRECTIVE, + STMT_OMP_TARGET_UPDATE_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, // ARC Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -8172,6 +8172,10 @@ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp target update'. + StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); /// Checks correctness of linear modifiers. bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, Index: include/clang/Basic/StmtNodes.td =================================================================== --- include/clang/Basic/StmtNodes.td +++ include/clang/Basic/StmtNodes.td @@ -220,6 +220,7 @@ def OMPTargetExitDataDirective : DStmt<OMPExecutableDirective>; def OMPTargetParallelDirective : DStmt<OMPExecutableDirective>; def OMPTargetParallelForDirective : DStmt<OMPExecutableDirective>; +def OMPTargetUpdateDirective : 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 @@ -72,6 +72,9 @@ #ifndef OPENMP_TARGET_PARALLEL_FOR_CLAUSE # define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) #endif +#ifndef OPENMP_TARGET_UPDATE_CLAUSE +# define OPENMP_TARGET_UPDATE_CLAUSE(Name) +#endif #ifndef OPENMP_TEAMS_CLAUSE # define OPENMP_TEAMS_CLAUSE(Name) #endif @@ -150,6 +153,7 @@ OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data") OPENMP_DIRECTIVE_EXT(target_parallel, "target parallel") OPENMP_DIRECTIVE_EXT(target_parallel_for, "target parallel for") +OPENMP_DIRECTIVE_EXT(target_update, "target update") OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for") OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd") OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections") @@ -442,6 +446,11 @@ OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered) OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear) +// Clauses allowed for OpenMP directive 'target update'. +// TODO More clauses for 'target update' directive. +OPENMP_TARGET_UPDATE_CLAUSE(if) +OPENMP_TARGET_UPDATE_CLAUSE(device) + // Clauses allowed for OpenMP directive 'teams'. // TODO More clauses for 'teams' directive. OPENMP_TEAMS_CLAUSE(default) @@ -553,3 +562,4 @@ #undef OPENMP_DIST_SCHEDULE_KIND #undef OPENMP_DEFAULTMAP_KIND #undef OPENMP_DEFAULTMAP_MODIFIER +#undef OPENMP_TARGET_UPDATE_CLAUSE Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8264,6 +8264,8 @@ "expected a reference to a parameter specified in a 'uniform' clause">; def err_omp_expected_int_param : Error< "expected a reference to an integer-typed parameter">; +def err_omp_at_least_one_motion_clause_required : Error< + "expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { Index: include/clang/AST/StmtOpenMP.h =================================================================== --- include/clang/AST/StmtOpenMP.h +++ include/clang/AST/StmtOpenMP.h @@ -2671,7 +2671,7 @@ /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. - /// + /// static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, @@ -2693,6 +2693,65 @@ } }; +/// \brief This represents '#pragma omp target update' directive. +/// +/// \code +/// #pragma omp target update to(a) from(b) device(1) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'to' with +/// argument 'a', clause 'from' with argument 'b' and clause 'device' with +/// argument '1'. +/// +class OMPTargetUpdateDirective : 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. + /// + OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, + OMPD_target_update, StartLoc, EndLoc, NumClauses, + 0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetUpdateDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, + OMPD_target_update, SourceLocation(), + SourceLocation(), NumClauses, 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. + /// + static OMPTargetUpdateDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses The number of clauses. + /// + static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetUpdateDirectiveClass; + } +}; + } // end namespace clang #endif Index: include/clang/AST/RecursiveASTVisitor.h =================================================================== --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -2502,6 +2502,9 @@ DEF_TRAVERSE_STMT(OMPTeamsDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTargetUpdateDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPTaskLoopDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -2281,7 +2281,7 @@ */ CXCursor_OMPTaskLoopSimdDirective = 259, - /** \brief OpenMP distribute directive. + /** \brief OpenMP distribute directive. */ CXCursor_OMPDistributeDirective = 260, @@ -2301,7 +2301,11 @@ */ CXCursor_OMPTargetParallelForDirective = 264, - CXCursor_LastStmt = CXCursor_OMPTargetParallelForDirective, + /** \brief OpenMP target update directive. + */ + CXCursor_OMPTargetUpdateDirective = 265, + + CXCursor_LastStmt = CXCursor_OMPTargetUpdateDirective, /** * \brief Cursor that represents the translation unit itself.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits