<div dir="ltr"><font face="arial, sans-serif">This looks good. The read  clause only adds v = x; as an expression. This structure is similar to:</font><br style="font-family:arial,sans-serif;font-size:13px"><div style="font-family:arial,sans-serif;font-size:13px">
<span style="font-size:18px">r213639 - [OPENMP] </span><span style="font-size:18px">Initial parsing and sema analysis for 'atomic' directive</span></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Tue, Jul 22, 2014 at 10:27 PM, Alexey Bataev <span dir="ltr"><<a href="mailto:a.bataev@hotmail.com" target="_blank">a.bataev@hotmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: abataev<br>
Date: Tue Jul 22 21:27:21 2014<br>
New Revision: 213717<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=213717&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=213717&view=rev</a><br>
Log:<br>
[OPENMP] Initial parsing and sema analysis for 'read' clause in 'atomic' directive.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/AST/OpenMPClause.h<br>
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/AST/StmtPrinter.cpp<br>
    cfe/trunk/lib/AST/StmtProfile.cpp<br>
    cfe/trunk/lib/Basic/OpenMPKinds.cpp<br>
    cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
    cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
    cfe/trunk/lib/Sema/TreeTransform.h<br>
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>
    cfe/trunk/test/OpenMP/atomic_ast_print.cpp<br>
    cfe/trunk/test/OpenMP/atomic_messages.cpp<br>
    cfe/trunk/tools/libclang/CIndex.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Tue Jul 22 21:27:21 2014<br>
@@ -2421,6 +2421,11 @@ RecursiveASTVisitor<Derived>::VisitOMPMe<br>
 }<br>
<br>
 template <typename Derived><br>
+bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {<br>
+  return true;<br>
+}<br>
+<br>
+template <typename Derived><br>
 template <typename T><br>
 bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {<br>
   for (auto *E : Node->varlists()) {<br>
<br>
Modified: cfe/trunk/include/clang/AST/OpenMPClause.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)<br>
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Tue Jul 22 21:27:21 2014<br>
@@ -770,6 +770,34 @@ public:<br>
   StmtRange children() { return StmtRange(); }<br>
 };<br>
<br>
+/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.<br>
+///<br>
+/// \code<br>
+/// #pragma omp atomic read<br>
+/// \endcode<br>
+/// In this example directive '#pragma omp atomic' has 'read' clause.<br>
+///<br>
+class OMPReadClause : public OMPClause {<br>
+public:<br>
+  /// \brief Build 'read' clause.<br>
+  ///<br>
+  /// \param StartLoc Starting location of the clause.<br>
+  /// \param EndLoc Ending location of the clause.<br>
+  ///<br>
+  OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)<br>
+      : OMPClause(OMPC_read, StartLoc, EndLoc) {}<br>
+<br>
+  /// \brief Build an empty clause.<br>
+  ///<br>
+  OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}<br>
+<br>
+  static bool classof(const OMPClause *T) {<br>
+    return T->getClauseKind() == OMPC_read;<br>
+  }<br>
+<br>
+  StmtRange children() { return StmtRange(); }<br>
+};<br>
+<br>
 /// \brief This represents clause 'private' in the '#pragma omp ...' directives.<br>
 ///<br>
 /// \code<br>
<br>
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jul 22 21:27:21 2014<br>
@@ -2443,6 +2443,11 @@ RecursiveASTVisitor<Derived>::VisitOMPMe<br>
 }<br>
<br>
 template <typename Derived><br>
+bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {<br>
+  return true;<br>
+}<br>
+<br>
+template <typename Derived><br>
 template <typename T><br>
 bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {<br>
   for (auto *E : Node->varlists()) {<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 22 21:27:21 2014<br>
@@ -7146,6 +7146,9 @@ def err_omp_parallel_sections_substmt_no<br>
   "statement in 'omp parallel sections' directive must be enclosed into a section region">;<br>
 def err_omp_parallel_reduction_in_task_firstprivate : Error<<br>
   "argument of a reduction clause of a %0 construct must not appear in a firstprivate clause on a task construct">;<br>
+def err_omp_atomic_read_not_expression_statement : Error<<br>
+  "the statement for 'atomic read' must be an expression statement of form 'v = x;',"<br>
+  " where v and x are both l-value expressions with scalar type">;<br>
 } // end of OpenMP category<br>
<br>
 let CategoryName = "Related Result Type Issue" in {<br>
<br>
Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)<br>
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Jul 22 21:27:21 2014<br>
@@ -101,6 +101,7 @@ OPENMP_CLAUSE(nowait, OMPNowaitClause)<br>
 OPENMP_CLAUSE(untied, OMPUntiedClause)<br>
 OPENMP_CLAUSE(mergeable, OMPMergeableClause)<br>
 OPENMP_CLAUSE(flush, OMPFlushClause)<br>
+OPENMP_CLAUSE(read, OMPReadClause)<br>
<br>
 // Clauses allowed for OpenMP directive 'parallel'.<br>
 OPENMP_PARALLEL_CLAUSE(if)<br>
@@ -198,6 +199,9 @@ OPENMP_TASK_CLAUSE(shared)<br>
 OPENMP_TASK_CLAUSE(untied)<br>
 OPENMP_TASK_CLAUSE(mergeable)<br>
<br>
+// TODO More clauses allowed for OpenMP directive 'atomic'.<br>
+OPENMP_ATOMIC_CLAUSE(read)<br>
+<br>
 #undef OPENMP_SCHEDULE_KIND<br>
 #undef OPENMP_PROC_BIND_KIND<br>
 #undef OPENMP_DEFAULT_KIND<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 22 21:27:21 2014<br>
@@ -7482,6 +7482,9 @@ public:<br>
   /// \brief Called on well-formed 'mergeable' clause.<br>
   OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc,<br>
                                         SourceLocation EndLoc);<br>
+  /// \brief Called on well-formed 'read' clause.<br>
+  OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc,<br>
+                                   SourceLocation EndLoc);<br>
<br>
   OMPClause *<br>
   ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars,<br>
<br>
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jul 22 21:27:21 2014<br>
@@ -665,6 +665,8 @@ void OMPClausePrinter::VisitOMPMergeable<br>
   OS << "mergeable";<br>
 }<br>
<br>
+void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }<br>
+<br>
 template<typename T><br>
 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {<br>
   for (typename T::varlist_iterator I = Node->varlist_begin(),<br>
<br>
Modified: cfe/trunk/lib/AST/StmtProfile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jul 22 21:27:21 2014<br>
@@ -310,6 +310,8 @@ void OMPClauseProfiler::VisitOMPUntiedCl<br>
<br>
 void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}<br>
<br>
+void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}<br>
+<br>
 template<typename T><br>
 void OMPClauseProfiler::VisitOMPClauseList(T *Node) {<br>
   for (auto *I : Node->varlists())<br>
<br>
Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)<br>
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Jul 22 21:27:21 2014<br>
@@ -108,6 +108,7 @@ unsigned clang::getOpenMPSimpleClauseTyp<br>
   case OMPC_untied:<br>
   case OMPC_mergeable:<br>
   case OMPC_flush:<br>
+  case OMPC_read:<br>
     break;<br>
   }<br>
   llvm_unreachable("Invalid OpenMP simple clause kind");<br>
@@ -167,6 +168,7 @@ const char *clang::getOpenMPSimpleClause<br>
   case OMPC_untied:<br>
   case OMPC_mergeable:<br>
   case OMPC_flush:<br>
+  case OMPC_read:<br>
     break;<br>
   }<br>
   llvm_unreachable("Invalid OpenMP simple clause kind");<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Jul 22 21:27:21 2014<br>
@@ -342,7 +342,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op<br>
 ///       | linear-clause | aligned-clause | collapse-clause |<br>
 ///       lastprivate-clause | reduction-clause | proc_bind-clause |<br>
 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |<br>
-///       mergeable-clause | flush-clause<br>
+///       mergeable-clause | flush-clause | read-clause<br>
 ///<br>
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,<br>
                                      OpenMPClauseKind CKind, bool FirstClause) {<br>
@@ -405,6 +405,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope<br>
   case OMPC_nowait:<br>
   case OMPC_untied:<br>
   case OMPC_mergeable:<br>
+  case OMPC_read:<br>
     // OpenMP [2.7.1, Restrictions, p. 9]<br>
     //  Only one ordered clause can appear on a loop directive.<br>
     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]<br>
@@ -527,6 +528,9 @@ OMPClause *Parser::ParseOpenMPSimpleClau<br>
 ///    mergeable-clause:<br>
 ///         'mergeable'<br>
 ///<br>
+///    read-clause:<br>
+///         'read'<br>
+///<br>
 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {<br>
   SourceLocation Loc = Tok.getLocation();<br>
   ConsumeAnyToken();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jul 22 21:27:21 2014<br>
@@ -92,15 +92,16 @@ private:<br>
     Scope *CurScope;<br>
     SourceLocation ConstructLoc;<br>
     bool OrderedRegion;<br>
+    SourceLocation AtomicClauseLoc;<br>
     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,<br>
                  Scope *CurScope, SourceLocation Loc)<br>
         : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),<br>
           Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),<br>
-          ConstructLoc(Loc), OrderedRegion(false) {}<br>
+          ConstructLoc(Loc), OrderedRegion(false), AtomicClauseLoc() {}<br>
     SharingMapTy()<br>
         : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),<br>
           Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),<br>
-          ConstructLoc(), OrderedRegion(false) {}<br>
+          ConstructLoc(), OrderedRegion(false), AtomicClauseLoc() {}<br>
   };<br>
<br>
   typedef SmallVector<SharingMapTy, 64> StackTy;<br>
@@ -207,6 +208,22 @@ public:<br>
     return false;<br>
   }<br>
<br>
+  /// \brief Checks if the 'atomic' construct has explicitly specified 'read',<br>
+  /// 'update', 'write' or 'capture' clause.<br>
+  bool hasAtomicClause() const {<br>
+    return Stack.back().AtomicClauseLoc.isValid();<br>
+  }<br>
+  /// \brief Gets location of explicitly specified clause for 'atomic'<br>
+  /// construct.<br>
+  SourceLocation getAtomicClauseLoc() const {<br>
+    return Stack.back().AtomicClauseLoc;<br>
+  }<br>
+  /// \brief Sets location of explicitly specified clause for 'atomic'<br>
+  /// directive.<br>
+  void setAtomicClauseLoc(SourceLocation Loc) {<br>
+    Stack.back().AtomicClauseLoc = Loc;<br>
+  }<br>
+<br>
   Scope *getCurScope() const { return Stack.back().CurScope; }<br>
   Scope *getCurScope() { return Stack.back().CurScope; }<br>
   SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }<br>
@@ -2379,12 +2396,22 @@ StmtResult Sema::ActOnOpenMPAtomicDirect<br>
                                             SourceLocation StartLoc,<br>
                                             SourceLocation EndLoc) {<br>
   assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");<br>
+  auto CS = cast<CapturedStmt>(AStmt);<br>
   // 1.2.2 OpenMP Language Terminology<br>
   // Structured block - An executable statement with a single entry at the<br>
   // top and a single exit at the bottom.<br>
   // The point of exit cannot be a branch out of the structured block.<br>
   // longjmp() and throw() must not violate the entry/exit criteria.<br>
   // TODO further analysis of associated statements and clauses.<br>
+  for (auto *C : Clauses) {<br>
+    if (C->getClauseKind() == OMPC_read) {<br>
+      if (!isa<Expr>(CS->getCapturedStmt())) {<br>
+          Diag(CS->getCapturedStmt()->getLocStart(),<br>
+               diag::err_omp_atomic_read_not_expression_statement);<br>
+        return StmtError();<br>
+      }<br>
+    }<br>
+  }<br>
<br>
   getCurFunction()->setHasBranchProtectedScope();<br>
<br>
@@ -2430,6 +2457,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl<br>
   case OMPC_mergeable:<br>
   case OMPC_threadprivate:<br>
   case OMPC_flush:<br>
+  case OMPC_read:<br>
   case OMPC_unknown:<br>
     llvm_unreachable("Clause is not allowed.");<br>
   }<br>
@@ -2633,6 +2661,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause<br>
   case OMPC_mergeable:<br>
   case OMPC_threadprivate:<br>
   case OMPC_flush:<br>
+  case OMPC_read:<br>
   case OMPC_unknown:<br>
     llvm_unreachable("Clause is not allowed.");<br>
   }<br>
@@ -2748,6 +2777,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi<br>
   case OMPC_mergeable:<br>
   case OMPC_threadprivate:<br>
   case OMPC_flush:<br>
+  case OMPC_read:<br>
   case OMPC_unknown:<br>
     llvm_unreachable("Clause is not allowed.");<br>
   }<br>
@@ -2827,6 +2857,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM<br>
   case OMPC_mergeable:<br>
     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);<br>
     break;<br>
+  case OMPC_read:<br>
+    Res = ActOnOpenMPReadClause(StartLoc, EndLoc);<br>
+    break;<br>
   case OMPC_if:<br>
   case OMPC_final:<br>
   case OMPC_num_threads:<br>
@@ -2873,6 +2906,12 @@ OMPClause *Sema::ActOnOpenMPMergeableCla<br>
   return new (Context) OMPMergeableClause(StartLoc, EndLoc);<br>
 }<br>
<br>
+OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,<br>
+                                       SourceLocation EndLoc) {<br>
+  DSAStack->setAtomicClauseLoc(StartLoc);<br>
+  return new (Context) OMPReadClause(StartLoc, EndLoc);<br>
+}<br>
+<br>
 OMPClause *Sema::ActOnOpenMPVarListClause(<br>
     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,<br>
     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,<br>
@@ -2926,6 +2965,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus<br>
   case OMPC_untied:<br>
   case OMPC_mergeable:<br>
   case OMPC_threadprivate:<br>
+  case OMPC_read:<br>
   case OMPC_unknown:<br>
     llvm_unreachable("Clause is not allowed.");<br>
   }<br>
@@ -4226,5 +4266,3 @@ OMPClause *Sema::ActOnOpenMPFlushClause(<br>
<br>
   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);<br>
 }<br>
-<br>
-#undef DSAStack<br>
<br>
Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jul 22 21:27:21 2014<br>
@@ -6762,6 +6762,12 @@ TreeTransform<Derived>::TransformOMPMerg<br>
 }<br>
<br>
 template <typename Derived><br>
+OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {<br>
+  // No need to rebuild this clause, no template-dependent parameters.<br>
+  return C;<br>
+}<br>
+<br>
+template <typename Derived><br>
 OMPClause *<br>
 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {<br>
   llvm::SmallVector<Expr *, 16> Vars;<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jul 22 21:27:21 2014<br>
@@ -1715,6 +1715,9 @@ OMPClause *OMPClauseReader::readClause()<br>
   case OMPC_mergeable:<br>
     C = new (Context) OMPMergeableClause();<br>
     break;<br>
+  case OMPC_read:<br>
+    C = new (Context) OMPReadClause();<br>
+    break;<br>
   case OMPC_private:<br>
     C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);<br>
     break;<br>
@@ -1809,6 +1812,8 @@ void OMPClauseReader::VisitOMPUntiedClau<br>
<br>
 void OMPClauseReader::VisitOMPMergeableClause(OMPMergeableClause *) {}<br>
<br>
+void OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {}<br>
+<br>
 void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {<br>
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));<br>
   unsigned NumVars = C->varlist_size();<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jul 22 21:27:21 2014<br>
@@ -1735,6 +1735,8 @@ void OMPClauseWriter::VisitOMPUntiedClau<br>
<br>
 void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}<br>
<br>
+void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}<br>
+<br>
 void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {<br>
   Record.push_back(C->varlist_size());<br>
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);<br>
<br>
Modified: cfe/trunk/test/OpenMP/atomic_ast_print.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_ast_print.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_ast_print.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/OpenMP/atomic_ast_print.cpp (original)<br>
+++ cfe/trunk/test/OpenMP/atomic_ast_print.cpp Tue Jul 22 21:27:21 2014<br>
@@ -11,23 +11,33 @@ T foo(T arg) {<br>
   T a;<br>
 #pragma omp atomic<br>
   a++;<br>
+#pragma omp atomic read<br>
+  a = arg;<br>
   return T();<br>
 }<br>
<br>
 // CHECK: int a;<br>
 // CHECK-NEXT: #pragma omp atomic<br>
 // CHECK-NEXT: a++;<br>
+// CHECK-NEXT: #pragma omp atomic read<br>
+// CHECK-NEXT: a = arg;<br>
 // CHECK: T a;<br>
 // CHECK-NEXT: #pragma omp atomic<br>
 // CHECK-NEXT: a++;<br>
+// CHECK-NEXT: #pragma omp atomic read<br>
+// CHECK-NEXT: a = arg;<br>
<br>
 int main(int argc, char **argv) {<br>
   int a;<br>
 // CHECK: int a;<br>
 #pragma omp atomic<br>
   a++;<br>
+#pragma omp atomic read<br>
+  a = argc;<br>
   // CHECK-NEXT: #pragma omp atomic<br>
   // CHECK-NEXT: a++;<br>
+  // CHECK-NEXT: #pragma omp atomic read<br>
+  // CHECK-NEXT: a = argc;<br>
   return foo(a);<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/OpenMP/atomic_messages.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_messages.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_messages.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/OpenMP/atomic_messages.cpp (original)<br>
+++ cfe/trunk/test/OpenMP/atomic_messages.cpp Tue Jul 22 21:27:21 2014<br>
@@ -1,20 +1,47 @@<br>
 // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s<br>
<br>
 int foo() {<br>
-  L1:<br>
-    foo();<br>
-  #pragma omp atomic<br>
+L1:<br>
+  foo();<br>
+#pragma omp atomic<br>
   {<br>
     foo();<br>
     goto L1; // expected-error {{use of undeclared label 'L1'}}<br>
   }<br>
   goto L2; // expected-error {{use of undeclared label 'L2'}}<br>
-  #pragma omp atomic<br>
+#pragma omp atomic<br>
   {<br>
     foo();<br>
-    L2:<br>
+  L2:<br>
     foo();<br>
   }<br>
<br>
   return 0;<br>
 }<br>
+<br>
+template <class T><br>
+T read() {<br>
+  T a, b = 0;<br>
+// Test for atomic read<br>
+#pragma omp atomic read<br>
+// 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}}<br>
+  ;<br>
+// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}<br>
+#pragma omp atomic read read<br>
+  a = b;<br>
+<br>
+  return T();<br>
+}<br>
+<br>
+int read() {<br>
+  int a, b = 0;<br>
+// Test for atomic read<br>
+#pragma omp atomic read<br>
+// 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}}<br>
+  ;<br>
+// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}<br>
+#pragma omp atomic read read<br>
+  a = b;<br>
+<br>
+  return read<int>();<br>
+}<br>
<br>
Modified: cfe/trunk/tools/libclang/CIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213717&r1=213716&r2=213717&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213717&r1=213716&r2=213717&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jul 22 21:27:21 2014<br>
@@ -1981,6 +1981,8 @@ void OMPClauseEnqueue::VisitOMPUntiedCla<br>
<br>
 void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}<br>
<br>
+void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}<br>
+<br>
 template<typename T><br>
 void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {<br>
   for (const auto *I : Node->varlists())<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>