From: Alexey Bataev Date: Wed, 23 Jul 2014 10:25:33 +0000 (+0000) Subject: [OPENMP] Initial parsing and sema analysis for 'update' clause of 'atomic' directive. X-Git-Tag: llvmorg-3.5.0-rc3~2^2~2047 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67a4f22f12b07c48f1779b3716f6b369c8a1a830;p=platform%2Fupstream%2Fllvm.git [OPENMP] Initial parsing and sema analysis for 'update' clause of 'atomic' directive. llvm-svn: 213735 --- diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h index 3e4c3c9e14bf..685f88fcf861 100644 --- a/clang/include/clang/AST/DataRecursiveASTVisitor.h +++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h @@ -2430,6 +2430,11 @@ bool RecursiveASTVisitor::VisitOMPWriteClause(OMPWriteClause *) { return true; } +template +bool RecursiveASTVisitor::VisitOMPUpdateClause(OMPUpdateClause *) { + return true; +} + template template bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index b213ddd8d611..c4816e0b22b7 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -827,6 +827,36 @@ public: StmtRange children() { return StmtRange(); } }; +/// \brief This represents 'update' clause in the '#pragma omp atomic' +/// directive. +/// +/// \code +/// #pragma omp atomic update +/// \endcode +/// In this example directive '#pragma omp atomic' has 'update' clause. +/// +class OMPUpdateClause : public OMPClause { +public: + /// \brief Build 'update' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_update, StartLoc, EndLoc) {} + + /// \brief Build an empty clause. + /// + OMPUpdateClause() + : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {} + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_update; + } + + StmtRange children() { return StmtRange(); } +}; + /// \brief This represents clause 'private' in the '#pragma omp ...' directives. /// /// \code diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 727c8a52480b..d6d15991330e 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2452,6 +2452,11 @@ bool RecursiveASTVisitor::VisitOMPWriteClause(OMPWriteClause *) { return true; } +template +bool RecursiveASTVisitor::VisitOMPUpdateClause(OMPUpdateClause *) { + return true; +} + template template bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 28590cf64fb0..6d781f971454 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7154,6 +7154,9 @@ def err_omp_atomic_read_not_expression_statement : Error< def err_omp_atomic_write_not_expression_statement : Error< "the statement for 'atomic write' must be an expression statement of form 'x = expr;'," " where x is an l-value expression with scalar type">; +def err_omp_atomic_update_not_expression_statement : Error< + "the statement for 'atomic%select{| update}0' 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">; def err_omp_atomic_several_clauses : Error< "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">; def note_omp_atomic_previous_clause : Note< diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index ac87a2a07d65..fa0622d371dc 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -103,6 +103,7 @@ OPENMP_CLAUSE(mergeable, OMPMergeableClause) OPENMP_CLAUSE(flush, OMPFlushClause) OPENMP_CLAUSE(read, OMPReadClause) OPENMP_CLAUSE(write, OMPWriteClause) +OPENMP_CLAUSE(update, OMPUpdateClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -203,6 +204,7 @@ OPENMP_TASK_CLAUSE(mergeable) // TODO More clauses allowed for OpenMP directive 'atomic'. OPENMP_ATOMIC_CLAUSE(read) OPENMP_ATOMIC_CLAUSE(write) +OPENMP_ATOMIC_CLAUSE(update) #undef OPENMP_SCHEDULE_KIND #undef OPENMP_PROC_BIND_KIND diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4b59583a2946..b61eec03a33f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7488,6 +7488,9 @@ public: /// \brief Called on well-formed 'write' clause. OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'update' clause. + OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc, + SourceLocation EndLoc); OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef Vars, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index bf90a5e232ab..8e5018d4faec 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -669,6 +669,10 @@ void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; } void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; } +void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) { + OS << "update"; +} + template void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { for (typename T::varlist_iterator I = Node->varlist_begin(), diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index b65d07036b4a..e4fcbef2e74f 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -314,6 +314,8 @@ void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {} void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {} +void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {} + template void OMPClauseProfiler::VisitOMPClauseList(T *Node) { for (auto *I : Node->varlists()) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index db86cc713c33..4520e62254fa 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -110,6 +110,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_flush: case OMPC_read: case OMPC_write: + case OMPC_update: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -171,6 +172,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_flush: case OMPC_read: case OMPC_write: + case OMPC_update: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index a5bc4a449420..024b1abe37c7 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -342,7 +342,8 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, /// | linear-clause | aligned-clause | collapse-clause | /// lastprivate-clause | reduction-clause | proc_bind-clause | /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | -/// mergeable-clause | flush-clause | read-clause | write-clause +/// mergeable-clause | flush-clause | read-clause | write-clause | +/// update-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -410,6 +411,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_mergeable: case OMPC_read: case OMPC_write: + case OMPC_update: // OpenMP [2.7.1, Restrictions, p. 9] // Only one ordered clause can appear on a loop directive. // OpenMP [2.7.1, Restrictions, C/C++, p. 4] diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 318b00c5aa07..0dbdf16412c2 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2389,7 +2389,8 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, OpenMPClauseKind AtomicKind = OMPC_unknown; SourceLocation AtomicKindLoc; for (auto *C : Clauses) { - if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write) { + if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || + C->getClauseKind() == OMPC_update) { if (AtomicKind != OMPC_unknown) { Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) << SourceRange(C->getLocStart(), C->getLocEnd()); @@ -2413,6 +2414,13 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, diag::err_omp_atomic_write_not_expression_statement); return StmtError(); } + } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { + if (!isa(CS->getCapturedStmt())) { + Diag(CS->getCapturedStmt()->getLocStart(), + diag::err_omp_atomic_update_not_expression_statement) + << (AtomicKind == OMPC_update); + return StmtError(); + } } getCurFunction()->setHasBranchProtectedScope(); @@ -2461,6 +2469,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_flush: case OMPC_read: case OMPC_write: + case OMPC_update: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -2665,6 +2674,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_flush: case OMPC_read: case OMPC_write: + case OMPC_update: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -2782,6 +2792,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_flush: case OMPC_read: case OMPC_write: + case OMPC_update: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -2867,6 +2878,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_write: Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); break; + case OMPC_update: + Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -2923,6 +2937,11 @@ OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, return new (Context) OMPWriteClause(StartLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPUpdateClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef VarList, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, @@ -2978,6 +2997,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_threadprivate: case OMPC_read: case OMPC_write: + case OMPC_update: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 66da412b2c13..16a424e90ab0 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6773,6 +6773,13 @@ OMPClause *TreeTransform::TransformOMPWriteClause(OMPWriteClause *C) { return C; } +template +OMPClause * +TreeTransform::TransformOMPUpdateClause(OMPUpdateClause *C) { + // No need to rebuild this clause, no template-dependent parameters. + return C; +} + template OMPClause * TreeTransform::TransformOMPPrivateClause(OMPPrivateClause *C) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 7cefa80e23fe..78a4441a0915 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1721,6 +1721,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_write: C = new (Context) OMPWriteClause(); break; + case OMPC_update: + C = new (Context) OMPUpdateClause(); + break; case OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]); break; @@ -1819,6 +1822,8 @@ void OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {} void OMPClauseReader::VisitOMPWriteClause(OMPWriteClause *) {} +void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *) {} + void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); unsigned NumVars = C->varlist_size(); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 5048594bc659..3b8dbea1695a 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1739,6 +1739,8 @@ void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {} void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {} +void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {} + void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); diff --git a/clang/test/OpenMP/atomic_ast_print.cpp b/clang/test/OpenMP/atomic_ast_print.cpp index a24e34fd5289..ce8ebd523474 100644 --- a/clang/test/OpenMP/atomic_ast_print.cpp +++ b/clang/test/OpenMP/atomic_ast_print.cpp @@ -15,6 +15,8 @@ T foo(T argc) { a = argc; #pragma omp atomic write a = argc + argc; +#pragma omp atomic update + a = a + argc; return T(); } @@ -25,6 +27,8 @@ T foo(T argc) { // CHECK-NEXT: a = argc; // CHECK-NEXT: #pragma omp atomic write // CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update +// CHECK-NEXT: a = a + argc; // CHECK: T a = T(); // CHECK-NEXT: #pragma omp atomic // CHECK-NEXT: a++; @@ -32,6 +36,8 @@ T foo(T argc) { // CHECK-NEXT: a = argc; // CHECK-NEXT: #pragma omp atomic write // CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update +// CHECK-NEXT: a = a + argc; int main(int argc, char **argv) { int a = 0; @@ -42,12 +48,16 @@ int main(int argc, char **argv) { a = argc; #pragma omp atomic write a = argc + argc; +#pragma omp atomic update + a = a + argc; // CHECK-NEXT: #pragma omp atomic // CHECK-NEXT: a++; // CHECK-NEXT: #pragma omp atomic read // CHECK-NEXT: a = argc; // CHECK-NEXT: #pragma omp atomic write // CHECK-NEXT: a = argc + argc; + // CHECK-NEXT: #pragma omp atomic update + // CHECK-NEXT: a = a + argc; return foo(a); } diff --git a/clang/test/OpenMP/atomic_messages.cpp b/clang/test/OpenMP/atomic_messages.cpp index 4bc7686c1125..d7856cc229a8 100644 --- a/clang/test/OpenMP/atomic_messages.cpp +++ b/clang/test/OpenMP/atomic_messages.cpp @@ -4,12 +4,14 @@ int foo() { L1: foo(); #pragma omp atomic +// expected-error@+1 {{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}} { foo(); goto L1; // expected-error {{use of undeclared label 'L1'}} } goto L2; // expected-error {{use of undeclared label 'L2'}} #pragma omp atomic +// expected-error@+1 {{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}} { foo(); L2: @@ -73,6 +75,41 @@ int write() { return write(); } +template +T update() { + T a, b = 0; +// Test for atomic update +#pragma omp atomic update +// expected-error@+1 {{the statement for 'atomic update' 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-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} +#pragma omp atomic update update + a += b; + +#pragma omp atomic +// expected-error@+1 {{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}} + ; + + return T(); +} + +int update() { + int a, b = 0; +// Test for atomic update +#pragma omp atomic update +// expected-error@+1 {{the statement for 'atomic update' 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-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} +#pragma omp atomic update update + a += b; + +#pragma omp atomic +// expected-error@+1 {{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}} + ; + + return update(); +} + template T mixed() { T a, b = T(); @@ -84,6 +121,10 @@ T mixed() { // expected-note@+1 2 {{'write' clause used here}} #pragma omp atomic write read a = b; +// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 2 {{'update' clause used here}} +#pragma omp atomic update read + a += b; return T(); } @@ -97,6 +138,10 @@ int mixed() { // expected-note@+1 {{'write' clause used here}} #pragma omp atomic write read a = b; +// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 {{'write' clause used here}} +#pragma omp atomic write update + a = b; // expected-note@+1 {{in instantiation of function template specialization 'mixed' requested here}} return mixed(); } diff --git a/clang/test/OpenMP/nesting_of_regions.cpp b/clang/test/OpenMP/nesting_of_regions.cpp index 78af1a528492..5076f666ddf2 100644 --- a/clang/test/OpenMP/nesting_of_regions.cpp +++ b/clang/test/OpenMP/nesting_of_regions.cpp @@ -1405,24 +1405,28 @@ void foo() { // ATOMIC DIRECTIVE #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1430,6 +1434,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp section // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1437,6 +1442,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp single // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1444,6 +1450,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp master // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1451,6 +1458,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp critical // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1458,12 +1466,14 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1471,6 +1481,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp task // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -1478,31 +1489,37 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp flush // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside an atomic region}} ++a; @@ -2746,24 +2763,28 @@ void foo() { // ATOMIC DIRECTIVE #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2771,6 +2792,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp section // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2778,6 +2800,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp single // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2785,6 +2808,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp master // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2792,6 +2816,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp critical // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2799,12 +2824,14 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} for (int i = 0; i < 10; ++i) ; } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2812,6 +2839,7 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp task // expected-error {{OpenMP constructs may not be nested inside an atomic region}} { @@ -2819,31 +2847,37 @@ void foo() { } } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp flush // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } #pragma omp atomic +// expected-error@+1 {{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}} { #pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside an atomic region}} ++a; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index e989566a45d5..e5e7d7eb8c4a 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1985,6 +1985,8 @@ void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {} void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {} +void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {} + template void OMPClauseEnqueue::VisitOMPClauseList(T *Node) { for (const auto *I : Node->varlists())