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

Samuel F Antao sfantao at us.ibm.com
Fri Jul 25 12:36:06 PDT 2014


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>:

> 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
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140725/68b760f8/attachment.html>


More information about the cfe-commits mailing list