<div dir="ltr"><div>I have reviewed this while reviewing: <br><h2>r212516 - [OPENMP] Parsing and sema analysis for 'omp parallel sections' directive.</h2><span><table cellpadding="0">
<tbody><tr><td style="background-color:rgb(221,221,221);color:rgb(102,102,102)"><br></td><td style="background-color:rgb(221,221,221);color:rgb(102,102,102)"><br></td></tr></tbody></table></span><br>
</div>All the code is a similar pattern and looks good.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jun 27, 2014 at 6:37 AM, Alexey Bataev <span dir="ltr"><<a href="mailto:a.bataev@hotmail.com" target="_blank">a.bataev@hotmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: abataev<br>
Date: Fri Jun 27 05:37:06 2014<br>
New Revision: 211886<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=211886&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=211886&view=rev</a><br>
Log:<br>
[OPENMP] Parsing and sema analysis for 'copyprivate' clause.<br>
<br>
Added:<br>
cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp (with props)<br>
Modified:<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/Basic/DiagnosticSemaKinds.td<br>
cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
cfe/trunk/include/clang/Sema/Sema.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/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/test/OpenMP/single_ast_print.cpp<br>
cfe/trunk/tools/libclang/CIndex.cpp<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Fri Jun 27 05:37:06 2014<br>
@@ -2434,6 +2434,13 @@ bool RecursiveASTVisitor<Derived>::Visit<br>
}<br>
<br>
template <typename Derived><br>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(<br>
+ OMPCopyprivateClause *C) {<br>
+ VisitOMPClauseList(C);<br>
+ return true;<br>
+}<br>
+<br>
+template <typename Derived><br>
bool<br>
RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {<br>
TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)<br>
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Fri Jun 27 05:37:06 2014<br>
@@ -1218,6 +1218,66 @@ public:<br>
}<br>
};<br>
<br>
+/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'<br>
+/// directives.<br>
+///<br>
+/// \code<br>
+/// #pragma omp single copyprivate(a,b)<br>
+/// \endcode<br>
+/// In this example directive '#pragma omp single' has clause 'copyprivate'<br>
+/// with the variables 'a' and 'b'.<br>
+///<br>
+class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> {<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>
+ OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,<br>
+ SourceLocation EndLoc, unsigned N)<br>
+ : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,<br>
+ LParenLoc, EndLoc, N) {}<br>
+<br>
+ /// \brief Build an empty clause.<br>
+ ///<br>
+ /// \param N Number of variables.<br>
+ ///<br>
+ explicit OMPCopyprivateClause(unsigned N)<br>
+ : OMPVarListClause<OMPCopyprivateClause>(<br>
+ OMPC_copyprivate, SourceLocation(), SourceLocation(),<br>
+ SourceLocation(), 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 OMPCopyprivateClause *<br>
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,<br>
+ SourceLocation EndLoc, 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 OMPCopyprivateClause *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_copyprivate;<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Jun 27 05:37:06 2014<br>
@@ -2456,6 +2456,13 @@ bool RecursiveASTVisitor<Derived>::Visit<br>
}<br>
<br>
template <typename Derived><br>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(<br>
+ OMPCopyprivateClause *C) {<br>
+ VisitOMPClauseList(C);<br>
+ return true;<br>
+}<br>
+<br>
+template <typename Derived><br>
bool<br>
RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {<br>
TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 27 05:37:06 2014<br>
@@ -7026,6 +7026,8 @@ def note_omp_predetermined_dsa : Note<<br>
"global variable is predetermined as shared|"<br>
"variable with automatic storage duration is predetermined as private}0"<br>
"%select{|; perhaps you forget to enclose 'omp %2' directive into a parallel or another task region?}1">;<br>
+def note_omp_implicit_dsa : Note<<br>
+ "implicitly determined as %0">;<br>
def err_omp_loop_var_dsa : Error<<br>
"loop iteration variable may not be %0">;<br>
def err_omp_not_for : 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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)<br>
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Fri Jun 27 05:37:06 2014<br>
@@ -67,6 +67,7 @@ OPENMP_CLAUSE(reduction, OMPReductionCl<br>
OPENMP_CLAUSE(linear, OMPLinearClause)<br>
OPENMP_CLAUSE(aligned, OMPAlignedClause)<br>
OPENMP_CLAUSE(copyin, OMPCopyinClause)<br>
+OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause)<br>
OPENMP_CLAUSE(proc_bind, OMPProcBindClause)<br>
OPENMP_CLAUSE(schedule, OMPScheduleClause)<br>
OPENMP_CLAUSE(ordered, OMPOrderedClause)<br>
@@ -111,6 +112,7 @@ OPENMP_SECTIONS_CLAUSE(nowait)<br>
// TODO more clauses allowed for directive 'omp single'.<br>
OPENMP_SINGLE_CLAUSE(private)<br>
OPENMP_SINGLE_CLAUSE(firstprivate)<br>
+OPENMP_SINGLE_CLAUSE(copyprivate)<br>
OPENMP_SINGLE_CLAUSE(nowait)<br>
<br>
// Static attributes for 'default' clause.<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun 27 05:37:06 2014<br>
@@ -7279,8 +7279,8 @@ public:<br>
Expr *Op);<br>
/// \brief Called on start of new data sharing attribute block.<br>
void StartOpenMPDSABlock(OpenMPDirectiveKind K,<br>
- const DeclarationNameInfo &DirName,<br>
- Scope *CurScope);<br>
+ const DeclarationNameInfo &DirName, Scope *CurScope,<br>
+ SourceLocation Loc);<br>
/// \brief Called on end of data sharing attribute block.<br>
void EndOpenMPDSABlock(Stmt *CurDirective);<br>
<br>
@@ -7300,8 +7300,7 @@ public:<br>
ArrayRef<Expr *> VarList);<br>
<br>
// brief Initialization of captured region for OpenMP region.<br>
- void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,<br>
- Scope *CurScope);<br>
+ void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);<br>
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,<br>
ArrayRef<OMPClause *> Clauses,<br>
Stmt *AStmt,<br>
@@ -7460,6 +7459,11 @@ public:<br>
SourceLocation StartLoc,<br>
SourceLocation LParenLoc,<br>
SourceLocation EndLoc);<br>
+ /// \brief Called on well-formed 'copyprivate' clause.<br>
+ OMPClause *ActOnOpenMPCopyprivateClause(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/lib/AST/Stmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Stmt.cpp (original)<br>
+++ cfe/trunk/lib/AST/Stmt.cpp Fri Jun 27 05:37:06 2014<br>
@@ -1280,6 +1280,28 @@ OMPCopyinClause *OMPCopyinClause::Create<br>
return new (Mem) OMPCopyinClause(N);<br>
}<br>
<br>
+OMPCopyprivateClause *OMPCopyprivateClause::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(OMPCopyprivateClause),<br>
+ llvm::alignOf<Expr *>()) +<br>
+ sizeof(Expr *) * VL.size());<br>
+ OMPCopyprivateClause *Clause =<br>
+ new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());<br>
+ Clause->setVarRefs(VL);<br>
+ return Clause;<br>
+}<br>
+<br>
+OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,<br>
+ unsigned N) {<br>
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),<br>
+ llvm::alignOf<Expr *>()) +<br>
+ sizeof(Expr *) * N);<br>
+ return new (Mem) OMPCopyprivateClause(N);<br>
+}<br>
+<br>
void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {<br>
assert(Clauses.size() == getNumClauses() &&<br>
"Number of clauses is not the same as the preallocated buffer");<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Jun 27 05:37:06 2014<br>
@@ -748,6 +748,14 @@ void OMPClausePrinter::VisitOMPCopyinCla<br>
}<br>
}<br>
<br>
+void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {<br>
+ if (!Node->varlist_empty()) {<br>
+ OS << "copyprivate";<br>
+ VisitOMPClauseList(Node, '(');<br>
+ OS << ")";<br>
+ }<br>
+}<br>
+<br>
}<br>
<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtProfile.cpp Fri Jun 27 05:37:06 2014<br>
@@ -335,6 +335,10 @@ void OMPClauseProfiler::VisitOMPAlignedC<br>
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {<br>
VisitOMPClauseList(C);<br>
}<br>
+void<br>
+OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {<br>
+ VisitOMPClauseList(C);<br>
+}<br>
}<br>
<br>
void<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)<br>
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Fri Jun 27 05:37:06 2014<br>
@@ -95,6 +95,7 @@ unsigned clang::getOpenMPSimpleClauseTyp<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
case OMPC_ordered:<br>
case OMPC_nowait:<br>
break;<br>
@@ -149,6 +150,7 @@ const char *clang::getOpenMPSimpleClause<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
case OMPC_ordered:<br>
case OMPC_nowait:<br>
break;<br>
@@ -193,7 +195,7 @@ bool clang::isAllowedClauseForDirective(<br>
break;<br>
case OMPD_sections:<br>
switch (CKind) {<br>
-#define OPENMP_SECTIONS_CLAUSE(Name) \<br>
+#define OPENMP_SECTIONS_CLAUSE(Name) \<br>
case OMPC_##Name: \<br>
return true;<br>
#include "clang/Basic/OpenMPKinds.def"<br>
@@ -203,7 +205,7 @@ bool clang::isAllowedClauseForDirective(<br>
break;<br>
case OMPD_single:<br>
switch (CKind) {<br>
-#define OPENMP_SINGLE_CLAUSE(Name) \<br>
+#define OPENMP_SINGLE_CLAUSE(Name) \<br>
case OMPC_##Name: \<br>
return true;<br>
#include "clang/Basic/OpenMPKinds.def"<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Fri Jun 27 05:37:06 2014<br>
@@ -131,7 +131,7 @@ StmtResult Parser::ParseOpenMPDeclarativ<br>
if (isOpenMPSimdDirective(DKind))<br>
ScopeFlags |= Scope::OpenMPSimdDirectiveScope;<br>
ParseScope OMPDirectiveScope(this, ScopeFlags);<br>
- Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope());<br>
+ Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);<br>
<br>
while (Tok.isNot(tok::annot_pragma_openmp_end)) {<br>
OpenMPClauseKind CKind = Tok.isAnnotation()<br>
@@ -159,7 +159,7 @@ StmtResult Parser::ParseOpenMPDeclarativ<br>
{<br>
// The body is a block scope like in Lambdas and Blocks.<br>
Sema::CompoundScopeRAII CompoundScope(Actions);<br>
- Actions.ActOnOpenMPRegionStart(DKind, Loc, getCurScope());<br>
+ Actions.ActOnOpenMPRegionStart(DKind, getCurScope());<br>
Actions.ActOnStartOfCompoundStmt();<br>
// Parse statement<br>
AssociatedStmt = ParseStatement();<br>
@@ -269,7 +269,8 @@ bool Parser::ParseOpenMPSimpleVarList(Op<br>
/// if-clause | num_threads-clause | safelen-clause | default-clause |<br>
/// private-clause | firstprivate-clause | shared-clause | linear-clause |<br>
/// aligned-clause | collapse-clause | lastprivate-clause |<br>
-/// reduction-clause | proc_bind-clause | schedule-clause<br>
+/// reduction-clause | proc_bind-clause | schedule-clause |<br>
+/// copyin-clause | copyprivate-clause<br>
///<br>
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,<br>
OpenMPClauseKind CKind, bool FirstClause) {<br>
@@ -345,6 +346,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
Clause = ParseOpenMPVarListClause(CKind);<br>
break;<br>
case OMPC_unknown:<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Jun 27 05:37:06 2014<br>
@@ -68,7 +68,10 @@ public:<br>
OpenMPDirectiveKind DKind;<br>
OpenMPClauseKind CKind;<br>
DeclRefExpr *RefExpr;<br>
- DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr) {}<br>
+ SourceLocation ImplicitDSALoc;<br>
+ DSAVarData()<br>
+ : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),<br>
+ ImplicitDSALoc() {}<br>
};<br>
<br>
private:<br>
@@ -83,17 +86,20 @@ private:<br>
DeclSAMapTy SharingMap;<br>
AlignedMapTy AlignedMap;<br>
DefaultDataSharingAttributes DefaultAttr;<br>
+ SourceLocation DefaultAttrLoc;<br>
OpenMPDirectiveKind Directive;<br>
DeclarationNameInfo DirectiveName;<br>
Scope *CurScope;<br>
+ SourceLocation ConstructLoc;<br>
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,<br>
- Scope *CurScope)<br>
+ Scope *CurScope, SourceLocation Loc)<br>
: SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),<br>
- Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope) {<br>
- }<br>
+ Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),<br>
+ ConstructLoc(Loc) {}<br>
SharingMapTy()<br>
: SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),<br>
- Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr) {}<br>
+ Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),<br>
+ ConstructLoc() {}<br>
};<br>
<br>
typedef SmallVector<SharingMapTy, 64> StackTy;<br>
@@ -113,8 +119,9 @@ public:<br>
explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}<br>
<br>
void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,<br>
- Scope *CurScope) {<br>
- Stack.push_back(SharingMapTy(DKind, DirName, CurScope));<br>
+ Scope *CurScope, SourceLocation Loc) {<br>
+ Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));<br>
+ Stack.back().DefaultAttrLoc = Loc;<br>
}<br>
<br>
void pop() {<br>
@@ -160,13 +167,22 @@ public:<br>
}<br>
<br>
/// \brief Set default data sharing attribute to none.<br>
- void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }<br>
+ void setDefaultDSANone(SourceLocation Loc) {<br>
+ Stack.back().DefaultAttr = DSA_none;<br>
+ Stack.back().DefaultAttrLoc = Loc;<br>
+ }<br>
/// \brief Set default data sharing attribute to shared.<br>
- void setDefaultDSAShared() { Stack.back().DefaultAttr = DSA_shared; }<br>
+ void setDefaultDSAShared(SourceLocation Loc) {<br>
+ Stack.back().DefaultAttr = DSA_shared;<br>
+ Stack.back().DefaultAttrLoc = Loc;<br>
+ }<br>
<br>
DefaultDataSharingAttributes getDefaultDSA() const {<br>
return Stack.back().DefaultAttr;<br>
}<br>
+ SourceLocation getDefaultDSALocation() const {<br>
+ return Stack.back().DefaultAttrLoc;<br>
+ }<br>
<br>
/// \brief Checks if the specified variable is a threadprivate.<br>
bool isThreadPrivate(VarDecl *D) {<br>
@@ -176,6 +192,7 @@ public:<br>
<br>
Scope *getCurScope() const { return Stack.back().CurScope; }<br>
Scope *getCurScope() { return Stack.back().CurScope; }<br>
+ SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }<br>
};<br>
} // namespace<br>
<br>
@@ -227,6 +244,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS<br>
switch (Iter->DefaultAttr) {<br>
case DSA_shared:<br>
DVar.CKind = OMPC_shared;<br>
+ DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;<br>
return DVar;<br>
case DSA_none:<br>
return DVar;<br>
@@ -235,6 +253,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS<br>
// in a Construct, implicitly determined, p.2]<br>
// In a parallel construct, if no default clause is present, these<br>
// variables are shared.<br>
+ DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;<br>
if (isOpenMPParallelDirective(DVar.DKind)) {<br>
DVar.CKind = OMPC_shared;<br>
return DVar;<br>
@@ -456,8 +475,8 @@ void Sema::DestroyDataSharingAttributesS<br>
<br>
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,<br>
const DeclarationNameInfo &DirName,<br>
- Scope *CurScope) {<br>
- DSAStack->push(DKind, DirName, CurScope);<br>
+ Scope *CurScope, SourceLocation Loc) {<br>
+ DSAStack->push(DKind, DirName, CurScope, Loc);<br>
PushExpressionEvaluationContext(PotentiallyEvaluated);<br>
}<br>
<br>
@@ -776,8 +795,9 @@ static void ReportOriginalDSA(Sema &Sema<br>
PDSA_LoopIterVarLastprivate,<br>
PDSA_ConstVarShared,<br>
PDSA_GlobalVarShared,<br>
- PDSA_LocalVarPrivate<br>
- } Reason;<br>
+ PDSA_LocalVarPrivate,<br>
+ PDSA_Implicit<br>
+ } Reason = PDSA_Implicit;<br>
bool ReportHint = false;<br>
if (IsLoopIterVar) {<br>
if (DVar.CKind == OMPC_private)<br>
@@ -794,14 +814,18 @@ static void ReportOriginalDSA(Sema &Sema<br>
Reason = PDSA_GlobalVarShared;<br>
else if (VD->getType().isConstant(SemaRef.getASTContext()))<br>
Reason = PDSA_ConstVarShared;<br>
- else {<br>
+ else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {<br>
ReportHint = true;<br>
Reason = PDSA_LocalVarPrivate;<br>
}<br>
-<br>
- SemaRef.Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)<br>
- << Reason << ReportHint<br>
- << getOpenMPDirectiveName(Stack->getCurrentDirective());<br>
+ if (Reason != PDSA_Implicit) {<br>
+ SemaRef.Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)<br>
+ << Reason << ReportHint<br>
+ << getOpenMPDirectiveName(Stack->getCurrentDirective());<br>
+ } else if (DVar.ImplicitDSALoc.isValid()) {<br>
+ SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)<br>
+ << getOpenMPClauseName(DVar.CKind);<br>
+ }<br>
}<br>
<br>
namespace {<br>
@@ -882,8 +906,7 @@ public:<br>
};<br>
} // namespace<br>
<br>
-void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,<br>
- Scope *CurScope) {<br>
+void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {<br>
switch (DKind) {<br>
case OMPD_parallel: {<br>
QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);<br>
@@ -893,42 +916,48 @@ void Sema::ActOnOpenMPRegionStart(OpenMP<br>
std::make_pair(".bound_tid.", KmpInt32PtrTy),<br>
std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
};<br>
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+ Params);<br>
break;<br>
}<br>
case OMPD_simd: {<br>
Sema::CapturedParamNameType Params[] = {<br>
std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
};<br>
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+ Params);<br>
break;<br>
}<br>
case OMPD_for: {<br>
Sema::CapturedParamNameType Params[] = {<br>
std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
};<br>
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+ Params);<br>
break;<br>
}<br>
case OMPD_sections: {<br>
Sema::CapturedParamNameType Params[] = {<br>
std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
};<br>
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+ Params);<br>
break;<br>
}<br>
case OMPD_section: {<br>
Sema::CapturedParamNameType Params[] = {<br>
std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
};<br>
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+ Params);<br>
break;<br>
}<br>
case OMPD_single: {<br>
Sema::CapturedParamNameType Params[] = {<br>
std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
};<br>
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,<br>
+ Params);<br>
break;<br>
}<br>
case OMPD_threadprivate:<br>
@@ -1695,6 +1724,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
case OMPC_ordered:<br>
case OMPC_nowait:<br>
case OMPC_threadprivate:<br>
@@ -1874,6 +1904,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
case OMPC_ordered:<br>
case OMPC_nowait:<br>
case OMPC_threadprivate:<br>
@@ -1914,10 +1945,10 @@ OMPClause *Sema::ActOnOpenMPDefaultClaus<br>
}<br>
switch (Kind) {<br>
case OMPC_DEFAULT_none:<br>
- DSAStack->setDefaultDSANone();<br>
+ DSAStack->setDefaultDSANone(KindKwLoc);<br>
break;<br>
case OMPC_DEFAULT_shared:<br>
- DSAStack->setDefaultDSAShared();<br>
+ DSAStack->setDefaultDSAShared(KindKwLoc);<br>
break;<br>
case OMPC_DEFAULT_unknown:<br>
llvm_unreachable("Clause kind is not allowed.");<br>
@@ -1984,6 +2015,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
case OMPC_ordered:<br>
case OMPC_nowait:<br>
case OMPC_threadprivate:<br>
@@ -2073,6 +2105,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM<br>
case OMPC_linear:<br>
case OMPC_aligned:<br>
case OMPC_copyin:<br>
+ case OMPC_copyprivate:<br>
case OMPC_default:<br>
case OMPC_proc_bind:<br>
case OMPC_threadprivate:<br>
@@ -2126,6 +2159,9 @@ OMPClause *Sema::ActOnOpenMPVarListClaus<br>
case OMPC_copyin:<br>
Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);<br>
break;<br>
+ case OMPC_copyprivate:<br>
+ Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);<br>
+ break;<br>
case OMPC_if:<br>
case OMPC_num_threads:<br>
case OMPC_safelen:<br>
@@ -3281,4 +3317,108 @@ OMPClause *Sema::ActOnOpenMPCopyinClause<br>
return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);<br>
}<br>
<br>
+OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,<br>
+ SourceLocation StartLoc,<br>
+ SourceLocation LParenLoc,<br>
+ SourceLocation EndLoc) {<br>
+ SmallVector<Expr *, 8> Vars;<br>
+ for (auto &RefExpr : VarList) {<br>
+ assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");<br>
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {<br>
+ // It will be analyzed later.<br>
+ Vars.push_back(RefExpr);<br>
+ continue;<br>
+ }<br>
+<br>
+ SourceLocation ELoc = RefExpr->getExprLoc();<br>
+ // OpenMP [2.1, C/C++]<br>
+ // A list item is a variable name.<br>
+ // OpenMP [2.14.4.1, Restrictions, p.1]<br>
+ // A list item that appears in a copyin clause must be threadprivate.<br>
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);<br>
+ if (!DE || !isa<VarDecl>(DE->getDecl())) {<br>
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();<br>
+ continue;<br>
+ }<br>
+<br>
+ Decl *D = DE->getDecl();<br>
+ VarDecl *VD = cast<VarDecl>(D);<br>
+<br>
+ QualType Type = VD->getType();<br>
+ if (Type->isDependentType() || Type->isInstantiationDependentType()) {<br>
+ // It will be analyzed later.<br>
+ Vars.push_back(DE);<br>
+ continue;<br>
+ }<br>
+<br>
+ // OpenMP [2.14.4.2, Restrictions, p.2]<br>
+ // A list item that appears in a copyprivate clause may not appear in a<br>
+ // private or firstprivate clause on the single construct.<br>
+ if (!DSAStack->isThreadPrivate(VD)) {<br>
+ auto DVar = DSAStack->getTopDSA(VD);<br>
+ if (DVar.CKind != OMPC_copyprivate && DVar.CKind != OMPC_unknown &&<br>
+ !(DVar.CKind == OMPC_private && !DVar.RefExpr)) {<br>
+ Diag(ELoc, diag::err_omp_wrong_dsa)<br>
+ << getOpenMPClauseName(DVar.CKind)<br>
+ << getOpenMPClauseName(OMPC_copyprivate);<br>
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);<br>
+ continue;<br>
+ }<br>
+<br>
+ // OpenMP [2.11.4.2, Restrictions, p.1]<br>
+ // All list items that appear in a copyprivate clause must be either<br>
+ // threadprivate or private in the enclosing context.<br>
+ if (DVar.CKind == OMPC_unknown) {<br>
+ DVar = DSAStack->getImplicitDSA(VD);<br>
+ if (DVar.CKind == OMPC_shared) {<br>
+ Diag(ELoc, diag::err_omp_required_access)<br>
+ << getOpenMPClauseName(OMPC_copyprivate)<br>
+ << "threadprivate or private in the enclosing context";<br>
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);<br>
+ continue;<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]<br>
+ // A variable of class type (or array thereof) that appears in a<br>
+ // copyin clause requires an accessible, unambiguous copy assignment<br>
+ // operator for the class type.<br>
+ Type = Context.getBaseElementType(Type);<br>
+ CXXRecordDecl *RD =<br>
+ getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;<br>
+ // FIXME This code must be replaced by actual assignment of the<br>
+ // threadprivate variable.<br>
+ if (RD) {<br>
+ CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);<br>
+ DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());<br>
+ if (MD) {<br>
+ if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||<br>
+ MD->isDeleted()) {<br>
+ Diag(ELoc, diag::err_omp_required_method)<br>
+ << getOpenMPClauseName(OMPC_copyprivate) << 2;<br>
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==<br>
+ VarDecl::DeclarationOnly;<br>
+ Diag(VD->getLocation(),<br>
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)<br>
+ << VD;<br>
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;<br>
+ continue;<br>
+ }<br>
+ MarkFunctionReferenced(ELoc, MD);<br>
+ DiagnoseUseOfDecl(MD, ELoc);<br>
+ }<br>
+ }<br>
+<br>
+ // No need to mark vars as copyprivate, they are already threadprivate or<br>
+ // implicitly private.<br>
+ Vars.push_back(DE);<br>
+ }<br>
+<br>
+ if (Vars.empty())<br>
+ return nullptr;<br>
+<br>
+ return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jun 27 05:37:06 2014<br>
@@ -1494,6 +1494,18 @@ public:<br>
EndLoc);<br>
}<br>
<br>
+ /// \brief Build a new OpenMP 'copyprivate' 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 *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,<br>
+ SourceLocation StartLoc,<br>
+ SourceLocation LParenLoc,<br>
+ SourceLocation EndLoc) {<br>
+ return getSema().ActOnOpenMPCopyprivateClause(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>
@@ -6403,7 +6415,8 @@ template <typename Derived><br>
StmtResult<br>
TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {<br>
DeclarationNameInfo DirName;<br>
- getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr);<br>
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,<br>
+ D->getLocStart());<br>
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
return Res;<br>
@@ -6413,7 +6426,8 @@ template <typename Derived><br>
StmtResult<br>
TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {<br>
DeclarationNameInfo DirName;<br>
- getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr);<br>
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,<br>
+ D->getLocStart());<br>
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
return Res;<br>
@@ -6423,7 +6437,8 @@ template <typename Derived><br>
StmtResult<br>
TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {<br>
DeclarationNameInfo DirName;<br>
- getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr);<br>
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,<br>
+ D->getLocStart());<br>
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
return Res;<br>
@@ -6433,7 +6448,8 @@ template <typename Derived><br>
StmtResult<br>
TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {<br>
DeclarationNameInfo DirName;<br>
- getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr);<br>
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,<br>
+ D->getLocStart());<br>
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
return Res;<br>
@@ -6443,7 +6459,8 @@ template <typename Derived><br>
StmtResult<br>
TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {<br>
DeclarationNameInfo DirName;<br>
- getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr);<br>
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,<br>
+ D->getLocStart());<br>
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
return Res;<br>
@@ -6453,7 +6470,8 @@ template <typename Derived><br>
StmtResult<br>
TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {<br>
DeclarationNameInfo DirName;<br>
- getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr);<br>
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,<br>
+ D->getLocStart());<br>
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
return Res;<br>
@@ -6680,6 +6698,21 @@ TreeTransform<Derived>::TransformOMPCopy<br>
C->getLParenLoc(), C->getLocEnd());<br>
}<br>
<br>
+template <typename Derived><br>
+OMPClause *<br>
+TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *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().RebuildOMPCopyprivateClause(<br>
+ Vars, C->getLocStart(), 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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Fri Jun 27 05:37:06 2014<br>
@@ -1724,6 +1724,9 @@ OMPClause *OMPClauseReader::readClause()<br>
case OMPC_copyin:<br>
C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);<br>
break;<br>
+ case OMPC_copyprivate:<br>
+ C = OMPCopyprivateClause::CreateEmpty(Context, Record[Idx++]);<br>
+ break;<br>
}<br>
Visit(C);<br>
C->setLocStart(Reader->ReadSourceLocation(Record, Idx));<br>
@@ -1865,6 +1868,16 @@ void OMPClauseReader::VisitOMPCopyinClau<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>
+void OMPClauseReader::VisitOMPCopyprivateClause(OMPCopyprivateClause *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>
<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Fri Jun 27 05:37:06 2014<br>
@@ -1782,6 +1782,13 @@ void OMPClauseWriter::VisitOMPCopyinClau<br>
Writer->Writer.AddStmt(VE);<br>
}<br>
<br>
+void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *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>
<br>
Modified: cfe/trunk/test/OpenMP/single_ast_print.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/single_ast_print.cpp?rev=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/single_ast_print.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/single_ast_print.cpp (original)<br>
+++ cfe/trunk/test/OpenMP/single_ast_print.cpp Fri Jun 27 05:37:06 2014<br>
@@ -13,11 +13,11 @@ T tmain(T argc) {<br>
T b = argc, c, d, e, f, g;<br>
static T a;<br>
// CHECK: static T a;<br>
-#pragma omp parallel<br>
-#pragma omp single private(argc, b), firstprivate(c, d), nowait<br>
+#pragma omp parallel private(g)<br>
+#pragma omp single private(argc, b), firstprivate(c, d), nowait copyprivate(g)<br>
foo();<br>
- // CHECK-NEXT: #pragma omp parallel<br>
- // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait<br>
+ // CHECK-NEXT: #pragma omp parallel private(g)<br>
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait copyprivate(g)<br>
// CHECK-NEXT: foo();<br>
return T();<br>
}<br>
@@ -26,11 +26,11 @@ int main(int argc, char **argv) {<br>
int b = argc, c, d, e, f, g;<br>
static int a;<br>
// CHECK: static int a;<br>
-#pragma omp parallel<br>
-#pragma omp single private(argc, b), firstprivate(argv, c), nowait<br>
+#pragma omp parallel private(g)<br>
+#pragma omp single private(argc, b), firstprivate(argv, c), nowait copyprivate(g)<br>
foo();<br>
- // CHECK-NEXT: #pragma omp parallel<br>
- // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait<br>
+ // CHECK-NEXT: #pragma omp parallel private(g)<br>
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait copyprivate(g)<br>
// CHECK-NEXT: foo();<br>
return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));<br>
}<br>
<br>
Added: cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp?rev=211886&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp?rev=211886&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp (added)<br>
+++ cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp Fri Jun 27 05:37:06 2014<br>
@@ -0,0 +1,157 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s<br>
+<br>
+void foo() {<br>
+}<br>
+<br>
+struct S1; // expected-note 2 {{declared here}}<br>
+class S2 {<br>
+ mutable int a;<br>
+<br>
+public:<br>
+ S2() : a(0) {}<br>
+ S2 &operator=(S2 &s2) { return *this; }<br>
+};<br>
+class S3 {<br>
+ int a;<br>
+<br>
+public:<br>
+ S3() : a(0) {}<br>
+ S3 &operator=(S3 &s3) { return *this; }<br>
+};<br>
+class S4 { // expected-note 2 {{'S4' declared here}}<br>
+ int a;<br>
+ S4();<br>
+ S4 &operator=(const S4 &s4);<br>
+<br>
+public:<br>
+ S4(int v) : a(v) {}<br>
+};<br>
+class S5 { // expected-note 2 {{'S5' declared here}}<br>
+ int a;<br>
+ S5() : a(0) {}<br>
+ S5 &operator=(const S5 &s5) { return *this; }<br>
+<br>
+public:<br>
+ S5(int v) : a(v) {}<br>
+};<br>
+<br>
+S2 k;<br>
+S3 h;<br>
+S4 l(3); // expected-note 2 {{'l' defined here}}<br>
+S5 m(4); // expected-note 2 {{'m' defined here}}<br>
+#pragma omp threadprivate(h, k, l, m)<br>
+<br>
+template <class T, class C><br>
+T tmain(T argc, C **argv) {<br>
+ T i;<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate // expected-error {{expected '(' after 'copyprivate'}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate() // expected-error {{expected expression}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(k // expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(l) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(argv[1]) // expected-error {{expected variable name}}<br>
+#pragma omp parallel // expected-note {{implicitly determined as shared}}<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(m) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}<br>
+ foo();<br>
+#pragma omp parallel private(i)<br>
+ {<br>
+#pragma omp single copyprivate(i)<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel shared(i) // expected-note {{defined as shared}}<br>
+ {<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel private(i)<br>
+#pragma omp parallel default(shared) // expected-note {{implicitly determined as shared}}<br>
+ {<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel private(i)<br>
+#pragma omp parallel // expected-note {{implicitly determined as shared}}<br>
+ {<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel<br>
+#pragma omp single private(i) copyprivate(i) // expected-error {{private variable cannot be copyprivate}} expected-note {{defined as private}}<br>
+ foo();<br>
+#pragma omp parallel<br>
+#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}<br>
+ foo();<br>
+<br>
+ return T();<br>
+}<br>
+<br>
+int main(int argc, char **argv) {<br>
+ int i;<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate // expected-error {{expected '(' after 'copyprivate'}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate() // expected-error {{expected expression}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(k // expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(l) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(argv[1]) // expected-error {{expected variable name}}<br>
+#pragma omp parallel // expected-note {{implicitly determined as shared}}<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+#pragma omp parallel<br>
+#pragma omp single copyprivate(m) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}<br>
+ foo();<br>
+#pragma omp parallel private(i)<br>
+ {<br>
+#pragma omp single copyprivate(i)<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel shared(i) // expected-note {{defined as shared}}<br>
+ {<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel private(i)<br>
+#pragma omp parallel default(shared) // expected-note {{implicitly determined as shared}}<br>
+ {<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel private(i)<br>
+#pragma omp parallel // expected-note {{implicitly determined as shared}}<br>
+ {<br>
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}<br>
+ foo();<br>
+ }<br>
+#pragma omp parallel<br>
+#pragma omp single private(i) copyprivate(i) // expected-error {{private variable cannot be copyprivate}} expected-note {{defined as private}}<br>
+ foo();<br>
+#pragma omp parallel<br>
+#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}<br>
+ foo();<br>
+<br>
+ return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}}<br>
+}<br>
<br>
Propchange: cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp<br>
------------------------------------------------------------------------------<br>
svn:eol-style = native<br>
<br>
Propchange: cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp<br>
------------------------------------------------------------------------------<br>
svn:keywords = Author Date Id Rev URL<br>
<br>
Propchange: cfe/trunk/test/OpenMP/single_copyprivate_messages.cpp<br>
------------------------------------------------------------------------------<br>
svn:mime-type = text/plain<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=211886&r1=211885&r2=211886&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=211886&r1=211885&r2=211886&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Jun 27 05:37:06 2014<br>
@@ -1989,6 +1989,10 @@ void OMPClauseEnqueue::VisitOMPAlignedCl<br>
void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {<br>
VisitOMPClauseList(C);<br>
}<br>
+void<br>
+OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {<br>
+ VisitOMPClauseList(C);<br>
+}<br>
}<br>
<br>
void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {<br>
<br>
<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>
</blockquote></div><br></div>