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 <[email protected] <mailto:[email protected]>>:

    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 <[email protected]
    <mailto:[email protected]>>:

        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
        [email protected] <mailto:[email protected]>
        http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




    _______________________________________________
    cfe-commits mailing list
    [email protected] <mailto:[email protected]>
    http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to