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