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

Bataev, Alexey a.bataev at hotmail.com
Mon Jul 28 22:20:47 PDT 2014


Samuel, Ok, no problems. Thanks!

Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team

28.07.2014 20:03, Samuel F Antao пишет:
> Hi Alexey,
>
> My comments are bellow.
>
> Thanks,
> Samuel
>
> 2014-07-27 23:38 GMT-04:00 Bataev, Alexey <a.bataev at hotmail.com 
> <mailto:a.bataev at hotmail.com>>:
>
>     Hi Samuel,
>     Thanks for the review.
>>     If I understand it correctly, the reason for having a Clause
>>     instance for the flush directive is to enable the use of the
>>     machinery that parses the clauses for this directive as well. I
>>     think that this deserves a more thorough comment here. I would
>>     prefer the term implicit clause instead of pseudo here. In
>>     SemaOpenMP.cpp, 'implicit' is currently used in the code related
>>     to the flush directive.
>     Ok, I'll do that.
>
>>      OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
>>     +  if (Str == "flush")
>>     +    return OMPC_unknown;
>>
>>     I suggest adding a comment here on why the special case for flush
>>     and link it with the comment about pseudo/implicit clauses.
>     I'll add the comment.
>
>>     +#pragma omp flush // expected-error {{'#pragma omp flush' cannot
>>     be an immediate substatement}}
>>
>>     I think "cannot have" seems more accurate than "cannot be" in the
>>     diagnostic message.
>     Samuel, I don't quite understand how to express the same idea with
>     "cannot have". Could you provide an example of the error message
>     you'd like to see?
>
>
> I was revisiting the testcase again and you are right. I 
> misinterpreted the error as something that relates with the flush 
> following statement and not the previous. It is okay the way it. Sorry 
> about the confusion.
>
>>     +#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}}
>>
>>     I would expect these two last warnings to be errors. That is my
>>     understanding of "standalone directive" in the OpenMP spec. Gcc
>>     currently emits an error for the same constructs, so, unless
>>     there is a strong reason to emit the warning, I think clang
>>     should also emit an error here.
>     I don't agree. 'flush' is a directive name and there are no
>     clauses with the name 'flush'. So, if you specify 'flush' clause,
>     it should not be recognized by the Parser. The Parser should
>     return the same result as if there are some extra tokens at the
>     end of the directive (for clang it is a warning).
>
>
> Ok, so this is clang's policy on how the parser deals with extra 
> tokens. In that case this is fine.
>
>     Best regards,
>     Alexey Bataev
>     =============
>     Software Engineer
>     Intel Compiler Team
>
>     25.07.2014 23 <tel:25.07.2014%2023>:36, Samuel F Antao пишет:
>>     Hi Alexey,
>>
>>     Thanks for the commit. I took a close look into this commit and
>>     my comments are bellow.
>>
>>     Regards,
>>     Samuel
>>
>>
>>     2014-07-21 7:26 GMT-04:00 Alexey Bataev <a.bataev at hotmail.com
>>     <mailto:a.bataev at hotmail.com>>:
>>
>>         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:
>>            }
>>          };
>>
>>
>>     If I understand it correctly, the reason for having a Clause
>>     instance for the flush directive is to enable the use of the
>>     machinery that parses the clauses for this directive as well. I
>>     think that this deserves a more thorough comment here. I would
>>     prefer the term implicit clause instead of pseudo here. In
>>     SemaOpenMP.cpp, 'implicit' is currently used in the code related
>>     to the flush directive.
>>
>>         +/// \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;
>>
>>
>>     I suggest adding a comment here on why the special case for flush
>>     and link it with the comment about pseudo/implicit clauses.
>>
>>            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}}
>>
>>
>>     I think "cannot have" seems more accurate than "cannot be" in the
>>     diagnostic message.
>>
>>         +    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}}
>>
>>
>>     I would expect these two last warnings to be errors. That is my
>>     understanding of "standalone directive" in the OpenMP spec. Gcc
>>     currently emits an error for the same constructs, so, unless
>>     there is a strong reason to emit the warning, I think clang
>>     should also emit an error here.
>>
>>         +  ;
>>         +  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 } };
>>
>>
>>         _______________________________________________
>>         cfe-commits mailing list
>>         cfe-commits at cs.uiuc.edu <mailto:cfe-commits at cs.uiuc.edu>
>>         http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
>
>     _______________________________________________
>     cfe-commits mailing list
>     cfe-commits at cs.uiuc.edu <mailto:cfe-commits at cs.uiuc.edu>
>     http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>





More information about the cfe-commits mailing list