This looks good. The update clause is the same as when atomic is alone without any clause. This is similar to: r213639 - [OPENMP] Initial parsing and sema analysis for 'atomic' directive
On Wed, Jul 23, 2014 at 6:25 AM, Alexey Bataev <[email protected]> wrote: > Author: abataev > Date: Wed Jul 23 05:25:33 2014 > New Revision: 213735 > > URL: http://llvm.org/viewvc/llvm-project?rev=213735&view=rev > Log: > [OPENMP] Initial parsing and sema analysis for 'update' clause of 'atomic' > directive. > > Modified: > cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h > cfe/trunk/include/clang/AST/OpenMPClause.h > cfe/trunk/include/clang/AST/RecursiveASTVisitor.h > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/include/clang/Basic/OpenMPKinds.def > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/AST/StmtPrinter.cpp > cfe/trunk/lib/AST/StmtProfile.cpp > cfe/trunk/lib/Basic/OpenMPKinds.cpp > cfe/trunk/lib/Parse/ParseOpenMP.cpp > cfe/trunk/lib/Sema/SemaOpenMP.cpp > cfe/trunk/lib/Sema/TreeTransform.h > cfe/trunk/lib/Serialization/ASTReaderStmt.cpp > cfe/trunk/lib/Serialization/ASTWriterStmt.cpp > cfe/trunk/test/OpenMP/atomic_ast_print.cpp > cfe/trunk/test/OpenMP/atomic_messages.cpp > cfe/trunk/test/OpenMP/nesting_of_regions.cpp > cfe/trunk/tools/libclang/CIndex.cpp > > Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original) > +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Wed Jul 23 > 05:25:33 2014 > @@ -2431,6 +2431,11 @@ bool RecursiveASTVisitor<Derived>::Visit > } > > template <typename Derived> > +bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause > *) { > + return true; > +} > + > +template <typename Derived> > template <typename T> > bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { > for (auto *E : Node->varlists()) { > > Modified: cfe/trunk/include/clang/AST/OpenMPClause.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/OpenMPClause.h (original) > +++ cfe/trunk/include/clang/AST/OpenMPClause.h Wed Jul 23 05:25:33 2014 > @@ -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 > > Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) > +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Jul 23 05:25:33 > 2014 > @@ -2453,6 +2453,11 @@ bool RecursiveASTVisitor<Derived>::Visit > } > > template <typename Derived> > +bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause > *) { > + return true; > +} > + > +template <typename Derived> > template <typename T> > bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { > for (auto *E : Node->varlists()) { > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 23 > 05:25:33 2014 > @@ -7154,6 +7154,9 @@ def err_omp_atomic_read_not_expression_s > 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< > > Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original) > +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Wed Jul 23 05:25:33 2014 > @@ -103,6 +103,7 @@ OPENMP_CLAUSE(mergeable, OMPMergeableCla > 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 > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 23 05:25:33 2014 > @@ -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<Expr *> Vars, > > Modified: cfe/trunk/lib/AST/StmtPrinter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) > +++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed Jul 23 05:25:33 2014 > @@ -669,6 +669,10 @@ void OMPClausePrinter::VisitOMPReadClaus > > void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << > "write"; } > > +void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) { > + OS << "update"; > +} > + > template<typename T> > void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { > for (typename T::varlist_iterator I = Node->varlist_begin(), > > Modified: cfe/trunk/lib/AST/StmtProfile.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/StmtProfile.cpp (original) > +++ cfe/trunk/lib/AST/StmtProfile.cpp Wed Jul 23 05:25:33 2014 > @@ -314,6 +314,8 @@ void OMPClauseProfiler::VisitOMPReadClau > > void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {} > > +void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {} > + > template<typename T> > void OMPClauseProfiler::VisitOMPClauseList(T *Node) { > for (auto *I : Node->varlists()) > > Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original) > +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Wed Jul 23 05:25:33 2014 > @@ -110,6 +110,7 @@ unsigned clang::getOpenMPSimpleClauseTyp > 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::getOpenMPSimpleClause > case OMPC_flush: > case OMPC_read: > case OMPC_write: > + case OMPC_update: > break; > } > llvm_unreachable("Invalid OpenMP simple clause kind"); > > Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) > +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Wed Jul 23 05:25:33 2014 > @@ -342,7 +342,8 @@ bool Parser::ParseOpenMPSimpleVarList(Op > /// | 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(Ope > 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] > > Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Jul 23 05:25:33 2014 > @@ -2389,7 +2389,8 @@ StmtResult Sema::ActOnOpenMPAtomicDirect > 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::ActOnOpenMPAtomicDirect > diag::err_omp_atomic_write_not_expression_statement); > return StmtError(); > } > + } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { > + if (!isa<Expr>(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::ActOnOpenMPSingleExprCl > 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::ActOnOpenMPSingleExprWi > 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(OpenM > 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( > 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<Expr *> VarList, Expr *TailExpr, > SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation > ColonLoc, > @@ -2978,6 +2997,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus > case OMPC_threadprivate: > case OMPC_read: > case OMPC_write: > + case OMPC_update: > case OMPC_unknown: > llvm_unreachable("Clause is not allowed."); > } > > Modified: cfe/trunk/lib/Sema/TreeTransform.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/TreeTransform.h (original) > +++ cfe/trunk/lib/Sema/TreeTransform.h Wed Jul 23 05:25:33 2014 > @@ -6775,6 +6775,13 @@ OMPClause *TreeTransform<Derived>::Trans > > template <typename Derived> > OMPClause * > +TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) { > + // No need to rebuild this clause, no template-dependent parameters. > + return C; > +} > + > +template <typename Derived> > +OMPClause * > TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { > llvm::SmallVector<Expr *, 16> Vars; > Vars.reserve(C->varlist_size()); > > Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Wed Jul 23 05:25:33 2014 > @@ -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 > > void OMPClauseReader::VisitOMPWriteClause(OMPWriteClause *) {} > > +void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *) {} > + > void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { > C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); > unsigned NumVars = C->varlist_size(); > > Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Wed Jul 23 05:25:33 2014 > @@ -1739,6 +1739,8 @@ void OMPClauseWriter::VisitOMPReadClause > > 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); > > Modified: cfe/trunk/test/OpenMP/atomic_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_ast_print.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/atomic_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/atomic_ast_print.cpp Wed Jul 23 05:25:33 2014 > @@ -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); > } > > > Modified: cfe/trunk/test/OpenMP/atomic_messages.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_messages.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/atomic_messages.cpp (original) > +++ cfe/trunk/test/OpenMP/atomic_messages.cpp Wed Jul 23 05:25:33 2014 > @@ -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: > @@ -74,6 +76,41 @@ int write() { > } > > template <class T> > +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<int>(); > +} > + > +template <class T> > T mixed() { > T a, b = T(); > // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain > more than one 'read', 'write', 'update' or 'capture' clause}} > @@ -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<int>' requested here}} > return mixed<int>(); > } > > Modified: cfe/trunk/test/OpenMP/nesting_of_regions.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/nesting_of_regions.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original) > +++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Wed Jul 23 05:25:33 2014 > @@ -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; > > Modified: cfe/trunk/tools/libclang/CIndex.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213735&r1=213734&r2=213735&view=diff > > ============================================================================== > --- cfe/trunk/tools/libclang/CIndex.cpp (original) > +++ cfe/trunk/tools/libclang/CIndex.cpp Wed Jul 23 05:25:33 2014 > @@ -1985,6 +1985,8 @@ void OMPClauseEnqueue::VisitOMPReadClaus > > void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {} > > +void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {} > + > template<typename T> > void OMPClauseEnqueue::VisitOMPClauseList(T *Node) { > for (const auto *I : Node->varlists()) > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
