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