ABataev added a comment. Samuel, this will be captured. But foo() will use original A. This cannot be changed. But Inside the region all reference to this->A will be replaced by the CapturedDecl A. It will allow proper codegen for inner captured contexts. For example, such code won't be handled correctly without my changes: #pragma omp target map(to: this->A) []()->void {++A}();
In this code you will work with original A, not the one captured in the target region. I reworked the patch a little bit, here is improved version: diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index 48a03b1..f51fadb 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -2784,6 +2784,7 @@ public: /// with the variables 'a' and 'b'. /// class OMPMapClause final : public OMPVarListClause<OMPMapClause>, + public OMPClauseWithPreInit, private llvm::TrailingObjects<OMPMapClause, Expr *> { friend TrailingObjects; friend OMPVarListClause; @@ -2838,8 +2839,9 @@ class OMPMapClause final : public OMPVarListClause<OMPMapClause>, unsigned N) : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc, N), - MapTypeModifier(MapTypeModifier), MapType(MapType), - MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {} + OMPClauseWithPreInit(this), MapTypeModifier(MapTypeModifier), + MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { + } /// \brief Build an empty clause. /// @@ -2848,8 +2850,8 @@ class OMPMapClause final : public OMPVarListClause<OMPMapClause>, explicit OMPMapClause(unsigned N) : OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), N), - MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), - MapTypeIsImplicit(false), MapLoc() {} + OMPClauseWithPreInit(this), MapTypeModifier(OMPC_MAP_unknown), + MapType(OMPC_MAP_unknown), MapTypeIsImplicit(false), MapLoc() {} public: /// \brief Creates clause with a list of variables \a VL. @@ -2862,13 +2864,15 @@ public: /// \param Type Map type. /// \param TypeIsImplicit Map type is inferred implicitly. /// \param TypeLoc Location of the map type. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. /// static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, - SourceLocation TypeLoc); + SourceLocation TypeLoc, Stmt *PreInit); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 6d86727..7835a17 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2816,6 +2816,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) { template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) { TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPreInit(C)); return true; } diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp index 8843ded..8cc6b86 100644 --- a/lib/AST/OpenMPClause.cpp +++ b/lib/AST/OpenMPClause.cpp @@ -48,6 +48,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { return static_cast<const OMPReductionClause *>(C); case OMPC_linear: return static_cast<const OMPLinearClause *>(C); + case OMPC_map: + return static_cast<const OMPMapClause *>(C); case OMPC_default: case OMPC_proc_bind: case OMPC_if: @@ -76,7 +78,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_device: case OMPC_threads: case OMPC_simd: - case OMPC_map: case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: @@ -533,8 +534,8 @@ OMPMapClause *OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, - bool TypeIsImplicit, - SourceLocation TypeLoc) { + bool TypeIsImplicit, SourceLocation TypeLoc, + Stmt *PreInit) { void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); OMPMapClause *Clause = new (Mem) OMPMapClause(TypeModifier, Type, TypeIsImplicit, TypeLoc, @@ -543,6 +544,7 @@ OMPMapClause *OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, Clause->setMapTypeModifier(TypeModifier); Clause->setMapType(Type); Clause->setMapLoc(TypeLoc); + Clause->setPreInitStmt(PreInit); return Clause; } diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 327b4c0..68fb535 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -471,6 +471,7 @@ void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) { } void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) { VisitOMPClauseList(C); + VistOMPClauseWithPreInit(C); } void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) { Profiler->VisitStmt(C->getNumTeams()); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 826f069..7d3e3cf 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -9776,16 +9776,11 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { SmallVector<Expr *, 4> Vars; + SmallVector<Decl *, 4> ExprCaptures; for (auto &RE : VarList) { assert(RE && "Null expr in omp map"); - if (isa<DependentScopeDeclRefExpr>(RE)) { - // It will be analyzed later. - Vars.push_back(RE); - continue; - } SourceLocation ELoc = RE->getExprLoc(); - auto *VE = RE->IgnoreParenLValueCasts(); if (VE->isValueDependent() || VE->isTypeDependent() || @@ -9797,9 +9792,9 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, continue; } - auto *SimpleExpr = RE->IgnoreParenCasts(); + auto *SimpleExpr = VE->IgnoreParenCasts(); - if (!RE->IgnoreParenImpCasts()->isLValue()) { + if (!VE->isLValue()) { Diag(ELoc, diag::err_omp_expected_named_var_member_or_array_expression) << RE->getSourceRange(); continue; @@ -9897,15 +9892,43 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, continue; } - Vars.push_back(RE); - DSAStack->addExprToVarMapInfo(D, RE); + Expr *VarsExpr = RE->IgnoreParens(); + if (!VD) { + DeclRefExpr *Ref; + if (BE != SimpleExpr) { + TransformExprToCaptures RebuildToCapture(*this, D); + VarsExpr = + RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); + Ref = RebuildToCapture.getCapturedExpr(); + } else { + VarsExpr = Ref = + buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); + } + if (!IsOpenMPCapturedDecl(D)) + ExprCaptures.push_back(Ref->getDecl()); + } + Vars.push_back(VarsExpr); + DSAStack->addExprToVarMapInfo(D, RE->IgnoreParens()); } + if (Vars.empty()) + return nullptr; + + Stmt *PreInit = nullptr; + if (!ExprCaptures.empty()) { + PreInit = new (Context) + DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), + ExprCaptures.size()), + SourceLocation(), SourceLocation()); + } // We need to produce a map clause even if we don't have variables so that // other diagnostics related with non-existing map clauses are accurate. return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, MapTypeModifier, MapType, IsMapTypeImplicit, - MapLoc); + MapLoc, PreInit); } QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index ab44c96..941caf7 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -2214,6 +2214,7 @@ void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) { } void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { + VisitOMPClauseWithPreInit(C); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); C->setMapTypeModifier( static_cast<OpenMPMapClauseKind>(Record[Idx++])); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index ea3b804..6d3dca3 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -2013,6 +2013,7 @@ void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) { void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->varlist_size()); + VisitOMPClauseWithPreInit(C); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); Record.push_back(C->getMapTypeModifier()); Record.push_back(C->getMapType()); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 5dca6f9..05c0380 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2247,6 +2247,7 @@ void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) { } void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) { VisitOMPClauseList(C); + VisitOMPClauseWithPreInit(C); } void OMPClauseEnqueue::VisitOMPDistScheduleClause( const OMPDistScheduleClause *C) { Best regards, Alexey Bataev ============= Software Engineer Intel Compiler Team http://reviews.llvm.org/D16749 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits