diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-06-27 10:37:06 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-06-27 10:37:06 +0000 |
commit | 3b54d86f4f0bedfffb6305b6f12283f9c62682db (patch) | |
tree | 04730260ddc52d65d4452d6e651786058fd92015 /lib | |
parent | 11a33cee19725d88b474912665c72835db03a87f (diff) | |
download | clang-3b54d86f4f0bedfffb6305b6f12283f9c62682db.tar.gz clang-3b54d86f4f0bedfffb6305b6f12283f9c62682db.tar.bz2 clang-3b54d86f4f0bedfffb6305b6f12283f9c62682db.tar.xz |
[OPENMP] Parsing and sema analysis for 'copyprivate' clause.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211886 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Stmt.cpp | 22 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 8 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 4 | ||||
-rw-r--r-- | lib/Basic/OpenMPKinds.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 196 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 45 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 13 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 7 |
9 files changed, 270 insertions, 39 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 5245944e85..102d14b475 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -1280,6 +1280,28 @@ OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, 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"); diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 4a46063df3..28ce174207 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -748,6 +748,14 @@ void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) { } } +void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) { + if (!Node->varlist_empty()) { + OS << "copyprivate"; + VisitOMPClauseList(Node, '('); + OS << ")"; + } +} + } //===----------------------------------------------------------------------===// diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index f3f3c7ba8e..f562ed6aa7 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -335,6 +335,10 @@ void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) { void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) { VisitOMPClauseList(C); } +void +OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) { + VisitOMPClauseList(C); +} } void diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index 623af2df60..07121215e7 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -95,6 +95,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, 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::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, 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(OpenMPDirectiveKind DKind, 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(OpenMPDirectiveKind DKind, 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" diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 102cab36e9..b35082e6c4 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -131,7 +131,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() { 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::ParseOpenMPDeclarativeOrExecutableDirective() { { // 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(OpenMPDirectiveKind Kind, /// 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(OpenMPDirectiveKind DKind, case OMPC_linear: case OMPC_aligned: case OMPC_copyin: + case OMPC_copyprivate: Clause = ParseOpenMPVarListClause(CKind); break; case OMPC_unknown: diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 7f3560fc01..6ff617fc17 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -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::getDSA(StackTy::reverse_iterator Iter, 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::getDSA(StackTy::reverse_iterator Iter, // 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::DestroyDataSharingAttributesStack() { delete DSAStack; } 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 &SemaRef, DSAStackTy *Stack, 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 &SemaRef, DSAStackTy *Stack, 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(OpenMPDirectiveKind DKind, SourceLocation Loc, 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::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 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::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, } 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::ActOnOpenMPSingleExprWithArgClause( 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(OpenMPClauseKind Kind, 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::ActOnOpenMPVarListClause( 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(ArrayRef<Expr *> VarList, 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 diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 974f5e061b..175c4e6502 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -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>::TransformOMPCopyinClause(OMPCopyinClause *C) { 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 //===----------------------------------------------------------------------===// diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index ea8d0f3ac9..c94c43578f 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -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)); @@ -1871,6 +1874,16 @@ void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) { 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()); + C->setVarRefs(Vars); +} + //===----------------------------------------------------------------------===// // OpenMP Directives. //===----------------------------------------------------------------------===// diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 1292ec8aa8..8655bc67ed 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1782,6 +1782,13 @@ void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) { 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. //===----------------------------------------------------------------------===// |