r213512 - [OPENMP] Initial parsing and sema analysis for 'flush' directive.
Bataev, Alexey
a.bataev at hotmail.com
Mon Jul 28 22:20:47 PDT 2014
Samuel, Ok, no problems. Thanks!
Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team
28.07.2014 20:03, Samuel F Antao пишет:
> Hi Alexey,
>
> My comments are bellow.
>
> Thanks,
> Samuel
>
> 2014-07-27 23:38 GMT-04:00 Bataev, Alexey <a.bataev at hotmail.com
> <mailto:a.bataev at hotmail.com>>:
>
> Hi Samuel,
> Thanks for the review.
>> If I understand it correctly, the reason for having a Clause
>> instance for the flush directive is to enable the use of the
>> machinery that parses the clauses for this directive as well. I
>> think that this deserves a more thorough comment here. I would
>> prefer the term implicit clause instead of pseudo here. In
>> SemaOpenMP.cpp, 'implicit' is currently used in the code related
>> to the flush directive.
> Ok, I'll do that.
>
>> OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
>> + if (Str == "flush")
>> + return OMPC_unknown;
>>
>> I suggest adding a comment here on why the special case for flush
>> and link it with the comment about pseudo/implicit clauses.
> I'll add the comment.
>
>> +#pragma omp flush // expected-error {{'#pragma omp flush' cannot
>> be an immediate substatement}}
>>
>> I think "cannot have" seems more accurate than "cannot be" in the
>> diagnostic message.
> Samuel, I don't quite understand how to express the same idea with
> "cannot have". Could you provide an example of the error message
> you'd like to see?
>
>
> I was revisiting the testcase again and you are right. I
> misinterpreted the error as something that relates with the flush
> following statement and not the previous. It is okay the way it. Sorry
> about the confusion.
>
>> +#pragma omp flush(argc) flush(argc) // expected-warning {{extra
>> tokens at the end of '#pragma omp flush' are ignored}}
>> +#pragma omp parallel flush(argc) // expected-warning {{extra
>> tokens at the end of '#pragma omp parallel' are ignored}}
>>
>> I would expect these two last warnings to be errors. That is my
>> understanding of "standalone directive" in the OpenMP spec. Gcc
>> currently emits an error for the same constructs, so, unless
>> there is a strong reason to emit the warning, I think clang
>> should also emit an error here.
> I don't agree. 'flush' is a directive name and there are no
> clauses with the name 'flush'. So, if you specify 'flush' clause,
> it should not be recognized by the Parser. The Parser should
> return the same result as if there are some extra tokens at the
> end of the directive (for clang it is a warning).
>
>
> Ok, so this is clang's policy on how the parser deals with extra
> tokens. In that case this is fine.
>
> Best regards,
> Alexey Bataev
> =============
> Software Engineer
> Intel Compiler Team
>
> 25.07.2014 23 <tel:25.07.2014%2023>:36, Samuel F Antao пишет:
>> Hi Alexey,
>>
>> Thanks for the commit. I took a close look into this commit and
>> my comments are bellow.
>>
>> Regards,
>> Samuel
>>
>>
>> 2014-07-21 7:26 GMT-04:00 Alexey Bataev <a.bataev at hotmail.com
>> <mailto:a.bataev at hotmail.com>>:
>>
>> Author: abataev
>> Date: Mon Jul 21 06:26:11 2014
>> New Revision: 213512
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=213512&view=rev
>> Log:
>> [OPENMP] Initial parsing and sema analysis for 'flush' directive.
>>
>> Added:
>> cfe/trunk/test/OpenMP/flush_ast_print.cpp (with props)
>> cfe/trunk/test/OpenMP/flush_messages.cpp (with props)
>> Modified:
>> cfe/trunk/include/clang-c/Index.h
>> cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
>> cfe/trunk/include/clang/AST/OpenMPClause.h
>> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> cfe/trunk/include/clang/AST/StmtOpenMP.h
>> cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>> cfe/trunk/include/clang/Basic/OpenMPKinds.def
>> cfe/trunk/include/clang/Basic/StmtNodes.td
>> cfe/trunk/include/clang/Sema/Sema.h
>> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> cfe/trunk/lib/AST/Stmt.cpp
>> cfe/trunk/lib/AST/StmtPrinter.cpp
>> cfe/trunk/lib/AST/StmtProfile.cpp
>> cfe/trunk/lib/Basic/OpenMPKinds.cpp
>> cfe/trunk/lib/CodeGen/CGStmt.cpp
>> cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
>> cfe/trunk/lib/CodeGen/CodeGenFunction.h
>> cfe/trunk/lib/Parse/ParseOpenMP.cpp
>> cfe/trunk/lib/Sema/SemaOpenMP.cpp
>> cfe/trunk/lib/Sema/TreeTransform.h
>> cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>> cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>> cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
>> cfe/trunk/test/OpenMP/nesting_of_regions.cpp
>> cfe/trunk/tools/libclang/CIndex.cpp
>> cfe/trunk/tools/libclang/CXCursor.cpp
>>
>> Modified: cfe/trunk/include/clang-c/Index.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang-c/Index.h (original)
>> +++ cfe/trunk/include/clang-c/Index.h Mon Jul 21 06:26:11 2014
>> @@ -2187,9 +2187,13 @@ enum CXCursorKind {
>> */
>> CXCursor_OMPTaskwaitDirective = 245,
>>
>> + /** \brief OpenMP flush directive.
>> + */
>> + CXCursor_OMPFlushDirective = 246,
>> +
>> /** \brief Windows Structured Exception Handling's leave
>> statement.
>> */
>> - CXCursor_SEHLeaveStmt = 246,
>> + CXCursor_SEHLeaveStmt = 247,
>>
>> CXCursor_LastStmt =
>> CXCursor_SEHLeaveStmt,
>>
>>
>> Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
>> (original)
>> +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Mon
>> Jul 21 06:26:11 2014
>> @@ -2323,6 +2323,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
>> DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
>> {
>> TRY_TO(TraverseOMPExecutableDirective(S)); })
>>
>> +DEF_TRAVERSE_STMT(OMPFlushDirective,
>> + {
>> TRY_TO(TraverseOMPExecutableDirective(S)); })
>> +
>> // OpenMP clauses.
>> template <typename Derived>
>> bool
>> RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
>> @@ -2481,6 +2484,12 @@ RecursiveASTVisitor<Derived>::VisitOMPRe
>> TRY_TO(VisitOMPClauseList(C));
>> return true;
>> }
>> +
>> +template <typename Derived>
>> +bool
>> RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause
>> *C) {
>> + TRY_TO(VisitOMPClauseList(C));
>> + return true;
>> +}
>>
>> // FIXME: look at the following tricky-seeming exprs to see
>> if we
>> // need to recurse on anything. These are ones that have
>> methods
>>
>> Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
>> +++ cfe/trunk/include/clang/AST/OpenMPClause.h Mon Jul 21
>> 06:26:11 2014
>> @@ -1390,6 +1390,66 @@ public:
>> }
>> };
>>
>>
>> If I understand it correctly, the reason for having a Clause
>> instance for the flush directive is to enable the use of the
>> machinery that parses the clauses for this directive as well. I
>> think that this deserves a more thorough comment here. I would
>> prefer the term implicit clause instead of pseudo here. In
>> SemaOpenMP.cpp, 'implicit' is currently used in the code related
>> to the flush directive.
>>
>> +/// \brief This represents pseudo clause 'flush' for the
>> '#pragma omp flush'
>> +/// directive.
>> +///
>> +/// \code
>> +/// #pragma omp flush(a,b)
>> +/// \endcode
>> +/// In this example directive '#pragma omp flush' has pseudo
>> clause 'flush'
>> +/// with the variables 'a' and 'b'.
>> +///
>> +class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
>> + /// \brief Build clause with number of variables \a N.
>> + ///
>> + /// \param StartLoc Starting location of the clause.
>> + /// \param LParenLoc Location of '('.
>> + /// \param EndLoc Ending location of the clause.
>> + /// \param N Number of the variables in the clause.
>> + ///
>> + OMPFlushClause(SourceLocation StartLoc, SourceLocation
>> LParenLoc,
>> + SourceLocation EndLoc, unsigned N)
>> + : OMPVarListClause<OMPFlushClause>(OMPC_flush,
>> StartLoc, LParenLoc,
>> + EndLoc, N) {}
>> +
>> + /// \brief Build an empty clause.
>> + ///
>> + /// \param N Number of variables.
>> + ///
>> + explicit OMPFlushClause(unsigned N)
>> + : OMPVarListClause<OMPFlushClause>(OMPC_flush,
>> SourceLocation(),
>> + SourceLocation(), SourceLocation(),
>> + N) {}
>> +
>> +public:
>> + /// \brief Creates clause with a list of variables \a VL.
>> + ///
>> + /// \param C AST context.
>> + /// \param StartLoc Starting location of the clause.
>> + /// \param LParenLoc Location of '('.
>> + /// \param EndLoc Ending location of the clause.
>> + /// \param VL List of references to the variables.
>> + ///
>> + static OMPFlushClause *Create(const ASTContext &C,
>> SourceLocation StartLoc,
>> + SourceLocation LParenLoc, SourceLocation EndLoc,
>> + ArrayRef<Expr *> VL);
>> + /// \brief Creates an empty clause with \a N variables.
>> + ///
>> + /// \param C AST context.
>> + /// \param N The number of variables.
>> + ///
>> + static OMPFlushClause *CreateEmpty(const ASTContext &C,
>> unsigned N);
>> +
>> + StmtRange children() {
>> + return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
>> + reinterpret_cast<Stmt **>(varlist_end()));
>> + }
>> +
>> + static bool classof(const OMPClause *T) {
>> + return T->getClauseKind() == OMPC_flush;
>> + }
>> +};
>> +
>> } // end namespace clang
>>
>> #endif
>>
>> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
>> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jul
>> 21 06:26:11 2014
>> @@ -2345,6 +2345,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
>> DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
>> {
>> TRY_TO(TraverseOMPExecutableDirective(S)); })
>>
>> +DEF_TRAVERSE_STMT(OMPFlushDirective,
>> + {
>> TRY_TO(TraverseOMPExecutableDirective(S)); })
>> +
>> // OpenMP clauses.
>> template <typename Derived>
>> bool
>> RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
>> @@ -2503,6 +2506,12 @@ RecursiveASTVisitor<Derived>::VisitOMPRe
>> TRY_TO(VisitOMPClauseList(C));
>> return true;
>> }
>> +
>> +template <typename Derived>
>> +bool
>> RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause
>> *C) {
>> + TRY_TO(VisitOMPClauseList(C));
>> + return true;
>> +}
>>
>> // FIXME: look at the following tricky-seeming exprs to see
>> if we
>> // need to recurse on anything. These are ones that have
>> methods
>>
>> Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
>> +++ cfe/trunk/include/clang/AST/StmtOpenMP.h Mon Jul 21
>> 06:26:11 2014
>> @@ -969,6 +969,65 @@ public:
>> }
>> };
>>
>> +/// \brief This represents '#pragma omp flush' directive.
>> +///
>> +/// \code
>> +/// #pragma omp flush(a,b)
>> +/// \endcode
>> +/// In this example directive '#pragma omp flush' has 2
>> arguments- variables 'a'
>> +/// and 'b'.
>> +/// 'omp flush' directive does not have clauses but have an
>> optional list of
>> +/// variables to flush. This list of variables is stored
>> within some fake clause
>> +/// FlushClause.
>> +class OMPFlushDirective : public OMPExecutableDirective {
>> + friend class ASTStmtReader;
>> + /// \brief Build directive with the given start and end
>> location.
>> + ///
>> + /// \param StartLoc Starting location of the directive kind.
>> + /// \param EndLoc Ending location of the directive.
>> + /// \param NumClauses Number of clauses.
>> + ///
>> + OMPFlushDirective(SourceLocation StartLoc, SourceLocation
>> EndLoc,
>> + unsigned NumClauses)
>> + : OMPExecutableDirective(this, OMPFlushDirectiveClass,
>> OMPD_flush,
>> + StartLoc, EndLoc, NumClauses,
>> 0) {}
>> +
>> + /// \brief Build an empty directive.
>> + ///
>> + /// \param NumClauses Number of clauses.
>> + ///
>> + explicit OMPFlushDirective(unsigned NumClauses)
>> + : OMPExecutableDirective(this, OMPFlushDirectiveClass,
>> OMPD_flush,
>> + SourceLocation(), SourceLocation(), NumClauses,
>> + 0) {}
>> +
>> +public:
>> + /// \brief Creates directive with a list of \a Clauses.
>> + ///
>> + /// \param C AST context.
>> + /// \param StartLoc Starting location of the directive kind.
>> + /// \param EndLoc Ending Location of the directive.
>> + /// \param Clauses List of clauses (only single
>> OMPFlushClause clause is
>> + /// allowed).
>> + ///
>> + static OMPFlushDirective *Create(const ASTContext &C,
>> SourceLocation StartLoc,
>> + SourceLocation EndLoc,
>> + ArrayRef<OMPClause *> Clauses);
>> +
>> + /// \brief Creates an empty directive with the place for
>> \a NumClauses
>> + /// clauses.
>> + ///
>> + /// \param C AST context.
>> + /// \param NumClauses Number of clauses.
>> + ///
>> + static OMPFlushDirective *CreateEmpty(const ASTContext &C,
>> + unsigned NumClauses, EmptyShell);
>> +
>> + static bool classof(const Stmt *T) {
>> + return T->getStmtClass() == OMPFlushDirectiveClass;
>> + }
>> +};
>> +
>> } // end namespace clang
>>
>> #endif
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>> (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon
>> Jul 21 06:26:11 2014
>> @@ -903,7 +903,7 @@ def err_omp_unknown_directive : Error<
>> def err_omp_unexpected_directive : Error<
>> "unexpected OpenMP directive '#pragma omp %0'">;
>> def err_omp_expected_punc : Error<
>> - "expected ',' or ')' in '%0' clause">;
>> + "expected ',' or ')' in '%0' %select{clause|directive}1">;
>> def err_omp_unexpected_clause : Error<
>> "unexpected OpenMP clause '%0' in directive '#pragma omp
>> %1'">;
>> def err_omp_more_one_clause : Error<
>>
>> Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
>> +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Mon Jul 21
>> 06:26:11 2014
>> @@ -69,6 +69,7 @@ OPENMP_DIRECTIVE(critical)
>> OPENMP_DIRECTIVE(taskyield)
>> OPENMP_DIRECTIVE(barrier)
>> OPENMP_DIRECTIVE(taskwait)
>> +OPENMP_DIRECTIVE(flush)
>> OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
>> OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
>>
>> @@ -94,6 +95,7 @@ OPENMP_CLAUSE(ordered, OMPOrderedClause)
>> OPENMP_CLAUSE(nowait, OMPNowaitClause)
>> OPENMP_CLAUSE(untied, OMPUntiedClause)
>> OPENMP_CLAUSE(mergeable, OMPMergeableClause)
>> +OPENMP_CLAUSE(flush, OMPFlushClause)
>>
>> // Clauses allowed for OpenMP directive 'parallel'.
>> OPENMP_PARALLEL_CLAUSE(if)
>>
>> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
>> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Mon Jul 21
>> 06:26:11 2014
>> @@ -192,3 +192,4 @@ def OMPTaskDirective : DStmt<OMPExecutab
>> def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
>> def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
>> def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
>> +def OMPFlushDirective : DStmt<OMPExecutableDirective>;
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul 21 06:26:11 2014
>> @@ -7382,7 +7382,11 @@ public:
>> SourceLocation EndLoc);
>> /// \brief Called on well-formed '\#pragma omp taskwait'.
>> StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation
>> StartLoc,
>> - SourceLocation EndLoc);
>> + SourceLocation EndLoc);
>> + /// \brief Called on well-formed '\#pragma omp flush'.
>> + StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *>
>> Clauses,
>> + SourceLocation StartLoc,
>> + SourceLocation EndLoc);
>>
>> OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
>> Expr *Expr,
>> @@ -7520,6 +7524,11 @@ public:
>> SourceLocation StartLoc,
>> SourceLocation LParenLoc,
>> SourceLocation EndLoc);
>> + /// \brief Called on well-formed 'flush' pseudo clause.
>> + OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
>> + SourceLocation StartLoc,
>> + SourceLocation LParenLoc,
>> + SourceLocation EndLoc);
>>
>> /// \brief The kind of conversion being performed.
>> enum CheckedConversionKind {
>>
>> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon
>> Jul 21 06:26:11 2014
>> @@ -1354,6 +1354,7 @@ namespace clang {
>> STMT_OMP_TASKYIELD_DIRECTIVE,
>> STMT_OMP_BARRIER_DIRECTIVE,
>> STMT_OMP_TASKWAIT_DIRECTIVE,
>> + STMT_OMP_FLUSH_DIRECTIVE,
>>
>> // ARC
>> EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
>>
>> Modified: cfe/trunk/lib/AST/Stmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/AST/Stmt.cpp (original)
>> +++ cfe/trunk/lib/AST/Stmt.cpp Mon Jul 21 06:26:11 2014
>> @@ -1327,6 +1327,27 @@ OMPReductionClause *OMPReductionClause::
>> return new (Mem) OMPReductionClause(N);
>> }
>>
>> +OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
>> + SourceLocation StartLoc,
>> + SourceLocation LParenLoc,
>> + SourceLocation EndLoc,
>> + ArrayRef<Expr *> VL) {
>> + void *Mem =
>> C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
>> + llvm::alignOf<Expr *>()) +
>> + sizeof(Expr *) * VL.size());
>> + OMPFlushClause *Clause =
>> + new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc,
>> VL.size());
>> + Clause->setVarRefs(VL);
>> + return Clause;
>> +}
>> +
>> +OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext
>> &C, unsigned N) {
>> + void *Mem =
>> C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
>> + llvm::alignOf<Expr *>()) +
>> + sizeof(Expr *) * N);
>> + return new (Mem) OMPFlushClause(N);
>> +}
>> +
>> OMPParallelDirective *OMPParallelDirective::Create(
>> const ASTContext &C,
>> SourceLocation StartLoc,
>> @@ -1635,3 +1656,25 @@ OMPTaskwaitDirective *OMPTaskwaitDirecti
>> return new (Mem) OMPTaskwaitDirective();
>> }
>>
>> +OMPFlushDirective *OMPFlushDirective::Create(const
>> ASTContext &C,
>> + SourceLocation StartLoc,
>> + SourceLocation EndLoc,
>> + ArrayRef<OMPClause *> Clauses) {
>> + unsigned Size =
>> llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
>> + llvm::alignOf<OMPClause *>());
>> + void *Mem = C.Allocate(Size + sizeof(OMPClause *) *
>> Clauses.size());
>> + OMPFlushDirective *Dir =
>> + new (Mem) OMPFlushDirective(StartLoc, EndLoc,
>> Clauses.size());
>> + Dir->setClauses(Clauses);
>> + return Dir;
>> +}
>> +
>> +OMPFlushDirective *OMPFlushDirective::CreateEmpty(const
>> ASTContext &C,
>> + unsigned NumClauses,
>> + EmptyShell) {
>> + unsigned Size =
>> llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
>> + llvm::alignOf<OMPClause *>());
>> + void *Mem = C.Allocate(Size + sizeof(OMPClause *) *
>> NumClauses);
>> + return new (Mem) OMPFlushDirective(NumClauses);
>> +}
>> +
>>
>> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
>> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jul 21 06:26:11 2014
>> @@ -775,6 +775,12 @@ void OMPClausePrinter::VisitOMPCopypriva
>> }
>> }
>>
>> +void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause
>> *Node) {
>> + if (!Node->varlist_empty()) {
>> + VisitOMPClauseList(Node, '(');
>> + OS << ")";
>> + }
>> +}
>> }
>>
>> //===----------------------------------------------------------------------===//
>> @@ -875,6 +881,11 @@ void StmtPrinter::VisitOMPTaskwaitDirect
>> PrintOMPExecutableDirective(Node);
>> }
>>
>> +void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective
>> *Node) {
>> + Indent() << "#pragma omp flush ";
>> + PrintOMPExecutableDirective(Node);
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // Expr printing methods.
>> //===----------------------------------------------------------------------===//
>>
>> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
>> +++ cfe/trunk/lib/AST/StmtProfile.cpp Mon Jul 21 06:26:11 2014
>> @@ -352,6 +352,9 @@ void
>> OMPClauseProfiler::VisitOMPCopyprivateClause(const
>> OMPCopyprivateClause *C) {
>> VisitOMPClauseList(C);
>> }
>> +void OMPClauseProfiler::VisitOMPFlushClause(const
>> OMPFlushClause *C) {
>> + VisitOMPClauseList(C);
>> +}
>> }
>>
>> void
>> @@ -424,6 +427,10 @@ void StmtProfiler::VisitOMPTaskwaitDirec
>> VisitOMPExecutableDirective(S);
>> }
>>
>> +void StmtProfiler::VisitOMPFlushDirective(const
>> OMPFlushDirective *S) {
>> + VisitOMPExecutableDirective(S);
>> +}
>> +
>> void StmtProfiler::VisitExpr(const Expr *S) {
>> VisitStmt(S);
>> }
>>
>> Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
>> +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Mon Jul 21 06:26:11 2014
>> @@ -46,6 +46,8 @@ const char *clang::getOpenMPDirectiveNam
>> }
>>
>> OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
>> + if (Str == "flush")
>> + return OMPC_unknown;
>>
>>
>> I suggest adding a comment here on why the special case for flush
>> and link it with the comment about pseudo/implicit clauses.
>>
>> return llvm::StringSwitch<OpenMPClauseKind>(Str)
>> #define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
>> #include "clang/Basic/OpenMPKinds.def"
>> @@ -105,6 +107,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
>> case OMPC_nowait:
>> case OMPC_untied:
>> case OMPC_mergeable:
>> + case OMPC_flush:
>> break;
>> }
>> llvm_unreachable("Invalid OpenMP simple clause kind");
>> @@ -163,6 +166,7 @@ const char *clang::getOpenMPSimpleClause
>> case OMPC_nowait:
>> case OMPC_untied:
>> case OMPC_mergeable:
>> + case OMPC_flush:
>> break;
>> }
>> llvm_unreachable("Invalid OpenMP simple clause kind");
>> @@ -253,6 +257,9 @@ bool clang::isAllowedClauseForDirective(
>> break;
>> }
>> break;
>> + case OMPD_flush:
>> + return CKind == OMPC_flush;
>> + break;
>> case OMPD_unknown:
>> case OMPD_threadprivate:
>> case OMPD_section:
>>
>> Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Mon Jul 21 06:26:11 2014
>> @@ -218,6 +218,9 @@ void CodeGenFunction::EmitStmt(const Stm
>> case Stmt::OMPTaskwaitDirectiveClass:
>> EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S));
>> break;
>> + case Stmt::OMPFlushDirectiveClass:
>> + EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
>> + break;
>> }
>> }
>>
>>
>> Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Mon Jul 21
>> 06:26:11 2014
>> @@ -124,3 +124,7 @@ void CodeGenFunction::EmitOMPTaskwaitDir
>> llvm_unreachable("CodeGen for 'omp taskwait' is not
>> supported yet.");
>> }
>>
>> +void CodeGenFunction::EmitOMPFlushDirective(const
>> OMPFlushDirective &) {
>> + llvm_unreachable("CodeGen for 'omp flush' is not supported
>> yet.");
>> +}
>> +
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Jul 21
>> 06:26:11 2014
>> @@ -1935,6 +1935,7 @@ public:
>> void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective
>> &S);
>> void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
>> void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
>> + void EmitOMPFlushDirective(const OMPFlushDirective &S);
>>
>> //===--------------------------------------------------------------------===//
>> // LValue Expression Emission
>>
>> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Mon Jul 21 06:26:11 2014
>> @@ -86,6 +86,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
>> case OMPD_taskyield:
>> case OMPD_barrier:
>> case OMPD_taskwait:
>> + case OMPD_flush:
>> case OMPD_for:
>> case OMPD_sections:
>> case OMPD_section:
>> @@ -112,7 +113,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
>> /// annot_pragma_openmp 'parallel' | 'simd' | 'for'
>> | 'sections' |
>> /// 'section' | 'single' | 'master' | 'critical' [
>> '(' <name> ')' ] |
>> /// 'parallel for' | 'parallel sections' | 'task' |
>> 'taskyield' |
>> -/// 'barrier' | 'taskwait' {clause}
>> annot_pragma_openmp_end
>> +/// 'barrier' | 'taskwait' | 'flush' {clause}
>> annot_pragma_openmp_end
>> ///
>> StmtResult
>> Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool
>> StandAloneAllowed) {
>> @@ -130,6 +131,7 @@ Parser::ParseOpenMPDeclarativeOrExecutab
>> DeclarationNameInfo DirName;
>> StmtResult Directive = StmtError();
>> bool HasAssociatedStatement = true;
>> + bool FlushHasClause = false;
>>
>> switch (DKind) {
>> case OMPD_threadprivate:
>> @@ -148,6 +150,13 @@ Parser::ParseOpenMPDeclarativeOrExecutab
>> }
>> SkipUntil(tok::annot_pragma_openmp_end);
>> break;
>> + case OMPD_flush:
>> + if (PP.LookAhead(0).is(tok::l_paren)) {
>> + FlushHasClause = true;
>> + // Push copy of the current token back to stream to
>> properly parse
>> + // pseudo-clause OMPFlushClause.
>> + PP.EnterToken(Tok);
>> + }
>> case OMPD_taskyield:
>> case OMPD_barrier:
>> case OMPD_taskwait:
>> @@ -156,6 +165,7 @@ Parser::ParseOpenMPDeclarativeOrExecutab
>> << getOpenMPDirectiveName(DKind);
>> }
>> HasAssociatedStatement = false;
>> + // Fall through for further analysis.
>> case OMPD_parallel:
>> case OMPD_simd:
>> case OMPD_for:
>> @@ -192,9 +202,12 @@ Parser::ParseOpenMPDeclarativeOrExecutab
>> Actions.StartOpenMPDSABlock(DKind, DirName,
>> Actions.getCurScope(), Loc);
>>
>> while (Tok.isNot(tok::annot_pragma_openmp_end)) {
>> - OpenMPClauseKind CKind = Tok.isAnnotation()
>> - ? OMPC_unknown
>> - :
>> getOpenMPClauseKind(PP.getSpelling(Tok));
>> + OpenMPClauseKind CKind =
>> + Tok.isAnnotation()
>> + ? OMPC_unknown
>> + : FlushHasClause ? OMPC_flush
>> + :
>> getOpenMPClauseKind(PP.getSpelling(Tok));
>> + FlushHasClause = false;
>> OMPClause *Clause =
>> ParseOpenMPClause(DKind, CKind,
>> !FirstClauses[CKind].getInt());
>> FirstClauses[CKind].setInt(true);
>> @@ -324,7 +337,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op
>> /// | linear-clause | aligned-clause | collapse-clause |
>> /// lastprivate-clause | reduction-clause |
>> proc_bind-clause |
>> /// schedule-clause | copyin-clause |
>> copyprivate-clause | untied-clause |
>> -/// mergeable-clause
>> +/// mergeable-clause | flush-clause
>> ///
>> OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
>> OpenMPClauseKind CKind, bool FirstClause) {
>> @@ -407,6 +420,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
>> case OMPC_aligned:
>> case OMPC_copyin:
>> case OMPC_copyprivate:
>> + case OMPC_flush:
>> Clause = ParseOpenMPVarListClause(CKind);
>> break;
>> case OMPC_unknown:
>> @@ -605,7 +619,7 @@ static bool ParseReductionId(Parser &P,
>> }
>>
>> /// \brief Parsing of OpenMP clause 'private',
>> 'firstprivate', 'lastprivate',
>> -/// 'shared', 'copyin', or 'reduction'.
>> +/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
>> ///
>> /// private-clause:
>> /// 'private' '(' list ')'
>> @@ -621,6 +635,10 @@ static bool ParseReductionId(Parser &P,
>> /// 'aligned' '(' list [ ':' alignment ] ')'
>> /// reduction-clause:
>> /// 'reduction' '(' reduction-identifier ':' list ')'
>> +/// copyprivate-clause:
>> +/// 'copyprivate' '(' list ')'
>> +/// flush-clause:
>> +/// 'flush' '(' list ')'
>> ///
>> OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind
>> Kind) {
>> SourceLocation Loc = Tok.getLocation();
>> @@ -676,7 +694,10 @@ OMPClause *Parser::ParseOpenMPVarListCla
>> else if (Tok.isNot(tok::r_paren) &&
>> Tok.isNot(tok::annot_pragma_openmp_end) &&
>> (!MayHaveTail || Tok.isNot(tok::colon)))
>> - Diag(Tok, diag::err_omp_expected_punc) <<
>> getOpenMPClauseName(Kind);
>> + Diag(Tok, diag::err_omp_expected_punc)
>> + << ((Kind == OMPC_flush) ?
>> getOpenMPDirectiveName(OMPD_flush)
>> + : getOpenMPClauseName(Kind))
>> + << (Kind == OMPC_flush);
>> }
>>
>> // Parse ':' linear-step (or ':' alignment).
>>
>> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Jul 21 06:26:11 2014
>> @@ -1085,6 +1085,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
>> Params);
>> break;
>> }
>> + case OMPD_flush: {
>> + Sema::CapturedParamNameType Params[] = {
>> + std::make_pair(StringRef(), QualType()) // __context
>> with shared vars
>> + };
>> + ActOnCapturedRegionStart(DSAStack->getConstructLoc(),
>> CurScope, CR_OpenMP,
>> + Params);
>> + break;
>> + }
>> case OMPD_threadprivate:
>> llvm_unreachable("OpenMP Directive is not allowed");
>> case OMPD_unknown:
>> @@ -1114,6 +1122,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | parallel | taskyield | *
>> |
>> // | parallel | barrier | *
>> |
>> // | parallel | taskwait | *
>> |
>> + // | parallel | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | for | parallel | *
>> |
>> // | for | for | +
>> |
>> @@ -1129,6 +1138,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | for | taskyield | *
>> |
>> // | for | barrier | +
>> |
>> // | for | taskwait | *
>> |
>> + // | for | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | master | parallel | *
>> |
>> // | master | for | +
>> |
>> @@ -1144,6 +1154,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | master | taskyield | *
>> |
>> // | master | barrier | +
>> |
>> // | master | taskwait | *
>> |
>> + // | master | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | critical | parallel | *
>> |
>> // | critical | for | +
>> |
>> @@ -1174,6 +1185,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | simd | taskyield |
>> |
>> // | simd | barrier |
>> |
>> // | simd | taskwait |
>> |
>> + // | simd | flush |
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | sections | parallel | *
>> |
>> // | sections | for | +
>> |
>> @@ -1189,6 +1201,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | sections | taskyield | *
>> |
>> // | sections | barrier | +
>> |
>> // | sections | taskwait | *
>> |
>> + // | sections | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | section | parallel | *
>> |
>> // | section | for | +
>> |
>> @@ -1204,6 +1217,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | section | taskyield | *
>> |
>> // | section | barrier | +
>> |
>> // | section | taskwait | *
>> |
>> + // | section | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | single | parallel | *
>> |
>> // | single | for | +
>> |
>> @@ -1219,6 +1233,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | single | taskyield | *
>> |
>> // | single | barrier | +
>> |
>> // | single | taskwait | *
>> |
>> + // | single | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | parallel for | parallel | *
>> |
>> // | parallel for | for | +
>> |
>> @@ -1234,6 +1249,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | parallel for | taskyield | *
>> |
>> // | parallel for | barrier | +
>> |
>> // | parallel for | taskwait | *
>> |
>> + // | parallel for | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | parallel sections| parallel | *
>> |
>> // | parallel sections| for | +
>> |
>> @@ -1249,6 +1265,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | parallel sections| taskyield | *
>> |
>> // | parallel sections| barrier | +
>> |
>> // | parallel sections| taskwait | *
>> |
>> + // | parallel sections| flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> // | task | parallel | *
>> |
>> // | task | for | +
>> |
>> @@ -1264,6 +1281,7 @@ static bool CheckNestingOfRegions(Sema &
>> // | task | taskyield | *
>> |
>> // | task | barrier | +
>> |
>> // | task | taskwait | *
>> |
>> + // | task | flush | *
>> |
>> //
>> +------------------+-----------------+------------------------------------+
>> if (Stack->getCurScope()) {
>> auto ParentRegion = Stack->getParentDirective();
>> @@ -1371,6 +1389,7 @@ StmtResult Sema::ActOnOpenMPExecutableDi
>> llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
>> llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
>> bool ErrorFound = false;
>> + ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
>> if (AStmt) {
>> assert(isa<CapturedStmt>(AStmt) && "Captured statement
>> expected");
>>
>> @@ -1381,7 +1400,6 @@ StmtResult Sema::ActOnOpenMPExecutableDi
>> return StmtError();
>> // Generate list of implicitly defined firstprivate
>> variables.
>> VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
>> - ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
>>
>> if (!DSAChecker.getImplicitFirstprivate().empty()) {
>> if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
>> @@ -1464,6 +1482,11 @@ StmtResult Sema::ActOnOpenMPExecutableDi
>> "No associated statement allowed for 'omp
>> taskwait' directive");
>> Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
>> break;
>> + case OMPD_flush:
>> + assert(AStmt == nullptr &&
>> + "No associated statement allowed for 'omp flush'
>> directive");
>> + Res = ActOnOpenMPFlushDirective(ClausesWithImplicit,
>> StartLoc, EndLoc);
>> + break;
>> case OMPD_threadprivate:
>> llvm_unreachable("OpenMP Directive is not allowed");
>> case OMPD_unknown:
>> @@ -2234,6 +2257,13 @@ StmtResult Sema::ActOnOpenMPTaskwaitDire
>> return OMPTaskwaitDirective::Create(Context, StartLoc,
>> EndLoc);
>> }
>>
>> +StmtResult
>> Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
>> + SourceLocation StartLoc,
>> + SourceLocation EndLoc) {
>> + assert(Clauses.size() <= 1 && "Extra clauses in flush
>> directive");
>> + return OMPFlushDirective::Create(Context, StartLoc,
>> EndLoc, Clauses);
>> +}
>> +
>> OMPClause
>> *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
>> Expr *Expr,
>> SourceLocation StartLoc,
>> SourceLocation LParenLoc,
>> @@ -2272,6 +2302,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
>> case OMPC_untied:
>> case OMPC_mergeable:
>> case OMPC_threadprivate:
>> + case OMPC_flush:
>> case OMPC_unknown:
>> llvm_unreachable("Clause is not allowed.");
>> }
>> @@ -2474,6 +2505,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
>> case OMPC_untied:
>> case OMPC_mergeable:
>> case OMPC_threadprivate:
>> + case OMPC_flush:
>> case OMPC_unknown:
>> llvm_unreachable("Clause is not allowed.");
>> }
>> @@ -2588,6 +2620,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi
>> case OMPC_untied:
>> case OMPC_mergeable:
>> case OMPC_threadprivate:
>> + case OMPC_flush:
>> case OMPC_unknown:
>> llvm_unreachable("Clause is not allowed.");
>> }
>> @@ -2685,6 +2718,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM
>> case OMPC_default:
>> case OMPC_proc_bind:
>> case OMPC_threadprivate:
>> + case OMPC_flush:
>> case OMPC_unknown:
>> llvm_unreachable("Clause is not allowed.");
>> }
>> @@ -2748,6 +2782,9 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
>> case OMPC_copyprivate:
>> Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc,
>> LParenLoc, EndLoc);
>> break;
>> + case OMPC_flush:
>> + Res = ActOnOpenMPFlushClause(VarList, StartLoc,
>> LParenLoc, EndLoc);
>> + break;
>> case OMPC_if:
>> case OMPC_final:
>> case OMPC_num_threads:
>> @@ -4052,4 +4089,14 @@ OMPClause *Sema::ActOnOpenMPCopyprivateC
>> return OMPCopyprivateClause::Create(Context, StartLoc,
>> LParenLoc, EndLoc, Vars);
>> }
>>
>> +OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *>
>> VarList,
>> + SourceLocation StartLoc,
>> + SourceLocation LParenLoc,
>> + SourceLocation EndLoc) {
>> + if (VarList.empty())
>> + return nullptr;
>> +
>> + return OMPFlushClause::Create(Context, StartLoc,
>> LParenLoc, EndLoc, VarList);
>> +}
>> +
>> #undef DSAStack
>>
>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>> +++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jul 21 06:26:11 2014
>> @@ -1517,6 +1517,18 @@ public:
>> EndLoc);
>> }
>>
>> + /// \brief Build a new OpenMP 'flush' pseudo clause.
>> + ///
>> + /// By default, performs semantic analysis to build the
>> new OpenMP clause.
>> + /// Subclasses may override this routine to provide
>> different behavior.
>> + OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
>> + SourceLocation StartLoc,
>> + SourceLocation LParenLoc,
>> + SourceLocation EndLoc) {
>> + return getSema().ActOnOpenMPFlushClause(VarList,
>> StartLoc, LParenLoc,
>> + EndLoc);
>> + }
>> +
>> /// \brief Rebuild the operand to an Objective-C
>> \@synchronized statement.
>> ///
>> /// By default, performs semantic analysis to build the
>> new statement.
>> @@ -6610,6 +6622,17 @@ TreeTransform<Derived>::TransformOMPTask
>> return Res;
>> }
>>
>> +template <typename Derived>
>> +StmtResult
>> +TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective
>> *D) {
>> + DeclarationNameInfo DirName;
>> + getDerived().getSema().StartOpenMPDSABlock(OMPD_flush,
>> DirName, nullptr,
>> + D->getLocStart());
>> + StmtResult Res =
>> getDerived().TransformOMPExecutableDirective(D);
>> + getDerived().getSema().EndOpenMPDSABlock(Res.get());
>> + return Res;
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // OpenMP clause transformation
>> //===----------------------------------------------------------------------===//
>> @@ -6869,6 +6892,20 @@ TreeTransform<Derived>::TransformOMPCopy
>> Vars, C->getLocStart(), C->getLParenLoc(),
>> C->getLocEnd());
>> }
>>
>> +template <typename Derived>
>> +OMPClause
>> *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause
>> *C) {
>> + llvm::SmallVector<Expr *, 16> Vars;
>> + Vars.reserve(C->varlist_size());
>> + for (auto *VE : C->varlists()) {
>> + ExprResult EVar =
>> getDerived().TransformExpr(cast<Expr>(VE));
>> + if (EVar.isInvalid())
>> + return nullptr;
>> + Vars.push_back(EVar.get());
>> + }
>> + return getDerived().RebuildOMPFlushClause(Vars,
>> C->getLocStart(),
>> + C->getLParenLoc(), C->getLocEnd());
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // Expression transformation
>> //===----------------------------------------------------------------------===//
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Jul 21
>> 06:26:11 2014
>> @@ -1742,6 +1742,9 @@ OMPClause *OMPClauseReader::readClause()
>> case OMPC_copyprivate:
>> C = OMPCopyprivateClause::CreateEmpty(Context,
>> Record[Idx++]);
>> break;
>> + case OMPC_flush:
>> + C = OMPFlushClause::CreateEmpty(Context, Record[Idx++]);
>> + break;
>> }
>> Visit(C);
>> C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
>> @@ -1908,6 +1911,16 @@ void OMPClauseReader::VisitOMPCopyprivat
>> C->setVarRefs(Vars);
>> }
>>
>> +void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) {
>> + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
>> + unsigned NumVars = C->varlist_size();
>> + SmallVector<Expr *, 16> Vars;
>> + Vars.reserve(NumVars);
>> + for (unsigned i = 0; i != NumVars; ++i)
>> + Vars.push_back(Reader->Reader.ReadSubExpr());
>> + C->setVarRefs(Vars);
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // OpenMP Directives.
>> //===----------------------------------------------------------------------===//
>> @@ -2011,6 +2024,13 @@ void ASTStmtReader::VisitOMPTaskwaitDire
>> VisitOMPExecutableDirective(D);
>> }
>>
>> +void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective
>> *D) {
>> + VisitStmt(D);
>> + // The NumClauses field was read in ReadStmtFromStream.
>> + ++Idx;
>> + VisitOMPExecutableDirective(D);
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // ASTReader Implementation
>> //===----------------------------------------------------------------------===//
>> @@ -2561,6 +2581,11 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
>> S = OMPTaskwaitDirective::CreateEmpty(Context, Empty);
>> break;
>>
>> + case STMT_OMP_FLUSH_DIRECTIVE:
>> + S = OMPFlushDirective::CreateEmpty(
>> + Context, Record[ASTStmtReader::NumStmtFields], Empty);
>> + break;
>> +
>> case EXPR_CXX_OPERATOR_CALL:
>> S = new (Context) CXXOperatorCallExpr(Context, Empty);
>> break;
>>
>> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Jul 21
>> 06:26:11 2014
>> @@ -1805,6 +1805,13 @@ void OMPClauseWriter::VisitOMPCopyprivat
>> Writer->Writer.AddStmt(VE);
>> }
>>
>> +void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
>> + Record.push_back(C->varlist_size());
>> + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
>> + for (auto *VE : C->varlists())
>> + Writer->Writer.AddStmt(VE);
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // OpenMP Directives.
>> //===----------------------------------------------------------------------===//
>> @@ -1916,6 +1923,13 @@ void ASTStmtWriter::VisitOMPTaskwaitDire
>> Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
>> }
>>
>> +void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective
>> *D) {
>> + VisitStmt(D);
>> + Record.push_back(D->getNumClauses());
>> + VisitOMPExecutableDirective(D);
>> + Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
>> +}
>> +
>> //===----------------------------------------------------------------------===//
>> // ASTWriter Implementation
>> //===----------------------------------------------------------------------===//
>>
>> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
>> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Jul
>> 21 06:26:11 2014
>> @@ -745,6 +745,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
>> case Stmt::OMPTaskyieldDirectiveClass:
>> case Stmt::OMPBarrierDirectiveClass:
>> case Stmt::OMPTaskwaitDirectiveClass:
>> + case Stmt::OMPFlushDirectiveClass:
>> llvm_unreachable("Stmt should not be in analyzer
>> evaluation loop");
>>
>> case Stmt::ObjCSubscriptRefExprClass:
>>
>> Added: cfe/trunk/test/OpenMP/flush_ast_print.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/flush_ast_print.cpp?rev=213512&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/OpenMP/flush_ast_print.cpp (added)
>> +++ cfe/trunk/test/OpenMP/flush_ast_print.cpp Mon Jul 21
>> 06:26:11 2014
>> @@ -0,0 +1,38 @@
>> +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s |
>> FileCheck %s
>> +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11
>> -emit-pch -o %t %s
>> +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch
>> %t -fsyntax-only -verify %s -ast-print | FileCheck %s
>> +// expected-no-diagnostics
>> +
>> +#ifndef HEADER
>> +#define HEADER
>> +
>> +void foo() {}
>> +
>> +template <class T>
>> +T tmain(T argc) {
>> + static T a;
>> +#pragma omp flush
>> +#pragma omp flush(a)
>> + return a + argc;
>> +}
>> +// CHECK: static int a;
>> +// CHECK-NEXT: #pragma omp flush
>> +// CHECK-NEXT: #pragma omp flush (a)
>> +// CHECK: static char a;
>> +// CHECK-NEXT: #pragma omp flush
>> +// CHECK-NEXT: #pragma omp flush (a)
>> +// CHECK: static T a;
>> +// CHECK-NEXT: #pragma omp flush
>> +// CHECK-NEXT: #pragma omp flush (a)
>> +
>> +int main(int argc, char **argv) {
>> + static int a;
>> +// CHECK: static int a;
>> +#pragma omp flush
>> +#pragma omp flush(a)
>> +// CHECK-NEXT: #pragma omp flush
>> +// CHECK-NEXT: #pragma omp flush (a)
>> + return tmain(argc) + tmain(argv[0][0]) + a;
>> +}
>> +
>> +#endif
>>
>> Propchange: cfe/trunk/test/OpenMP/flush_ast_print.cpp
>> ------------------------------------------------------------------------------
>> svn:eol-style = native
>>
>> Propchange: cfe/trunk/test/OpenMP/flush_ast_print.cpp
>> ------------------------------------------------------------------------------
>> svn:keywords = Author Date Id Rev URL
>>
>> Propchange: cfe/trunk/test/OpenMP/flush_ast_print.cpp
>> ------------------------------------------------------------------------------
>> svn:mime-type = text/plain
>>
>> Added: cfe/trunk/test/OpenMP/flush_messages.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/flush_messages.cpp?rev=213512&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/OpenMP/flush_messages.cpp (added)
>> +++ cfe/trunk/test/OpenMP/flush_messages.cpp Mon Jul 21
>> 06:26:11 2014
>> @@ -0,0 +1,134 @@
>> +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit
>> 100 %s
>> +
>> +struct S1 { // expected-note 2 {{declared here}}
>> + int a;
>> +};
>> +
>> +template <class T>
>> +T tmain(T argc) {
>> +#pragma omp flush
>> + ;
>> +#pragma omp flush untied // expected-error {{unexpected
>> OpenMP clause 'untied' in directive '#pragma omp flush'}}
>> +#pragma omp flush unknown // expected-warning {{extra tokens
>> at the end of '#pragma omp flush' are ignored}}
>> + if (argc)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>>
>>
>> I think "cannot have" seems more accurate than "cannot be" in the
>> diagnostic message.
>>
>> + if (argc) {
>> +#pragma omp flush
>> + }
>> + while (argc)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + while (argc) {
>> +#pragma omp flush
>> + }
>> + do
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + while (argc)
>> + ;
>> + do {
>> +#pragma omp flush
>> + } while (argc);
>> + switch (argc)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + switch (argc)
>> + case 1:
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + switch (argc)
>> + case 1: {
>> +#pragma omp flush
>> + }
>> + switch (argc) {
>> +#pragma omp flush
>> + case 1:
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + break;
>> + default: {
>> +#pragma omp flush
>> + } break;
>> + }
>> + for (;;)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + for (;;) {
>> +#pragma omp flush
>> + }
>> +label:
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> +label1 : {
>> +#pragma omp flush
>> +}
>> +
>> +#pragma omp flush
>> +#pragma omp flush( // expected-error {{expected
>> expression}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> +#pragma omp flush() // expected-error {{expected expression}}
>> +#pragma omp flush(argc // expected-error {{expected ')'}}
>> expected-note {{to match this '('}}
>> +#pragma omp flush(argc, // expected-error {{expected
>> expression}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> +#pragma omp flush(argc)
>> +#pragma omp flush(S1) // expected-error {{'S1' does not
>> refer to a value}}
>> +#pragma omp flush(argc) flush(argc) // expected-warning
>> {{extra tokens at the end of '#pragma omp flush' are ignored}}
>> +#pragma omp parallel flush(argc) // expected-warning {{extra
>> tokens at the end of '#pragma omp parallel' are ignored}}
>>
>>
>> I would expect these two last warnings to be errors. That is my
>> understanding of "standalone directive" in the OpenMP spec. Gcc
>> currently emits an error for the same constructs, so, unless
>> there is a strong reason to emit the warning, I think clang
>> should also emit an error here.
>>
>> + ;
>> + return T();
>> +}
>> +
>> +int main(int argc, char **argv) {
>> +#pragma omp flush
>> + ;
>> +#pragma omp flush untied // expected-error {{unexpected
>> OpenMP clause 'untied' in directive '#pragma omp flush'}}
>> +#pragma omp flush unknown // expected-warning {{extra tokens
>> at the end of '#pragma omp flush' are ignored}}
>> + if (argc)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + if (argc) {
>> +#pragma omp flush
>> + }
>> + while (argc)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + while (argc) {
>> +#pragma omp flush
>> + }
>> + do
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + while (argc)
>> + ;
>> + do {
>> +#pragma omp flush
>> + } while (argc);
>> + switch (argc)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + switch (argc)
>> + case 1:
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + switch (argc)
>> + case 1: {
>> +#pragma omp flush
>> + }
>> + switch (argc) {
>> +#pragma omp flush
>> + case 1:
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + break;
>> + default: {
>> +#pragma omp flush
>> + } break;
>> + }
>> + for (;;)
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> + for (;;) {
>> +#pragma omp flush
>> + }
>> +label:
>> +#pragma omp flush // expected-error {{'#pragma omp flush'
>> cannot be an immediate substatement}}
>> +label1 : {
>> +#pragma omp flush
>> +}
>> +
>> +#pragma omp flush
>> +#pragma omp flush( // expected-error {{expected
>> expression}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> +#pragma omp flush() // expected-error {{expected expression}}
>> +#pragma omp flush(argc // expected-error {{expected ')'}}
>> expected-note {{to match this '('}}
>> +#pragma omp flush(argc, // expected-error {{expected
>> expression}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> +#pragma omp flush(argc)
>> +#pragma omp flush(S1) // expected-error {{'S1' does not
>> refer to a value}}
>> +#pragma omp flush(argc) flush(argc) // expected-warning
>> {{extra tokens at the end of '#pragma omp flush' are ignored}}
>> +#pragma omp parallel flush(argc) // expected-warning {{extra
>> tokens at the end of '#pragma omp parallel' are ignored}}
>> + ;
>> + return tmain(argc);
>> +}
>>
>> Propchange: cfe/trunk/test/OpenMP/flush_messages.cpp
>> ------------------------------------------------------------------------------
>> svn:eol-style = native
>>
>> Propchange: cfe/trunk/test/OpenMP/flush_messages.cpp
>> ------------------------------------------------------------------------------
>> svn:keywords = Author Date Id Rev URL
>>
>> Propchange: cfe/trunk/test/OpenMP/flush_messages.cpp
>> ------------------------------------------------------------------------------
>> svn:mime-type = text/plain
>>
>> Modified: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/nesting_of_regions.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original)
>> +++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Mon Jul 21
>> 06:26:11 2014
>> @@ -66,6 +66,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp parallel
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // SIMD DIRECTIVE
>> #pragma omp simd
>> @@ -156,6 +161,11 @@ void foo() {
>> #pragma omp taskwait // expected-error {{OpenMP constructs
>> may not be nested inside a simd region}}
>> bar();
>> }
>> +#pragma omp simd
>> + for (int i = 0; i < 10; ++i) {
>> +#pragma omp flush // expected-error {{OpenMP constructs may
>> not be nested inside a simd region}}
>> + bar();
>> + }
>>
>> // FOR DIRECTIVE
>> #pragma omp for
>> @@ -264,6 +274,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp for
>> + for (int i = 0; i < 10; ++i) {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // SECTIONS DIRECTIVE
>> #pragma omp sections
>> @@ -385,6 +400,10 @@ void foo() {
>> {
>> #pragma omp taskwait
>> }
>> +#pragma omp sections
>> + {
>> +#pragma omp flush
>> + }
>>
>> // SECTION DIRECTIVE
>> #pragma omp section // expected-error {{orphaned 'omp
>> section' directives are prohibited, it must be closely nested
>> to a sections region}}
>> @@ -523,6 +542,14 @@ void foo() {
>> bar();
>> }
>> }
>> +#pragma omp sections
>> + {
>> +#pragma omp section
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>> + }
>>
>> // SINGLE DIRECTIVE
>> #pragma omp single
>> @@ -623,6 +650,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp single
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // MASTER DIRECTIVE
>> #pragma omp master
>> @@ -723,6 +755,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp master
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // CRITICAL DIRECTIVE
>> #pragma omp critical
>> @@ -952,6 +989,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp parallel for
>> + for (int i = 0; i < 10; ++i) {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // PARALLEL SECTIONS DIRECTIVE
>> #pragma omp parallel sections
>> @@ -1059,6 +1101,10 @@ void foo() {
>> {
>> #pragma omp taskwait
>> }
>> +#pragma omp parallel sections
>> + {
>> +#pragma omp flush
>> + }
>>
>> // TASK DIRECTIVE
>> #pragma omp task
>> @@ -1118,6 +1164,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp task
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>> }
>>
>> void foo() {
>> @@ -1183,6 +1234,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp parallel
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // SIMD DIRECTIVE
>> #pragma omp simd
>> @@ -1266,6 +1322,11 @@ void foo() {
>> #pragma omp taskwait // expected-error {{OpenMP constructs
>> may not be nested inside a simd region}}
>> bar();
>> }
>> +#pragma omp simd
>> + for (int i = 0; i < 10; ++i) {
>> +#pragma omp flush // expected-error {{OpenMP constructs may
>> not be nested inside a simd region}}
>> + bar();
>> + }
>>
>> // FOR DIRECTIVE
>> #pragma omp for
>> @@ -1361,6 +1422,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp for
>> + for (int i = 0; i < 10; ++i) {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // SECTIONS DIRECTIVE
>> #pragma omp sections
>> @@ -1454,6 +1520,10 @@ void foo() {
>> {
>> #pragma omp taskwait
>> }
>> +#pragma omp sections
>> + {
>> +#pragma omp flush
>> + }
>>
>> // SECTION DIRECTIVE
>> #pragma omp section // expected-error {{orphaned 'omp
>> section' directives are prohibited, it must be closely nested
>> to a sections region}}
>> @@ -1592,6 +1662,14 @@ void foo() {
>> bar();
>> }
>> }
>> +#pragma omp sections
>> + {
>> +#pragma omp section
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>> + }
>>
>> // SINGLE DIRECTIVE
>> #pragma omp single
>> @@ -1682,6 +1760,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp single
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // MASTER DIRECTIVE
>> #pragma omp master
>> @@ -1782,6 +1865,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp master
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // CRITICAL DIRECTIVE
>> #pragma omp critical
>> @@ -2010,6 +2098,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp parallel for
>> + for (int i = 0; i < 10; ++i) {
>> +#pragma omp flush
>> + bar();
>> + }
>>
>> // PARALLEL SECTIONS DIRECTIVE
>> #pragma omp parallel sections
>> @@ -2113,6 +2206,10 @@ void foo() {
>> {
>> #pragma omp taskwait
>> }
>> +#pragma omp parallel sections
>> + {
>> +#pragma omp flush
>> + }
>>
>> // TASK DIRECTIVE
>> #pragma omp task
>> @@ -2171,6 +2268,11 @@ void foo() {
>> #pragma omp taskwait
>> bar();
>> }
>> +#pragma omp task
>> + {
>> +#pragma omp flush
>> + bar();
>> + }
>> return foo<int>();
>> }
>>
>>
>> Modified: cfe/trunk/tools/libclang/CIndex.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
>> +++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jul 21 06:26:11 2014
>> @@ -1870,6 +1870,7 @@ public:
>> void VisitOMPTaskyieldDirective(const
>> OMPTaskyieldDirective *D);
>> void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
>> void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
>> + void VisitOMPFlushDirective(const OMPFlushDirective *D);
>>
>> private:
>> void AddDeclarationNameInfo(const Stmt *S);
>> @@ -2016,6 +2017,9 @@ void
>> OMPClauseEnqueue::VisitOMPCopyprivateClause(const
>> OMPCopyprivateClause *C) {
>> VisitOMPClauseList(C);
>> }
>> +void OMPClauseEnqueue::VisitOMPFlushClause(const
>> OMPFlushClause *C) {
>> + VisitOMPClauseList(C);
>> +}
>> }
>>
>> void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
>> @@ -2365,6 +2369,10 @@ void EnqueueVisitor::VisitOMPTaskwaitDir
>> VisitOMPExecutableDirective(D);
>> }
>>
>> +void EnqueueVisitor::VisitOMPFlushDirective(const
>> OMPFlushDirective *D) {
>> + VisitOMPExecutableDirective(D);
>> +}
>> +
>> void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL,
>> const Stmt *S) {
>> EnqueueVisitor(WL, MakeCXCursor(S, StmtParent,
>> TU,RegionOfInterest)).Visit(S);
>> }
>> @@ -4065,6 +4073,8 @@ CXString clang_getCursorKindSpelling(enu
>> return cxstring::createRef("OMPBarrierDirective");
>> case CXCursor_OMPTaskwaitDirective:
>> return cxstring::createRef("OMPTaskwaitDirective");
>> + case CXCursor_OMPFlushDirective:
>> + return cxstring::createRef("OMPFlushDirective");
>> }
>>
>> llvm_unreachable("Unhandled CXCursorKind");
>>
>> Modified: cfe/trunk/tools/libclang/CXCursor.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=213512&r1=213511&r2=213512&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXCursor.cpp (original)
>> +++ cfe/trunk/tools/libclang/CXCursor.cpp Mon Jul 21 06:26:11
>> 2014
>> @@ -559,6 +559,9 @@ CXCursor cxcursor::MakeCXCursor(const St
>> case Stmt::OMPTaskwaitDirectiveClass:
>> K = CXCursor_OMPTaskwaitDirective;
>> break;
>> + case Stmt::OMPFlushDirectiveClass:
>> + K = CXCursor_OMPFlushDirective;
>> + break;
>> }
>>
>> CXCursor C = { K, 0, { Parent, S, TU } };
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu <mailto:cfe-commits at cs.uiuc.edu>
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu <mailto:cfe-commits at cs.uiuc.edu>
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
More information about the cfe-commits
mailing list