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

Samuel F Antao sfantao at us.ibm.com
Mon Jul 28 09:03:14 PDT 2014


Hi Alexey,

My comments are bellow.

Thanks,
Samuel

2014-07-27 23:38 GMT-04:00 Bataev, Alexey <a.bataev at hotmail.com>:

>  Hi Samuel,
> Thanks for the review.
>
> If I understand it correctly, the reason for having a Clause instance for
> the flush directive is to enable the use of the machinery that parses the
> clauses for this directive as well. I think that this deserves a more
> thorough comment here. I would prefer the term implicit clause instead of
> pseudo here. In SemaOpenMP.cpp, 'implicit' is currently used in the code
> related to the flush directive.
>
> Ok, I'll do that.
>
>  OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
> +  if (Str == "flush")
> +    return OMPC_unknown;
>
>  I suggest adding a comment here on why the special case for flush and
> link it with the comment about pseudo/implicit clauses.
>
> I'll add the comment.
>
> +#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an
> immediate substatement}}
>
>  I think "cannot have" seems more accurate than "cannot be" in the
> diagnostic message.
>
> Samuel, I don't quite understand how to express the same idea with "cannot
> have". Could you provide an example of the error message you'd like to see?
>

I was revisiting the testcase again and you are right. I misinterpreted the
error as something that relates with the flush following statement and not
the previous. It is okay the way it. Sorry about the confusion.


> +#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at
> the end of '#pragma omp flush' are ignored}}
> +#pragma omp parallel flush(argc) // expected-warning {{extra tokens at
> the end of '#pragma omp parallel' are ignored}}
>
>  I would expect these two last warnings to be errors. That is my
> understanding of "standalone directive" in the OpenMP spec. Gcc currently
> emits an error for the same constructs, so, unless there is a strong reason
> to emit the warning, I think clang should also emit an error here.
>
> I don't agree. 'flush' is a directive name and there are no clauses with
> the name 'flush'. So, if you specify 'flush' clause, it should not be
> recognized by the Parser. The Parser should return the same result as if
> there are some extra tokens at the end of the directive (for clang it is a
> warning).
>
>
Ok, so this is clang's policy on how the parser deals with extra tokens. In
that case this is fine.

> Best regards,
> Alexey Bataev
> =============
> Software Engineer
> Intel Compiler Team
>
> 25.07.2014 23:36, Samuel F Antao пишет:
>
> Hi Alexey,
>
>  Thanks for the commit. I took a close look into this commit and my
> comments are bellow.
>
>  Regards,
> Samuel
>
>
> 2014-07-21 7:26 GMT-04:00 Alexey Bataev <a.bataev at hotmail.com>:
>
>> 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
>>
>
>
>
> _______________________________________________
> 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/20140728/46b6ea5d/attachment.html>


More information about the cfe-commits mailing list