This looks good. The read clause only adds v = x; as an expression. This structure is similar to: r213639 - [OPENMP] Initial parsing and sema analysis for 'atomic' directive
On Tue, Jul 22, 2014 at 10:27 PM, Alexey Bataev <[email protected]> wrote: > Author: abataev > Date: Tue Jul 22 21:27:21 2014 > New Revision: 213717 > > URL: http://llvm.org/viewvc/llvm-project?rev=213717&view=rev > Log: > [OPENMP] Initial parsing and sema analysis for 'read' clause in '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/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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original) > +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Tue Jul 22 > 21:27:21 2014 > @@ -2421,6 +2421,11 @@ RecursiveASTVisitor<Derived>::VisitOMPMe > } > > template <typename Derived> > +bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) { > + 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/OpenMPClause.h (original) > +++ cfe/trunk/include/clang/AST/OpenMPClause.h Tue Jul 22 21:27:21 2014 > @@ -770,6 +770,34 @@ public: > StmtRange children() { return StmtRange(); } > }; > > +/// \brief This represents 'read' clause in the '#pragma omp atomic' > directive. > +/// > +/// \code > +/// #pragma omp atomic read > +/// \endcode > +/// In this example directive '#pragma omp atomic' has 'read' clause. > +/// > +class OMPReadClause : public OMPClause { > +public: > + /// \brief Build 'read' clause. > + /// > + /// \param StartLoc Starting location of the clause. > + /// \param EndLoc Ending location of the clause. > + /// > + OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) > + : OMPClause(OMPC_read, StartLoc, EndLoc) {} > + > + /// \brief Build an empty clause. > + /// > + OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), > SourceLocation()) {} > + > + static bool classof(const OMPClause *T) { > + return T->getClauseKind() == OMPC_read; > + } > + > + 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) > +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jul 22 21:27:21 > 2014 > @@ -2443,6 +2443,11 @@ RecursiveASTVisitor<Derived>::VisitOMPMe > } > > template <typename Derived> > +bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) { > + 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 22 > 21:27:21 2014 > @@ -7146,6 +7146,9 @@ def err_omp_parallel_sections_substmt_no > "statement in 'omp parallel sections' directive must be enclosed into a > section region">; > def err_omp_parallel_reduction_in_task_firstprivate : Error< > "argument of a reduction clause of a %0 construct must not appear in a > firstprivate clause on a task construct">; > +def err_omp_atomic_read_not_expression_statement : Error< > + "the statement for 'atomic read' must be an expression statement of > form 'v = x;'," > + " where v and x are both l-value expressions with scalar type">; > } // end of OpenMP category > > let CategoryName = "Related Result Type Issue" in { > > Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original) > +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Jul 22 21:27:21 2014 > @@ -101,6 +101,7 @@ OPENMP_CLAUSE(nowait, OMPNowaitClause) > OPENMP_CLAUSE(untied, OMPUntiedClause) > OPENMP_CLAUSE(mergeable, OMPMergeableClause) > OPENMP_CLAUSE(flush, OMPFlushClause) > +OPENMP_CLAUSE(read, OMPReadClause) > > // Clauses allowed for OpenMP directive 'parallel'. > OPENMP_PARALLEL_CLAUSE(if) > @@ -198,6 +199,9 @@ OPENMP_TASK_CLAUSE(shared) > OPENMP_TASK_CLAUSE(untied) > OPENMP_TASK_CLAUSE(mergeable) > > +// TODO More clauses allowed for OpenMP directive 'atomic'. > +OPENMP_ATOMIC_CLAUSE(read) > + > #undef OPENMP_SCHEDULE_KIND > #undef OPENMP_PROC_BIND_KIND > #undef OPENMP_DEFAULT_KIND > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 22 21:27:21 2014 > @@ -7482,6 +7482,9 @@ public: > /// \brief Called on well-formed 'mergeable' clause. > OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc, > SourceLocation EndLoc); > + /// \brief Called on well-formed 'read' clause. > + OMPClause *ActOnOpenMPReadClause(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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) > +++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jul 22 21:27:21 2014 > @@ -665,6 +665,8 @@ void OMPClausePrinter::VisitOMPMergeable > OS << "mergeable"; > } > > +void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << > "read"; } > + > 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/StmtProfile.cpp (original) > +++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jul 22 21:27:21 2014 > @@ -310,6 +310,8 @@ void OMPClauseProfiler::VisitOMPUntiedCl > > void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause > *) {} > > +void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {} > + > 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original) > +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Jul 22 21:27:21 2014 > @@ -108,6 +108,7 @@ unsigned clang::getOpenMPSimpleClauseTyp > case OMPC_untied: > case OMPC_mergeable: > case OMPC_flush: > + case OMPC_read: > break; > } > llvm_unreachable("Invalid OpenMP simple clause kind"); > @@ -167,6 +168,7 @@ const char *clang::getOpenMPSimpleClause > case OMPC_untied: > case OMPC_mergeable: > case OMPC_flush: > + case OMPC_read: > 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) > +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Jul 22 21:27:21 2014 > @@ -342,7 +342,7 @@ 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 > +/// mergeable-clause | flush-clause | read-clause > /// > OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, > OpenMPClauseKind CKind, bool > FirstClause) { > @@ -405,6 +405,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope > case OMPC_nowait: > case OMPC_untied: > case OMPC_mergeable: > + case OMPC_read: > // 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] > @@ -527,6 +528,9 @@ OMPClause *Parser::ParseOpenMPSimpleClau > /// mergeable-clause: > /// 'mergeable' > /// > +/// read-clause: > +/// 'read' > +/// > OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) { > SourceLocation Loc = Tok.getLocation(); > ConsumeAnyToken(); > > Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jul 22 21:27:21 2014 > @@ -92,15 +92,16 @@ private: > Scope *CurScope; > SourceLocation ConstructLoc; > bool OrderedRegion; > + SourceLocation AtomicClauseLoc; > SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, > Scope *CurScope, SourceLocation Loc) > : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified), > Directive(DKind), DirectiveName(std::move(Name)), > CurScope(CurScope), > - ConstructLoc(Loc), OrderedRegion(false) {} > + ConstructLoc(Loc), OrderedRegion(false), AtomicClauseLoc() {} > SharingMapTy() > : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified), > Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), > - ConstructLoc(), OrderedRegion(false) {} > + ConstructLoc(), OrderedRegion(false), AtomicClauseLoc() {} > }; > > typedef SmallVector<SharingMapTy, 64> StackTy; > @@ -207,6 +208,22 @@ public: > return false; > } > > + /// \brief Checks if the 'atomic' construct has explicitly specified > 'read', > + /// 'update', 'write' or 'capture' clause. > + bool hasAtomicClause() const { > + return Stack.back().AtomicClauseLoc.isValid(); > + } > + /// \brief Gets location of explicitly specified clause for 'atomic' > + /// construct. > + SourceLocation getAtomicClauseLoc() const { > + return Stack.back().AtomicClauseLoc; > + } > + /// \brief Sets location of explicitly specified clause for 'atomic' > + /// directive. > + void setAtomicClauseLoc(SourceLocation Loc) { > + Stack.back().AtomicClauseLoc = Loc; > + } > + > Scope *getCurScope() const { return Stack.back().CurScope; } > Scope *getCurScope() { return Stack.back().CurScope; } > SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } > @@ -2379,12 +2396,22 @@ StmtResult Sema::ActOnOpenMPAtomicDirect > SourceLocation StartLoc, > SourceLocation EndLoc) { > assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement > expected"); > + auto CS = cast<CapturedStmt>(AStmt); > // 1.2.2 OpenMP Language Terminology > // Structured block - An executable statement with a single entry at the > // top and a single exit at the bottom. > // The point of exit cannot be a branch out of the structured block. > // longjmp() and throw() must not violate the entry/exit criteria. > // TODO further analysis of associated statements and clauses. > + for (auto *C : Clauses) { > + if (C->getClauseKind() == OMPC_read) { > + if (!isa<Expr>(CS->getCapturedStmt())) { > + Diag(CS->getCapturedStmt()->getLocStart(), > + diag::err_omp_atomic_read_not_expression_statement); > + return StmtError(); > + } > + } > + } > > getCurFunction()->setHasBranchProtectedScope(); > > @@ -2430,6 +2457,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl > case OMPC_mergeable: > case OMPC_threadprivate: > case OMPC_flush: > + case OMPC_read: > case OMPC_unknown: > llvm_unreachable("Clause is not allowed."); > } > @@ -2633,6 +2661,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause > case OMPC_mergeable: > case OMPC_threadprivate: > case OMPC_flush: > + case OMPC_read: > case OMPC_unknown: > llvm_unreachable("Clause is not allowed."); > } > @@ -2748,6 +2777,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi > case OMPC_mergeable: > case OMPC_threadprivate: > case OMPC_flush: > + case OMPC_read: > case OMPC_unknown: > llvm_unreachable("Clause is not allowed."); > } > @@ -2827,6 +2857,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM > case OMPC_mergeable: > Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); > break; > + case OMPC_read: > + Res = ActOnOpenMPReadClause(StartLoc, EndLoc); > + break; > case OMPC_if: > case OMPC_final: > case OMPC_num_threads: > @@ -2873,6 +2906,12 @@ OMPClause *Sema::ActOnOpenMPMergeableCla > return new (Context) OMPMergeableClause(StartLoc, EndLoc); > } > > +OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, > + SourceLocation EndLoc) { > + DSAStack->setAtomicClauseLoc(StartLoc); > + return new (Context) OMPReadClause(StartLoc, EndLoc); > +} > + > OMPClause *Sema::ActOnOpenMPVarListClause( > OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, > SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation > ColonLoc, > @@ -2926,6 +2965,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus > case OMPC_untied: > case OMPC_mergeable: > case OMPC_threadprivate: > + case OMPC_read: > case OMPC_unknown: > llvm_unreachable("Clause is not allowed."); > } > @@ -4226,5 +4266,3 @@ OMPClause *Sema::ActOnOpenMPFlushClause( > > return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, > VarList); > } > - > -#undef DSAStack > > Modified: cfe/trunk/lib/Sema/TreeTransform.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/TreeTransform.h (original) > +++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jul 22 21:27:21 2014 > @@ -6762,6 +6762,12 @@ TreeTransform<Derived>::TransformOMPMerg > } > > template <typename Derived> > +OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause > *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; > > Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jul 22 21:27:21 2014 > @@ -1715,6 +1715,9 @@ OMPClause *OMPClauseReader::readClause() > case OMPC_mergeable: > C = new (Context) OMPMergeableClause(); > break; > + case OMPC_read: > + C = new (Context) OMPReadClause(); > + break; > case OMPC_private: > C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]); > break; > @@ -1809,6 +1812,8 @@ void OMPClauseReader::VisitOMPUntiedClau > > void OMPClauseReader::VisitOMPMergeableClause(OMPMergeableClause *) {} > > +void OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {} > + > 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jul 22 21:27:21 2014 > @@ -1735,6 +1735,8 @@ void OMPClauseWriter::VisitOMPUntiedClau > > void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {} > > +void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {} > + > 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/atomic_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/atomic_ast_print.cpp Tue Jul 22 21:27:21 2014 > @@ -11,23 +11,33 @@ T foo(T arg) { > T a; > #pragma omp atomic > a++; > +#pragma omp atomic read > + a = arg; > return T(); > } > > // CHECK: int a; > // CHECK-NEXT: #pragma omp atomic > // CHECK-NEXT: a++; > +// CHECK-NEXT: #pragma omp atomic read > +// CHECK-NEXT: a = arg; > // CHECK: T a; > // CHECK-NEXT: #pragma omp atomic > // CHECK-NEXT: a++; > +// CHECK-NEXT: #pragma omp atomic read > +// CHECK-NEXT: a = arg; > > int main(int argc, char **argv) { > int a; > // CHECK: int a; > #pragma omp atomic > a++; > +#pragma omp atomic read > + a = argc; > // CHECK-NEXT: #pragma omp atomic > // CHECK-NEXT: a++; > + // CHECK-NEXT: #pragma omp atomic read > + // CHECK-NEXT: 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=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/atomic_messages.cpp (original) > +++ cfe/trunk/test/OpenMP/atomic_messages.cpp Tue Jul 22 21:27:21 2014 > @@ -1,20 +1,47 @@ > // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s > > int foo() { > - L1: > - foo(); > - #pragma omp atomic > +L1: > + foo(); > +#pragma omp atomic > { > foo(); > goto L1; // expected-error {{use of undeclared label 'L1'}} > } > goto L2; // expected-error {{use of undeclared label 'L2'}} > - #pragma omp atomic > +#pragma omp atomic > { > foo(); > - L2: > + L2: > foo(); > } > > return 0; > } > + > +template <class T> > +T read() { > + T a, b = 0; > +// Test for atomic read > +#pragma omp atomic read > +// expected-error@+1 {{the statement for 'atomic read' must be an > expression statement of form 'v = x;', where v and x are both l-value > expressions with scalar type}} > + ; > +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain > more than one 'read' clause}} > +#pragma omp atomic read read > + a = b; > + > + return T(); > +} > + > +int read() { > + int a, b = 0; > +// Test for atomic read > +#pragma omp atomic read > +// expected-error@+1 {{the statement for 'atomic read' must be an > expression statement of form 'v = x;', where v and x are both l-value > expressions with scalar type}} > + ; > +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain > more than one 'read' clause}} > +#pragma omp atomic read read > + a = b; > + > + return read<int>(); > +} > > Modified: cfe/trunk/tools/libclang/CIndex.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213717&r1=213716&r2=213717&view=diff > > ============================================================================== > --- cfe/trunk/tools/libclang/CIndex.cpp (original) > +++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jul 22 21:27:21 2014 > @@ -1981,6 +1981,8 @@ void OMPClauseEnqueue::VisitOMPUntiedCla > > void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause > *) {} > > +void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {} > + > 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
