r213512 - [OPENMP] Initial parsing and sema analysis for 'flush' directive.

Alexey Bataev a.bataev at hotmail.com
Mon Jul 21 04:26:12 PDT 2014


Author: abataev
Date: Mon Jul 21 06:26:11 2014
New Revision: 213512

URL: http://llvm.org/viewvc/llvm-project?rev=213512&view=rev
Log:
[OPENMP] Initial parsing and sema analysis for 'flush' directive.

Added:
    cfe/trunk/test/OpenMP/flush_ast_print.cpp   (with props)
    cfe/trunk/test/OpenMP/flush_messages.cpp   (with props)
Modified:
    cfe/trunk/include/clang-c/Index.h
    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/AST/StmtOpenMP.h
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/OpenMPKinds.def
    cfe/trunk/include/clang/Basic/StmtNodes.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/Basic/OpenMPKinds.cpp
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    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/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/OpenMP/nesting_of_regions.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Mon Jul 21 06:26:11 2014
@@ -2187,9 +2187,13 @@ enum CXCursorKind {
    */
   CXCursor_OMPTaskwaitDirective          = 245,
 
+  /** \brief OpenMP flush directive.
+   */
+  CXCursor_OMPFlushDirective             = 246,
+
   /** \brief Windows Structured Exception Handling's leave statement.
    */
-  CXCursor_SEHLeaveStmt                  = 246,
+  CXCursor_SEHLeaveStmt                  = 247,
 
   CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,
 

Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Mon Jul 21 06:26:11 2014
@@ -2323,6 +2323,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
 DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
 // OpenMP clauses.
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2481,6 +2484,12 @@ RecursiveASTVisitor<Derived>::VisitOMPRe
   TRY_TO(VisitOMPClauseList(C));
   return true;
 }
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
 
 // FIXME: look at the following tricky-seeming exprs to see if we
 // need to recurse on anything.  These are ones that have methods

Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Mon Jul 21 06:26:11 2014
@@ -1390,6 +1390,66 @@ public:
   }
 };
 
+/// \brief This represents pseudo clause 'flush' for the '#pragma omp flush'
+/// directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has pseudo clause 'flush'
+/// with the variables 'a' and 'b'.
+///
+class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                 SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
+                                         EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPFlushClause(unsigned N)
+      : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+                                         SourceLocation(), SourceLocation(),
+                                         N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                SourceLocation LParenLoc, SourceLocation EndLoc,
+                                ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_flush;
+  }
+};
+
 } // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jul 21 06:26:11 2014
@@ -2345,6 +2345,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
 DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
 // OpenMP clauses.
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2503,6 +2506,12 @@ RecursiveASTVisitor<Derived>::VisitOMPRe
   TRY_TO(VisitOMPClauseList(C));
   return true;
 }
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
 
 // FIXME: look at the following tricky-seeming exprs to see if we
 // need to recurse on anything.  These are ones that have methods

Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Mon Jul 21 06:26:11 2014
@@ -969,6 +969,65 @@ public:
   }
 };
 
+/// \brief This represents '#pragma omp flush' directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
+/// and 'b'.
+/// 'omp flush' directive does not have clauses but have an optional list of
+/// variables to flush. This list of variables is stored within some fake clause
+/// FlushClause.
+class OMPFlushDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                    unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+                               StartLoc, EndLoc, NumClauses, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPFlushDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               0) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses (only single OMPFlushClause clause is
+  /// allowed).
+  ///
+  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                   SourceLocation EndLoc,
+                                   ArrayRef<OMPClause *> Clauses);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
+                                        unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPFlushDirectiveClass;
+  }
+};
+
 } // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Jul 21 06:26:11 2014
@@ -903,7 +903,7 @@ def err_omp_unknown_directive : Error<
 def err_omp_unexpected_directive : Error<
   "unexpected OpenMP directive '#pragma omp %0'">;
 def err_omp_expected_punc : Error<
-  "expected ',' or ')' in '%0' clause">;
+  "expected ',' or ')' in '%0' %select{clause|directive}1">;
 def err_omp_unexpected_clause : Error<
   "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
 def err_omp_more_one_clause : Error<

Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Mon Jul 21 06:26:11 2014
@@ -69,6 +69,7 @@ OPENMP_DIRECTIVE(critical)
 OPENMP_DIRECTIVE(taskyield)
 OPENMP_DIRECTIVE(barrier)
 OPENMP_DIRECTIVE(taskwait)
+OPENMP_DIRECTIVE(flush)
 OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
 OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
 
@@ -94,6 +95,7 @@ OPENMP_CLAUSE(ordered, OMPOrderedClause)
 OPENMP_CLAUSE(nowait, OMPNowaitClause)
 OPENMP_CLAUSE(untied, OMPUntiedClause)
 OPENMP_CLAUSE(mergeable, OMPMergeableClause)
+OPENMP_CLAUSE(flush, OMPFlushClause)
 
 // Clauses allowed for OpenMP directive 'parallel'.
 OPENMP_PARALLEL_CLAUSE(if)

Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Mon Jul 21 06:26:11 2014
@@ -192,3 +192,4 @@ def OMPTaskDirective : DStmt<OMPExecutab
 def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
 def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
 def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
+def OMPFlushDirective : DStmt<OMPExecutableDirective>;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul 21 06:26:11 2014
@@ -7382,7 +7382,11 @@ public:
                                          SourceLocation EndLoc);
   /// \brief Called on well-formed '\#pragma omp taskwait'.
   StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
-                                         SourceLocation EndLoc);
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp flush'.
+  StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
+                                       SourceLocation StartLoc,
+                                       SourceLocation EndLoc);
 
   OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                          Expr *Expr,
@@ -7520,6 +7524,11 @@ public:
                                           SourceLocation StartLoc,
                                           SourceLocation LParenLoc,
                                           SourceLocation EndLoc);
+  /// \brief Called on well-formed 'flush' pseudo clause.
+  OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
+                                    SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation EndLoc);
 
   /// \brief The kind of conversion being performed.
   enum CheckedConversionKind {

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Jul 21 06:26:11 2014
@@ -1354,6 +1354,7 @@ namespace clang {
       STMT_OMP_TASKYIELD_DIRECTIVE,
       STMT_OMP_BARRIER_DIRECTIVE,
       STMT_OMP_TASKWAIT_DIRECTIVE,
+      STMT_OMP_FLUSH_DIRECTIVE,
 
       // ARC
       EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Mon Jul 21 06:26:11 2014
@@ -1327,6 +1327,27 @@ OMPReductionClause *OMPReductionClause::
   return new (Mem) OMPReductionClause(N);
 }
 
+OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc,
+                                       ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPFlushClause *Clause =
+      new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPFlushClause(N);
+}
+
 OMPParallelDirective *OMPParallelDirective::Create(
                                               const ASTContext &C,
                                               SourceLocation StartLoc,
@@ -1635,3 +1656,25 @@ OMPTaskwaitDirective *OMPTaskwaitDirecti
   return new (Mem) OMPTaskwaitDirective();
 }
 
+OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
+                                             SourceLocation StartLoc,
+                                             SourceLocation EndLoc,
+                                             ArrayRef<OMPClause *> Clauses) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size());
+  OMPFlushDirective *Dir =
+      new (Mem) OMPFlushDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  return Dir;
+}
+
+OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C,
+                                                  unsigned NumClauses,
+                                                  EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses);
+  return new (Mem) OMPFlushDirective(NumClauses);
+}
+

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jul 21 06:26:11 2014
@@ -775,6 +775,12 @@ void OMPClausePrinter::VisitOMPCopypriva
   }
 }
 
+void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
+  if (!Node->varlist_empty()) {
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
 }
 
 //===----------------------------------------------------------------------===//
@@ -875,6 +881,11 @@ void StmtPrinter::VisitOMPTaskwaitDirect
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
+  Indent() << "#pragma omp flush ";
+  PrintOMPExecutableDirective(Node);
+}
+
 //===----------------------------------------------------------------------===//
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Mon Jul 21 06:26:11 2014
@@ -352,6 +352,9 @@ void
 OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
+  VisitOMPClauseList(C);
+}
 }
 
 void
@@ -424,6 +427,10 @@ void StmtProfiler::VisitOMPTaskwaitDirec
   VisitOMPExecutableDirective(S);
 }
 
+void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
 void StmtProfiler::VisitExpr(const Expr *S) {
   VisitStmt(S);
 }

Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Mon Jul 21 06:26:11 2014
@@ -46,6 +46,8 @@ const char *clang::getOpenMPDirectiveNam
 }
 
 OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
+  if (Str == "flush")
+    return OMPC_unknown;
   return llvm::StringSwitch<OpenMPClauseKind>(Str)
 #define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
 #include "clang/Basic/OpenMPKinds.def"
@@ -105,6 +107,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
   case OMPC_nowait:
   case OMPC_untied:
   case OMPC_mergeable:
+  case OMPC_flush:
     break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -163,6 +166,7 @@ const char *clang::getOpenMPSimpleClause
   case OMPC_nowait:
   case OMPC_untied:
   case OMPC_mergeable:
+  case OMPC_flush:
     break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -253,6 +257,9 @@ bool clang::isAllowedClauseForDirective(
       break;
     }
     break;
+  case OMPD_flush:
+    return CKind == OMPC_flush;
+    break;
   case OMPD_unknown:
   case OMPD_threadprivate:
   case OMPD_section:

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Mon Jul 21 06:26:11 2014
@@ -218,6 +218,9 @@ void CodeGenFunction::EmitStmt(const Stm
   case Stmt::OMPTaskwaitDirectiveClass:
     EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S));
     break;
+  case Stmt::OMPFlushDirectiveClass:
+    EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
+    break;
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Mon Jul 21 06:26:11 2014
@@ -124,3 +124,7 @@ void CodeGenFunction::EmitOMPTaskwaitDir
   llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
 }
 
+void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
+  llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
+}
+

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Jul 21 06:26:11 2014
@@ -1935,6 +1935,7 @@ public:
   void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S);
   void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
   void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
+  void EmitOMPFlushDirective(const OMPFlushDirective &S);
 
   //===--------------------------------------------------------------------===//
   //                         LValue Expression Emission

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Mon Jul 21 06:26:11 2014
@@ -86,6 +86,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
   case OMPD_taskyield:
   case OMPD_barrier:
   case OMPD_taskwait:
+  case OMPD_flush:
   case OMPD_for:
   case OMPD_sections:
   case OMPD_section:
@@ -112,7 +113,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
-///         'barrier' | 'taskwait' {clause} annot_pragma_openmp_end
+///         'barrier' | 'taskwait' | 'flush' {clause} annot_pragma_openmp_end
 ///
 StmtResult
 Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
@@ -130,6 +131,7 @@ Parser::ParseOpenMPDeclarativeOrExecutab
   DeclarationNameInfo DirName;
   StmtResult Directive = StmtError();
   bool HasAssociatedStatement = true;
+  bool FlushHasClause = false;
 
   switch (DKind) {
   case OMPD_threadprivate:
@@ -148,6 +150,13 @@ Parser::ParseOpenMPDeclarativeOrExecutab
     }
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
+  case OMPD_flush:
+    if (PP.LookAhead(0).is(tok::l_paren)) {
+      FlushHasClause = true;
+      // Push copy of the current token back to stream to properly parse
+      // pseudo-clause OMPFlushClause.
+      PP.EnterToken(Tok);
+    }
   case OMPD_taskyield:
   case OMPD_barrier:
   case OMPD_taskwait:
@@ -156,6 +165,7 @@ Parser::ParseOpenMPDeclarativeOrExecutab
           << getOpenMPDirectiveName(DKind);
     }
     HasAssociatedStatement = false;
+    // Fall through for further analysis.
   case OMPD_parallel:
   case OMPD_simd:
   case OMPD_for:
@@ -192,9 +202,12 @@ Parser::ParseOpenMPDeclarativeOrExecutab
     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
 
     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
-      OpenMPClauseKind CKind = Tok.isAnnotation()
-                                   ? OMPC_unknown
-                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
+      OpenMPClauseKind CKind =
+          Tok.isAnnotation()
+              ? OMPC_unknown
+              : FlushHasClause ? OMPC_flush
+                               : getOpenMPClauseKind(PP.getSpelling(Tok));
+      FlushHasClause = false;
       OMPClause *Clause =
           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
       FirstClauses[CKind].setInt(true);
@@ -324,7 +337,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
+///       mergeable-clause | flush-clause
 ///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
@@ -407,6 +420,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
   case OMPC_aligned:
   case OMPC_copyin:
   case OMPC_copyprivate:
+  case OMPC_flush:
     Clause = ParseOpenMPVarListClause(CKind);
     break;
   case OMPC_unknown:
@@ -605,7 +619,7 @@ static bool ParseReductionId(Parser &P,
 }
 
 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
-/// 'shared', 'copyin', or 'reduction'.
+/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
 ///
 ///    private-clause:
 ///       'private' '(' list ')'
@@ -621,6 +635,10 @@ static bool ParseReductionId(Parser &P,
 ///       'aligned' '(' list [ ':' alignment ] ')'
 ///    reduction-clause:
 ///       'reduction' '(' reduction-identifier ':' list ')'
+///    copyprivate-clause:
+///       'copyprivate' '(' list ')'
+///    flush-clause:
+///       'flush' '(' list ')'
 ///
 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
   SourceLocation Loc = Tok.getLocation();
@@ -676,7 +694,10 @@ OMPClause *Parser::ParseOpenMPVarListCla
     else if (Tok.isNot(tok::r_paren) &&
              Tok.isNot(tok::annot_pragma_openmp_end) &&
              (!MayHaveTail || Tok.isNot(tok::colon)))
-      Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind);
+      Diag(Tok, diag::err_omp_expected_punc)
+          << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
+                                   : getOpenMPClauseName(Kind))
+          << (Kind == OMPC_flush);
   }
 
   // Parse ':' linear-step (or ':' alignment).

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Jul 21 06:26:11 2014
@@ -1085,6 +1085,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
                              Params);
     break;
   }
+  case OMPD_flush: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
   case OMPD_threadprivate:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
@@ -1114,6 +1122,7 @@ static bool CheckNestingOfRegions(Sema &
   // | parallel         | taskyield       | *                                  |
   // | parallel         | barrier         | *                                  |
   // | parallel         | taskwait        | *                                  |
+  // | parallel         | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | for              | parallel        | *                                  |
   // | for              | for             | +                                  |
@@ -1129,6 +1138,7 @@ static bool CheckNestingOfRegions(Sema &
   // | for              | taskyield       | *                                  |
   // | for              | barrier         | +                                  |
   // | for              | taskwait        | *                                  |
+  // | for              | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | master           | parallel        | *                                  |
   // | master           | for             | +                                  |
@@ -1144,6 +1154,7 @@ static bool CheckNestingOfRegions(Sema &
   // | master           | taskyield       | *                                  |
   // | master           | barrier         | +                                  |
   // | master           | taskwait        | *                                  |
+  // | master           | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | critical         | parallel        | *                                  |
   // | critical         | for             | +                                  |
@@ -1174,6 +1185,7 @@ static bool CheckNestingOfRegions(Sema &
   // | simd             | taskyield       |                                    |
   // | simd             | barrier         |                                    |
   // | simd             | taskwait        |                                    |
+  // | simd             | flush           |                                    |
   // +------------------+-----------------+------------------------------------+
   // | sections         | parallel        | *                                  |
   // | sections         | for             | +                                  |
@@ -1189,6 +1201,7 @@ static bool CheckNestingOfRegions(Sema &
   // | sections         | taskyield       | *                                  |
   // | sections         | barrier         | +                                  |
   // | sections         | taskwait        | *                                  |
+  // | sections         | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | section          | parallel        | *                                  |
   // | section          | for             | +                                  |
@@ -1204,6 +1217,7 @@ static bool CheckNestingOfRegions(Sema &
   // | section          | taskyield       | *                                  |
   // | section          | barrier         | +                                  |
   // | section          | taskwait        | *                                  |
+  // | section          | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | single           | parallel        | *                                  |
   // | single           | for             | +                                  |
@@ -1219,6 +1233,7 @@ static bool CheckNestingOfRegions(Sema &
   // | single           | taskyield       | *                                  |
   // | single           | barrier         | +                                  |
   // | single           | taskwait        | *                                  |
+  // | single           | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | parallel for     | parallel        | *                                  |
   // | parallel for     | for             | +                                  |
@@ -1234,6 +1249,7 @@ static bool CheckNestingOfRegions(Sema &
   // | parallel for     | taskyield       | *                                  |
   // | parallel for     | barrier         | +                                  |
   // | parallel for     | taskwait        | *                                  |
+  // | parallel for     | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | parallel sections| parallel        | *                                  |
   // | parallel sections| for             | +                                  |
@@ -1249,6 +1265,7 @@ static bool CheckNestingOfRegions(Sema &
   // | parallel sections| taskyield       | *                                  |
   // | parallel sections| barrier         | +                                  |
   // | parallel sections| taskwait        | *                                  |
+  // | parallel sections| flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | task             | parallel        | *                                  |
   // | task             | for             | +                                  |
@@ -1264,6 +1281,7 @@ static bool CheckNestingOfRegions(Sema &
   // | task             | taskyield       | *                                  |
   // | task             | barrier         | +                                  |
   // | task             | taskwait        | *                                  |
+  // | task             | flush           | *                                  |
   // +------------------+-----------------+------------------------------------+
   if (Stack->getCurScope()) {
     auto ParentRegion = Stack->getParentDirective();
@@ -1371,6 +1389,7 @@ StmtResult Sema::ActOnOpenMPExecutableDi
   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
   llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
   bool ErrorFound = false;
+  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
   if (AStmt) {
     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
@@ -1381,7 +1400,6 @@ StmtResult Sema::ActOnOpenMPExecutableDi
       return StmtError();
     // Generate list of implicitly defined firstprivate variables.
     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
-    ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
 
     if (!DSAChecker.getImplicitFirstprivate().empty()) {
       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
@@ -1464,6 +1482,11 @@ StmtResult Sema::ActOnOpenMPExecutableDi
            "No associated statement allowed for 'omp taskwait' directive");
     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
     break;
+  case OMPD_flush:
+    assert(AStmt == nullptr &&
+           "No associated statement allowed for 'omp flush' directive");
+    Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
+    break;
   case OMPD_threadprivate:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
@@ -2234,6 +2257,13 @@ StmtResult Sema::ActOnOpenMPTaskwaitDire
   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
 }
 
+StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
+                                           SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
+  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
+}
+
 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
                                              SourceLocation StartLoc,
                                              SourceLocation LParenLoc,
@@ -2272,6 +2302,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
   case OMPC_untied:
   case OMPC_mergeable:
   case OMPC_threadprivate:
+  case OMPC_flush:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2474,6 +2505,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
   case OMPC_untied:
   case OMPC_mergeable:
   case OMPC_threadprivate:
+  case OMPC_flush:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2588,6 +2620,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi
   case OMPC_untied:
   case OMPC_mergeable:
   case OMPC_threadprivate:
+  case OMPC_flush:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2685,6 +2718,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM
   case OMPC_default:
   case OMPC_proc_bind:
   case OMPC_threadprivate:
+  case OMPC_flush:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2748,6 +2782,9 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
   case OMPC_copyprivate:
     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_flush:
+    Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
   case OMPC_if:
   case OMPC_final:
   case OMPC_num_threads:
@@ -4052,4 +4089,14 @@ OMPClause *Sema::ActOnOpenMPCopyprivateC
   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
 }
 
+OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
+                                        SourceLocation StartLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation EndLoc) {
+  if (VarList.empty())
+    return nullptr;
+
+  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=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jul 21 06:26:11 2014
@@ -1517,6 +1517,18 @@ public:
                                                   EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'flush' pseudo clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
+                                   SourceLocation StartLoc,
+                                   SourceLocation LParenLoc,
+                                   SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
+                                            EndLoc);
+  }
+
   /// \brief Rebuild the operand to an Objective-C \@synchronized statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -6610,6 +6622,17 @@ TreeTransform<Derived>::TransformOMPTask
   return Res;
 }
 
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP clause transformation
 //===----------------------------------------------------------------------===//
@@ -6869,6 +6892,20 @@ TreeTransform<Derived>::TransformOMPCopy
       Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPFlushClause(Vars, C->getLocStart(),
+                                            C->getLParenLoc(), C->getLocEnd());
+}
+
 //===----------------------------------------------------------------------===//
 // Expression transformation
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Jul 21 06:26:11 2014
@@ -1742,6 +1742,9 @@ OMPClause *OMPClauseReader::readClause()
   case OMPC_copyprivate:
     C = OMPCopyprivateClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_flush:
+    C = OMPFlushClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   }
   Visit(C);
   C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
@@ -1908,6 +1911,16 @@ void OMPClauseReader::VisitOMPCopyprivat
   C->setVarRefs(Vars);
 }
 
+void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
@@ -2011,6 +2024,13 @@ void ASTStmtReader::VisitOMPTaskwaitDire
   VisitOMPExecutableDirective(D);
 }
 
+void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
 //===----------------------------------------------------------------------===//
 // ASTReader Implementation
 //===----------------------------------------------------------------------===//
@@ -2561,6 +2581,11 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       S = OMPTaskwaitDirective::CreateEmpty(Context, Empty);
       break;
 
+    case STMT_OMP_FLUSH_DIRECTIVE:
+      S = OMPFlushDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
     case EXPR_CXX_OPERATOR_CALL:
       S = new (Context) CXXOperatorCallExpr(Context, Empty);
       break;

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Jul 21 06:26:11 2014
@@ -1805,6 +1805,13 @@ void OMPClauseWriter::VisitOMPCopyprivat
     Writer->Writer.AddStmt(VE);
 }
 
+void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
@@ -1916,6 +1923,13 @@ void ASTStmtWriter::VisitOMPTaskwaitDire
   Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
+}
+
 //===----------------------------------------------------------------------===//
 // ASTWriter Implementation
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Jul 21 06:26:11 2014
@@ -745,6 +745,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
     case Stmt::OMPTaskyieldDirectiveClass:
     case Stmt::OMPBarrierDirectiveClass:
     case Stmt::OMPTaskwaitDirectiveClass:
+    case Stmt::OMPFlushDirectiveClass:
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
 
     case Stmt::ObjCSubscriptRefExprClass:

Added: cfe/trunk/test/OpenMP/flush_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/flush_ast_print.cpp?rev=213512&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/flush_ast_print.cpp (added)
+++ cfe/trunk/test/OpenMP/flush_ast_print.cpp Mon Jul 21 06:26:11 2014
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+T tmain(T argc) {
+  static T a;
+#pragma omp flush
+#pragma omp flush(a)
+  return a + argc;
+}
+// CHECK:      static int a;
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+// CHECK:      static char a;
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+// CHECK:      static T a;
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+
+int main(int argc, char **argv) {
+  static int a;
+// CHECK: static int a;
+#pragma omp flush
+#pragma omp flush(a)
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+  return tmain(argc) + tmain(argv[0][0]) + a;
+}
+
+#endif

Propchange: cfe/trunk/test/OpenMP/flush_ast_print.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/OpenMP/flush_ast_print.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/OpenMP/flush_ast_print.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/OpenMP/flush_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/flush_messages.cpp?rev=213512&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/flush_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/flush_messages.cpp Mon Jul 21 06:26:11 2014
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+struct S1 { // expected-note 2 {{declared here}}
+  int a;
+};
+
+template <class T>
+T tmain(T argc) {
+#pragma omp flush
+  ;
+#pragma omp flush untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp flush'}}
+#pragma omp flush unknown // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+  if (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp flush
+    }
+  while (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp flush
+    }
+  do
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp flush
+  } while (argc);
+  switch (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp flush
+  }
+  switch (argc) {
+#pragma omp flush
+  case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp flush
+  } break;
+  }
+  for (;;)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp flush
+    }
+label:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+label1 : {
+#pragma omp flush
+}
+
+#pragma omp flush
+#pragma omp flush(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush()                             // expected-error {{expected expression}}
+#pragma omp flush(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc)
+#pragma omp flush(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+#pragma omp parallel flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  ;
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp flush
+  ;
+#pragma omp flush untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp flush'}}
+#pragma omp flush unknown // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+  if (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp flush
+    }
+  while (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp flush
+    }
+  do
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp flush
+  } while (argc);
+  switch (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp flush
+  }
+  switch (argc) {
+#pragma omp flush
+  case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp flush
+  } break;
+  }
+  for (;;)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp flush
+    }
+label:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+label1 : {
+#pragma omp flush
+}
+
+#pragma omp flush
+#pragma omp flush(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush()                             // expected-error {{expected expression}}
+#pragma omp flush(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc)
+#pragma omp flush(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+#pragma omp parallel flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  ;
+  return tmain(argc);
+}

Propchange: cfe/trunk/test/OpenMP/flush_messages.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/OpenMP/flush_messages.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/OpenMP/flush_messages.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/nesting_of_regions.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original)
+++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Mon Jul 21 06:26:11 2014
@@ -66,6 +66,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp parallel
+  {
+#pragma omp flush
+    bar();
+  }
 
 // SIMD DIRECTIVE
 #pragma omp simd
@@ -156,6 +161,11 @@ void foo() {
 #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
     bar();
   }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
 
 // FOR DIRECTIVE
 #pragma omp for
@@ -264,6 +274,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
 
 // SECTIONS DIRECTIVE
 #pragma omp sections
@@ -385,6 +400,10 @@ void foo() {
   {
 #pragma omp taskwait
   }
+#pragma omp sections
+  {
+#pragma omp flush
+  }
 
 // SECTION DIRECTIVE
 #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -523,6 +542,14 @@ void foo() {
       bar();
     }
   }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp flush
+      bar();
+    }
+  }
 
 // SINGLE DIRECTIVE
 #pragma omp single
@@ -623,6 +650,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp single
+  {
+#pragma omp flush
+    bar();
+  }
 
 // MASTER DIRECTIVE
 #pragma omp master
@@ -723,6 +755,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp master
+  {
+#pragma omp flush
+    bar();
+  }
 
 // CRITICAL DIRECTIVE
 #pragma omp critical
@@ -952,6 +989,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
 
 // PARALLEL SECTIONS DIRECTIVE
 #pragma omp parallel sections
@@ -1059,6 +1101,10 @@ void foo() {
   {
 #pragma omp taskwait
   }
+#pragma omp parallel sections
+  {
+#pragma omp flush
+  }
 
 // TASK DIRECTIVE
 #pragma omp task
@@ -1118,6 +1164,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp task
+  {
+#pragma omp flush
+    bar();
+  }
 }
 
 void foo() {
@@ -1183,6 +1234,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp parallel
+  {
+#pragma omp flush
+    bar();
+  }
 
 // SIMD DIRECTIVE
 #pragma omp simd
@@ -1266,6 +1322,11 @@ void foo() {
 #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
     bar();
   }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
 
 // FOR DIRECTIVE
 #pragma omp for
@@ -1361,6 +1422,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
 
 // SECTIONS DIRECTIVE
 #pragma omp sections
@@ -1454,6 +1520,10 @@ void foo() {
   {
 #pragma omp taskwait
   }
+#pragma omp sections
+  {
+#pragma omp flush
+  }
 
 // SECTION DIRECTIVE
 #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -1592,6 +1662,14 @@ void foo() {
       bar();
     }
   }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp flush
+      bar();
+    }
+  }
 
 // SINGLE DIRECTIVE
 #pragma omp single
@@ -1682,6 +1760,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp single
+  {
+#pragma omp flush
+    bar();
+  }
 
 // MASTER DIRECTIVE
 #pragma omp master
@@ -1782,6 +1865,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp master
+  {
+#pragma omp flush
+    bar();
+  }
 
 // CRITICAL DIRECTIVE
 #pragma omp critical
@@ -2010,6 +2098,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
 
 // PARALLEL SECTIONS DIRECTIVE
 #pragma omp parallel sections
@@ -2113,6 +2206,10 @@ void foo() {
   {
 #pragma omp taskwait
   }
+#pragma omp parallel sections
+  {
+#pragma omp flush
+  }
 
 // TASK DIRECTIVE
 #pragma omp task
@@ -2171,6 +2268,11 @@ void foo() {
 #pragma omp taskwait
     bar();
   }
+#pragma omp task
+  {
+#pragma omp flush
+    bar();
+  }
   return foo<int>();
 }
 

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jul 21 06:26:11 2014
@@ -1870,6 +1870,7 @@ public:
   void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
   void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
   void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
+  void VisitOMPFlushDirective(const OMPFlushDirective *D);
 
 private:
   void AddDeclarationNameInfo(const Stmt *S);
@@ -2016,6 +2017,9 @@ void
 OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
+  VisitOMPClauseList(C);
+}
 }
 
 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
@@ -2365,6 +2369,10 @@ void EnqueueVisitor::VisitOMPTaskwaitDir
   VisitOMPExecutableDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
 }
@@ -4065,6 +4073,8 @@ CXString clang_getCursorKindSpelling(enu
     return cxstring::createRef("OMPBarrierDirective");
   case CXCursor_OMPTaskwaitDirective:
     return cxstring::createRef("OMPTaskwaitDirective");
+  case CXCursor_OMPFlushDirective:
+    return cxstring::createRef("OMPFlushDirective");
   }
 
   llvm_unreachable("Unhandled CXCursorKind");

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=213512&r1=213511&r2=213512&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Mon Jul 21 06:26:11 2014
@@ -559,6 +559,9 @@ CXCursor cxcursor::MakeCXCursor(const St
   case Stmt::OMPTaskwaitDirectiveClass:
     K = CXCursor_OMPTaskwaitDirective;
     break;
+  case Stmt::OMPFlushDirectiveClass:
+    K = CXCursor_OMPFlushDirective;
+    break;
   }
 
   CXCursor C = { K, 0, { Parent, S, TU } };





More information about the cfe-commits mailing list