<div dir="ltr">I reviewed this and the structure is again similar to the review for <br><h2>r212516 - [OPENMP] Parsing and sema analysis for 'omp parallel sections' directive.</h2><p><br></p><p>It seems good except<br>
</p><p><br></p><p>The testing seems sparse. For OMP atomic (in 4.0 at least), we support:</p><p>If clause is update or not present:<br>x++;<br>x--;<br>++x;<br>--x;<br>x binop= expr;<br>x = x binop expr;<br>x = expr binop x;</p>
<p><br></p><p>Shouldn't we test all these combinations? If they are there already and I missed them, then I apologize.  Thanks.<br></p><p><br></p><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 22, 2014 at 6:10 AM, 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 05:10:35 2014<br>
New Revision: 213639<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=213639&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=213639&view=rev</a><br>
Log:<br>
[OPENMP] Initial parsing and sema analysis for 'atomic' directive.<br>
<br>
Added:<br>
    cfe/trunk/test/OpenMP/atomic_ast_print.cpp   (with props)<br>
    cfe/trunk/test/OpenMP/atomic_messages.cpp   (with props)<br>
Modified:<br>
    cfe/trunk/include/clang-c/Index.h<br>
    cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/AST/StmtOpenMP.h<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
    cfe/trunk/include/clang/Basic/StmtNodes.td<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/AST/Stmt.cpp<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/CodeGen/CGStmt.cpp<br>
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.h<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/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
    cfe/trunk/tools/libclang/CIndex.cpp<br>
    cfe/trunk/tools/libclang/CXCursor.cpp<br>
<br>
Modified: cfe/trunk/include/clang-c/Index.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang-c/Index.h (original)<br>
+++ cfe/trunk/include/clang-c/Index.h Tue Jul 22 05:10:35 2014<br>
@@ -2190,14 +2190,18 @@ enum CXCursorKind {<br>
   /** \brief OpenMP flush directive.<br>
    */<br>
   CXCursor_OMPFlushDirective             = 246,<br>
-<br>
+<br>
   /** \brief OpenMP ordered directive.<br>
    */<br>
   CXCursor_OMPOrderedDirective           = 247,<br>
<br>
+  /** \brief OpenMP atomic directive.<br>
+   */<br>
+  CXCursor_OMPAtomicDirective            = 248,<br>
+<br>
   /** \brief Windows Structured Exception Handling's leave statement.<br>
    */<br>
-  CXCursor_SEHLeaveStmt                  = 248,<br>
+  CXCursor_SEHLeaveStmt                  = 249,<br>
<br>
   CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,<br>
<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Tue Jul 22 05:10:35 2014<br>
@@ -2329,6 +2329,9 @@ DEF_TRAVERSE_STMT(OMPFlushDirective,<br>
 DEF_TRAVERSE_STMT(OMPOrderedDirective,<br>
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })<br>
<br>
+DEF_TRAVERSE_STMT(OMPAtomicDirective,<br>
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })<br>
+<br>
 // OpenMP clauses.<br>
 template <typename Derived><br>
 bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jul 22 05:10:35 2014<br>
@@ -2351,6 +2351,9 @@ DEF_TRAVERSE_STMT(OMPFlushDirective,<br>
 DEF_TRAVERSE_STMT(OMPOrderedDirective,<br>
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })<br>
<br>
+DEF_TRAVERSE_STMT(OMPAtomicDirective,<br>
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })<br>
+<br>
 // OpenMP clauses.<br>
 template <typename Derived><br>
 bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {<br>
<br>
Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)<br>
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Tue Jul 22 05:10:35 2014<br>
@@ -1075,6 +1075,62 @@ public:<br>
   }<br>
 };<br>
<br>
+/// \brief This represents '#pragma omp atomic' directive.<br>
+///<br>
+/// \code<br>
+/// #pragma omp atomic capture<br>
+/// \endcode<br>
+/// In this example directive '#pragma omp atomic' has clause 'capture'.<br>
+///<br>
+class OMPAtomicDirective : public OMPExecutableDirective {<br>
+  friend class ASTStmtReader;<br>
+  /// \brief Build directive with the given start and end location.<br>
+  ///<br>
+  /// \param StartLoc Starting location of the directive kind.<br>
+  /// \param EndLoc Ending location of the directive.<br>
+  /// \param NumClauses Number of clauses.<br>
+  ///<br>
+  OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,<br>
+                     unsigned NumClauses)<br>
+      : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,<br>
+                               StartLoc, EndLoc, NumClauses, 1) {}<br>
+<br>
+  /// \brief Build an empty directive.<br>
+  ///<br>
+  /// \param NumClauses Number of clauses.<br>
+  ///<br>
+  explicit OMPAtomicDirective(unsigned NumClauses)<br>
+      : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,<br>
+                               SourceLocation(), SourceLocation(), NumClauses,<br>
+                               1) {}<br>
+<br>
+public:<br>
+  /// \brief Creates directive with a list of \a Clauses.<br>
+  ///<br>
+  /// \param C AST context.<br>
+  /// \param StartLoc Starting location of the directive kind.<br>
+  /// \param EndLoc Ending Location of the directive.<br>
+  /// \param Clauses List of clauses.<br>
+  /// \param AssociatedStmt Statement, associated with the directive.<br>
+  ///<br>
+  static OMPAtomicDirective *<br>
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,<br>
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);<br>
+<br>
+  /// \brief Creates an empty directive with the place for \a NumClauses<br>
+  /// clauses.<br>
+  ///<br>
+  /// \param C AST context.<br>
+  /// \param NumClauses Number of clauses.<br>
+  ///<br>
+  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,<br>
+                                         unsigned NumClauses, EmptyShell);<br>
+<br>
+  static bool classof(const Stmt *T) {<br>
+    return T->getStmtClass() == OMPAtomicDirectiveClass;<br>
+  }<br>
+};<br>
+<br>
 } // end namespace clang<br>
<br>
 #endif<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 22 05:10:35 2014<br>
@@ -7127,6 +7127,8 @@ def err_omp_prohibited_region : Error<<br>
   "; perhaps you forget to enclose 'omp %3' directive into a for or a parallel for region with 'ordered' clause?}2">;<br>
 def err_omp_prohibited_region_simd : Error<<br>
   "OpenMP constructs may not be nested inside a simd region">;<br>
+def err_omp_prohibited_region_atomic : Error<<br>
+  "OpenMP constructs may not be nested inside an atomic region">;<br>
 def err_omp_prohibited_region_critical_same_name : Error<<br>
   "cannot nest 'critical' regions having the same name %0">;<br>
 def note_omp_previous_critical_region : Note<<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)<br>
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Jul 22 05:10:35 2014<br>
@@ -45,6 +45,9 @@<br>
 #ifndef OPENMP_TASK_CLAUSE<br>
 #  define OPENMP_TASK_CLAUSE(Name)<br>
 #endif<br>
+#ifndef OPENMP_ATOMIC_CLAUSE<br>
+#  define OPENMP_ATOMIC_CLAUSE(Name)<br>
+#endif<br>
 #ifndef OPENMP_DEFAULT_KIND<br>
 #  define OPENMP_DEFAULT_KIND(Name)<br>
 #endif<br>
@@ -71,6 +74,7 @@ OPENMP_DIRECTIVE(barrier)<br>
 OPENMP_DIRECTIVE(taskwait)<br>
 OPENMP_DIRECTIVE(flush)<br>
 OPENMP_DIRECTIVE(ordered)<br>
+OPENMP_DIRECTIVE(atomic)<br>
 OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")<br>
 OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")<br>
<br>
@@ -206,6 +210,7 @@ OPENMP_TASK_CLAUSE(mergeable)<br>
 #undef OPENMP_PARALLEL_FOR_CLAUSE<br>
 #undef OPENMP_PARALLEL_SECTIONS_CLAUSE<br>
 #undef OPENMP_TASK_CLAUSE<br>
+#undef OPENMP_ATOMIC_CLAUSE<br>
 #undef OPENMP_SIMD_CLAUSE<br>
 #undef OPENMP_FOR_CLAUSE<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/StmtNodes.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)<br>
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Tue Jul 22 05:10:35 2014<br>
@@ -194,3 +194,4 @@ def OMPBarrierDirective : DStmt<OMPExecu<br>
 def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;<br>
 def OMPFlushDirective : DStmt<OMPExecutableDirective>;<br>
 def OMPOrderedDirective : DStmt<OMPExecutableDirective>;<br>
+def OMPAtomicDirective : DStmt<OMPExecutableDirective>;<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 22 05:10:35 2014<br>
@@ -7395,10 +7395,15 @@ public:<br>
   StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,<br>
                                        SourceLocation StartLoc,<br>
                                        SourceLocation EndLoc);<br>
-  /// \brief Called on well-formed '\#pragma omp master' after parsing of the<br>
+  /// \brief Called on well-formed '\#pragma omp ordered' after parsing of the<br>
   /// associated statement.<br>
   StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc,<br>
                                          SourceLocation EndLoc);<br>
+  /// \brief Called on well-formed '\#pragma omp atomic' after parsing of the<br>
+  /// associated statement.<br>
+  StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,<br>
+                                        Stmt *AStmt, SourceLocation StartLoc,<br>
+                                        SourceLocation EndLoc);<br>
<br>
   OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,<br>
                                          Expr *Expr,<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Jul 22 05:10:35 2014<br>
@@ -1356,6 +1356,7 @@ namespace clang {<br>
       STMT_OMP_TASKWAIT_DIRECTIVE,<br>
       STMT_OMP_FLUSH_DIRECTIVE,<br>
       STMT_OMP_ORDERED_DIRECTIVE,<br>
+      STMT_OMP_ATOMIC_DIRECTIVE,<br>
<br>
       // ARC<br>
       EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr<br>
<br>
Modified: cfe/trunk/lib/AST/Stmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/Stmt.cpp (original)<br>
+++ cfe/trunk/lib/AST/Stmt.cpp Tue Jul 22 05:10:35 2014<br>
@@ -1698,3 +1698,29 @@ OMPOrderedDirective *OMPOrderedDirective<br>
   return new (Mem) OMPOrderedDirective();<br>
 }<br>
<br>
+OMPAtomicDirective *OMPAtomicDirective::Create(const ASTContext &C,<br>
+                                               SourceLocation StartLoc,<br>
+                                               SourceLocation EndLoc,<br>
+                                               ArrayRef<OMPClause *> Clauses,<br>
+                                               Stmt *AssociatedStmt) {<br>
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective),<br>
+                                           llvm::alignOf<OMPClause *>());<br>
+  void *Mem =<br>
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));<br>
+  OMPAtomicDirective *Dir =<br>
+      new (Mem) OMPAtomicDirective(StartLoc, EndLoc, Clauses.size());<br>
+  Dir->setClauses(Clauses);<br>
+  Dir->setAssociatedStmt(AssociatedStmt);<br>
+  return Dir;<br>
+}<br>
+<br>
+OMPAtomicDirective *OMPAtomicDirective::CreateEmpty(const ASTContext &C,<br>
+                                                    unsigned NumClauses,<br>
+                                                    EmptyShell) {<br>
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective),<br>
+                                           llvm::alignOf<OMPClause *>());<br>
+  void *Mem =<br>
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));<br>
+  return new (Mem) OMPAtomicDirective(NumClauses);<br>
+}<br>
+<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jul 22 05:10:35 2014<br>
@@ -891,6 +891,11 @@ void StmtPrinter::VisitOMPOrderedDirecti<br>
   PrintOMPExecutableDirective(Node);<br>
 }<br>
<br>
+void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {<br>
+  Indent() << "#pragma omp atomic ";<br>
+  PrintOMPExecutableDirective(Node);<br>
+}<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 //  Expr printing methods.<br>
 //===----------------------------------------------------------------------===//<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jul 22 05:10:35 2014<br>
@@ -435,6 +435,10 @@ void StmtProfiler::VisitOMPOrderedDirect<br>
   VisitOMPExecutableDirective(S);<br>
 }<br>
<br>
+void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {<br>
+  VisitOMPExecutableDirective(S);<br>
+}<br>
+<br>
 void StmtProfiler::VisitExpr(const Expr *S) {<br>
   VisitStmt(S);<br>
 }<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)<br>
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Jul 22 05:10:35 2014<br>
@@ -260,6 +260,16 @@ bool clang::isAllowedClauseForDirective(<br>
   case OMPD_flush:<br>
     return CKind == OMPC_flush;<br>
     break;<br>
+  case OMPD_atomic:<br>
+    switch (CKind) {<br>
+#define OPENMP_ATOMIC_CLAUSE(Name)                                             \<br>
+  case OMPC_##Name:                                                            \<br>
+    return true;<br>
+#include "clang/Basic/OpenMPKinds.def"<br>
+    default:<br>
+      break;<br>
+    }<br>
+    break;<br>
   case OMPD_unknown:<br>
   case OMPD_threadprivate:<br>
   case OMPD_section:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Jul 22 05:10:35 2014<br>
@@ -224,6 +224,9 @@ void CodeGenFunction::EmitStmt(const Stm<br>
   case Stmt::OMPOrderedDirectiveClass:<br>
     EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S));<br>
     break;<br>
+  case Stmt::OMPAtomicDirectiveClass:<br>
+    EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S));<br>
+    break;<br>
   }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Jul 22 05:10:35 2014<br>
@@ -132,3 +132,7 @@ void CodeGenFunction::EmitOMPOrderedDire<br>
   llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");<br>
 }<br>
<br>
+void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {<br>
+  llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");<br>
+}<br>
+<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jul 22 05:10:35 2014<br>
@@ -1937,6 +1937,7 @@ public:<br>
   void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);<br>
   void EmitOMPFlushDirective(const OMPFlushDirective &S);<br>
   void EmitOMPOrderedDirective(const OMPOrderedDirective &S);<br>
+  void EmitOMPAtomicDirective(const OMPAtomicDirective &S);<br>
<br>
   //===--------------------------------------------------------------------===//<br>
   //                         LValue Expression Emission<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Jul 22 05:10:35 2014<br>
@@ -96,6 +96,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen<br>
   case OMPD_critical:<br>
   case OMPD_parallel_for:<br>
   case OMPD_parallel_sections:<br>
+  case OMPD_atomic:<br>
     Diag(Tok, diag::err_omp_unexpected_directive)<br>
         << getOpenMPDirectiveName(DKind);<br>
     break;<br>
@@ -114,7 +115,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen<br>
 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |<br>
 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |<br>
 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |<br>
-///         'barrier' | 'taskwait' | 'flush' | 'ordered' {clause}<br>
+///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' {clause}<br>
 ///         annot_pragma_openmp_end<br>
 ///<br>
 StmtResult<br>
@@ -179,7 +180,8 @@ Parser::ParseOpenMPDeclarativeOrExecutab<br>
   case OMPD_parallel_for:<br>
   case OMPD_parallel_sections:<br>
   case OMPD_task:<br>
-  case OMPD_ordered: {<br>
+  case OMPD_ordered:<br>
+  case OMPD_atomic: {<br>
     ConsumeToken();<br>
     // Parse directive name of the 'critical' directive if any.<br>
     if (DKind == OMPD_critical) {<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jul 22 05:10:35 2014<br>
@@ -1114,6 +1114,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP<br>
                              Params);<br>
     break;<br>
   }<br>
+  case OMPD_atomic: {<br>
+    Sema::CapturedParamNameType Params[] = {<br>
+        std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
+    };<br>
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+                             Params);<br>
+    break;<br>
+  }<br>
   case OMPD_threadprivate:<br>
     llvm_unreachable("OpenMP Directive is not allowed");<br>
   case OMPD_unknown:<br>
@@ -1145,6 +1153,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | parallel         | taskwait        | *                                  |<br>
   // | parallel         | flush           | *                                  |<br>
   // | parallel         | ordered         | +                                  |<br>
+  // | parallel         | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | for              | parallel        | *                                  |<br>
   // | for              | for             | +                                  |<br>
@@ -1162,6 +1171,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | for              | taskwait        | *                                  |<br>
   // | for              | flush           | *                                  |<br>
   // | for              | ordered         | * (if construct is ordered)        |<br>
+  // | for              | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | master           | parallel        | *                                  |<br>
   // | master           | for             | +                                  |<br>
@@ -1179,6 +1189,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | master           | taskwait        | *                                  |<br>
   // | master           | flush           | *                                  |<br>
   // | master           | ordered         | +                                  |<br>
+  // | master           | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | critical         | parallel        | *                                  |<br>
   // | critical         | for             | +                                  |<br>
@@ -1195,6 +1206,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | critical         | barrier         | +                                  |<br>
   // | critical         | taskwait        | *                                  |<br>
   // | critical         | ordered         | +                                  |<br>
+  // | critical         | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | simd             | parallel        |                                    |<br>
   // | simd             | for             |                                    |<br>
@@ -1212,6 +1224,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | simd             | taskwait        |                                    |<br>
   // | simd             | flush           |                                    |<br>
   // | simd             | ordered         |                                    |<br>
+  // | simd             | atomic          |                                    |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | sections         | parallel        | *                                  |<br>
   // | sections         | for             | +                                  |<br>
@@ -1229,6 +1242,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | sections         | taskwait        | *                                  |<br>
   // | sections         | flush           | *                                  |<br>
   // | sections         | ordered         | +                                  |<br>
+  // | sections         | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | section          | parallel        | *                                  |<br>
   // | section          | for             | +                                  |<br>
@@ -1246,6 +1260,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | section          | taskwait        | *                                  |<br>
   // | section          | flush           | *                                  |<br>
   // | section          | ordered         | +                                  |<br>
+  // | section          | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | single           | parallel        | *                                  |<br>
   // | single           | for             | +                                  |<br>
@@ -1263,6 +1278,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | single           | taskwait        | *                                  |<br>
   // | single           | flush           | *                                  |<br>
   // | single           | ordered         | +                                  |<br>
+  // | single           | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | parallel for     | parallel        | *                                  |<br>
   // | parallel for     | for             | +                                  |<br>
@@ -1280,6 +1296,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | parallel for     | taskwait        | *                                  |<br>
   // | parallel for     | flush           | *                                  |<br>
   // | parallel for     | ordered         | * (if construct is ordered)        |<br>
+  // | parallel for     | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | parallel sections| parallel        | *                                  |<br>
   // | parallel sections| for             | +                                  |<br>
@@ -1297,6 +1314,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | parallel sections| taskwait        | *                                  |<br>
   // | parallel sections| flush           | *                                  |<br>
   // | parallel sections| ordered         | +                                  |<br>
+  // | parallel sections| atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | task             | parallel        | *                                  |<br>
   // | task             | for             | +                                  |<br>
@@ -1314,6 +1332,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | task             | taskwait        | *                                  |<br>
   // | task             | flush           | *                                  |<br>
   // | task             | ordered         | +                                  |<br>
+  // | task             | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   // | ordered          | parallel        | *                                  |<br>
   // | ordered          | for             | +                                  |<br>
@@ -1331,6 +1350,7 @@ static bool CheckNestingOfRegions(Sema &<br>
   // | ordered          | taskwait        | *                                  |<br>
   // | ordered          | flush           | *                                  |<br>
   // | ordered          | ordered         | +                                  |<br>
+  // | ordered          | atomic          | *                                  |<br>
   // +------------------+-----------------+------------------------------------+<br>
   if (Stack->getCurScope()) {<br>
     auto ParentRegion = Stack->getParentDirective();<br>
@@ -1347,6 +1367,12 @@ static bool CheckNestingOfRegions(Sema &<br>
       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);<br>
       return true;<br>
     }<br>
+    if (ParentRegion == OMPD_atomic) {<br>
+      // OpenMP [2.16, Nesting of Regions]<br>
+      // OpenMP constructs may not be nested inside an atomic region.<br>
+      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);<br>
+      return true;<br>
+    }<br>
     if (CurrentRegion == OMPD_section) {<br>
       // OpenMP [2.7.2, sections Construct, Restrictions]<br>
       // Orphaned section directives are prohibited. That is, the section<br>
@@ -1368,7 +1394,7 @@ static bool CheckNestingOfRegions(Sema &<br>
     if (CurrentRegion == OMPD_master) {<br>
       // OpenMP [2.16, Nesting of Regions]<br>
       // A master region may not be closely nested inside a worksharing,<br>
-      // atomic (TODO), or explicit task region.<br>
+      // atomic, or explicit task region.<br>
       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||<br>
                           ParentRegion == OMPD_task;<br>
     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {<br>
@@ -1403,7 +1429,7 @@ static bool CheckNestingOfRegions(Sema &<br>
     } else if (CurrentRegion == OMPD_barrier) {<br>
       // OpenMP [2.16, Nesting of Regions]<br>
       // A barrier region may not be closely nested inside a worksharing,<br>
-      // explicit task, critical, ordered, atomic(TODO), or master region.<br>
+      // explicit task, critical, ordered, atomic, or master region.<br>
       NestingProhibited =<br>
           isOpenMPWorksharingDirective(ParentRegion) ||<br>
           ParentRegion == OMPD_task || ParentRegion == OMPD_master ||<br>
@@ -1414,7 +1440,6 @@ static bool CheckNestingOfRegions(Sema &<br>
       // OpenMP [2.16, Nesting of Regions]<br>
       // A worksharing region may not be closely nested inside a worksharing,<br>
       // explicit task, critical, ordered, atomic, or master region.<br>
-      // TODO<br>
       NestingProhibited =<br>
           (isOpenMPWorksharingDirective(ParentRegion) &&<br>
            !isOpenMPSimdDirective(ParentRegion)) ||<br>
@@ -1424,7 +1449,7 @@ static bool CheckNestingOfRegions(Sema &<br>
     } else if (CurrentRegion == OMPD_ordered) {<br>
       // OpenMP [2.16, Nesting of Regions]<br>
       // An ordered region may not be closely nested inside a critical,<br>
-      // atomic(TODO), or explicit task region.<br>
+      // atomic, or explicit task region.<br>
       // An ordered region must be closely nested inside a loop region (or<br>
       // parallel loop region) with an ordered clause.<br>
       NestingProhibited = ParentRegion == OMPD_critical ||<br>
@@ -1558,6 +1583,10 @@ StmtResult Sema::ActOnOpenMPExecutableDi<br>
            "No clauses are allowed for 'omp ordered' directive");<br>
     Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc);<br>
     break;<br>
+  case OMPD_atomic:<br>
+    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,<br>
+                                     EndLoc);<br>
+    break;<br>
   case OMPD_threadprivate:<br>
     llvm_unreachable("OpenMP Directive is not allowed");<br>
   case OMPD_unknown:<br>
@@ -2345,6 +2374,23 @@ StmtResult Sema::ActOnOpenMPOrderedDirec<br>
   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt);<br>
 }<br>
<br>
+StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,<br>
+                                            Stmt *AStmt,<br>
+                                            SourceLocation StartLoc,<br>
+                                            SourceLocation EndLoc) {<br>
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");<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>
+<br>
+  getCurFunction()->setHasBranchProtectedScope();<br>
+<br>
+  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);<br>
+}<br>
+<br>
 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,<br>
                                              SourceLocation StartLoc,<br>
                                              SourceLocation LParenLoc,<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jul 22 05:10:35 2014<br>
@@ -6644,6 +6644,17 @@ TreeTransform<Derived>::TransformOMPOrde<br>
   return Res;<br>
 }<br>
<br>
+template <typename Derived><br>
+StmtResult<br>
+TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {<br>
+  DeclarationNameInfo DirName;<br>
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr,<br>
+                                             D->getLocStart());<br>
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
+  return Res;<br>
+}<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // OpenMP clause transformation<br>
 //===----------------------------------------------------------------------===//<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jul 22 05:10:35 2014<br>
@@ -2036,6 +2036,13 @@ void ASTStmtReader::VisitOMPOrderedDirec<br>
   VisitOMPExecutableDirective(D);<br>
 }<br>
<br>
+void ASTStmtReader::VisitOMPAtomicDirective(OMPAtomicDirective *D) {<br>
+  VisitStmt(D);<br>
+  // The NumClauses field was read in ReadStmtFromStream.<br>
+  ++Idx;<br>
+  VisitOMPExecutableDirective(D);<br>
+}<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // ASTReader Implementation<br>
 //===----------------------------------------------------------------------===//<br>
@@ -2595,6 +2602,11 @@ Stmt *ASTReader::ReadStmtFromStream(Modu<br>
       S = OMPOrderedDirective::CreateEmpty(Context, Empty);<br>
       break;<br>
<br>
+    case STMT_OMP_ATOMIC_DIRECTIVE:<br>
+      S = OMPAtomicDirective::CreateEmpty(<br>
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);<br>
+      break;<br>
+<br>
     case EXPR_CXX_OPERATOR_CALL:<br>
       S = new (Context) CXXOperatorCallExpr(Context, Empty);<br>
       break;<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jul 22 05:10:35 2014<br>
@@ -1905,6 +1905,13 @@ void ASTStmtWriter::VisitOMPTaskDirectiv<br>
   Code = serialization::STMT_OMP_TASK_DIRECTIVE;<br>
 }<br>
<br>
+void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {<br>
+  VisitStmt(D);<br>
+  Record.push_back(D->getNumClauses());<br>
+  VisitOMPExecutableDirective(D);<br>
+  Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;<br>
+}<br>
+<br>
 void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {<br>
   VisitStmt(D);<br>
   VisitOMPExecutableDirective(D);<br>
<br>
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)<br>
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul 22 05:10:35 2014<br>
@@ -747,6 +747,7 @@ void ExprEngine::Visit(const Stmt *S, Ex<br>
     case Stmt::OMPTaskwaitDirectiveClass:<br>
     case Stmt::OMPFlushDirectiveClass:<br>
     case Stmt::OMPOrderedDirectiveClass:<br>
+    case Stmt::OMPAtomicDirectiveClass:<br>
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");<br>
<br>
     case Stmt::ObjCSubscriptRefExprClass:<br>
<br>
Added: 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=213639&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_ast_print.cpp?rev=213639&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/OpenMP/atomic_ast_print.cpp (added)<br>
+++ cfe/trunk/test/OpenMP/atomic_ast_print.cpp Tue Jul 22 05:10:35 2014<br>
@@ -0,0 +1,34 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s<br>
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s<br>
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s<br>
+// expected-no-diagnostics<br>
+<br>
+#ifndef HEADER<br>
+#define HEADER<br>
+<br>
+template <class T><br>
+T foo(T arg) {<br>
+  T a;<br>
+#pragma omp atomic<br>
+  a++;<br>
+  return T();<br>
+}<br>
+<br>
+// CHECK: int a;<br>
+// CHECK-NEXT: #pragma omp atomic<br>
+// CHECK-NEXT: a++;<br>
+// CHECK: T a;<br>
+// CHECK-NEXT: #pragma omp atomic<br>
+// CHECK-NEXT: a++;<br>
+<br>
+int main(int argc, char **argv) {<br>
+  int a;<br>
+// CHECK: int a;<br>
+#pragma omp atomic<br>
+  a++;<br>
+  // CHECK-NEXT: #pragma omp atomic<br>
+  // CHECK-NEXT: a++;<br>
+  return foo(a);<br>
+}<br>
+<br>
+#endif<br>
<br>
Propchange: cfe/trunk/test/OpenMP/atomic_ast_print.cpp<br>
------------------------------------------------------------------------------<br>
    svn:eol-style = native<br>
<br>
Propchange: cfe/trunk/test/OpenMP/atomic_ast_print.cpp<br>
------------------------------------------------------------------------------<br>
    svn:keywords = Author Date Id Rev URL<br>
<br>
Propchange: cfe/trunk/test/OpenMP/atomic_ast_print.cpp<br>
------------------------------------------------------------------------------<br>
    svn:mime-type = text/plain<br>
<br>
Added: 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=213639&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_messages.cpp?rev=213639&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/OpenMP/atomic_messages.cpp (added)<br>
+++ cfe/trunk/test/OpenMP/atomic_messages.cpp Tue Jul 22 05:10:35 2014<br>
@@ -0,0 +1,20 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s<br>
+<br>
+int foo() {<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>
+  {<br>
+    foo();<br>
+    L2:<br>
+    foo();<br>
+  }<br>
+<br>
+  return 0;<br>
+}<br>
<br>
Propchange: cfe/trunk/test/OpenMP/atomic_messages.cpp<br>
------------------------------------------------------------------------------<br>
    svn:eol-style = native<br>
<br>
Propchange: cfe/trunk/test/OpenMP/atomic_messages.cpp<br>
------------------------------------------------------------------------------<br>
    svn:keywords = Author Date Id Rev URL<br>
<br>
Propchange: cfe/trunk/test/OpenMP/atomic_messages.cpp<br>
------------------------------------------------------------------------------<br>
    svn:mime-type = text/plain<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=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jul 22 05:10:35 2014<br>
@@ -1872,6 +1872,7 @@ public:<br>
   void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);<br>
   void VisitOMPFlushDirective(const OMPFlushDirective *D);<br>
   void VisitOMPOrderedDirective(const OMPOrderedDirective *D);<br>
+  void VisitOMPAtomicDirective(const OMPAtomicDirective *D);<br>
<br>
 private:<br>
   void AddDeclarationNameInfo(const Stmt *S);<br>
@@ -2378,6 +2379,10 @@ void EnqueueVisitor::VisitOMPOrderedDire<br>
   VisitOMPExecutableDirective(D);<br>
 }<br>
<br>
+void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {<br>
+  VisitOMPExecutableDirective(D);<br>
+}<br>
+<br>
 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {<br>
   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);<br>
 }<br>
@@ -4082,6 +4087,8 @@ CXString clang_getCursorKindSpelling(enu<br>
     return cxstring::createRef("OMPFlushDirective");<br>
   case CXCursor_OMPOrderedDirective:<br>
     return cxstring::createRef("OMPOrderedDirective");<br>
+  case CXCursor_OMPAtomicDirective:<br>
+    return cxstring::createRef("OMPAtomicDirective");<br>
   }<br>
<br>
   llvm_unreachable("Unhandled CXCursorKind");<br>
<br>
Modified: cfe/trunk/tools/libclang/CXCursor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=213639&r1=213638&r2=213639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=213639&r1=213638&r2=213639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Jul 22 05:10:35 2014<br>
@@ -565,6 +565,9 @@ CXCursor cxcursor::MakeCXCursor(const St<br>
   case Stmt::OMPOrderedDirectiveClass:<br>
     K = CXCursor_OMPOrderedDirective;<br>
     break;<br>
+  case Stmt::OMPAtomicDirectiveClass:<br>
+    K = CXCursor_OMPAtomicDirective;<br>
+    break;<br>
   }<br>
<br>
   CXCursor C = { K, 0, { Parent, S, TU } };<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>