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