Author: abataev Date: Wed Feb 24 21:59:29 2016 New Revision: 261820 URL: http://llvm.org/viewvc/llvm-project?rev=261820&view=rev Log: [OPENMP 4.5] Support fielddecls in 'shared' clause.
OpenMP 4.5 allows to use non-static data members of current class in non-static member functions in different kind of clauses. Patch adds support for data members in 'shared' clause. Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/test/OpenMP/parallel_ast_print.cpp Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=261820&r1=261819&r2=261820&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Feb 24 21:59:29 2016 @@ -1739,16 +1739,19 @@ static OMPCapturedExprDecl *buildCapture return CED; } -static DeclRefExpr *buildCapture(Sema &S, IdentifierInfo *Id, - Expr *CaptureExpr) { - auto *CD = buildCaptureDecl(S, Id, CaptureExpr); +static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr) { + OMPCapturedExprDecl *CD; + if (auto *VD = S.IsOpenMPCapturedDecl(D)) + CD = cast<OMPCapturedExprDecl>(VD); + else + CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr); return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), SourceLocation()); } -static DeclRefExpr *buildCapture(Sema &S, StringRef Name, Expr *CaptureExpr) { - auto *CD = - buildCaptureDecl(S, &S.getASTContext().Idents.get(Name), CaptureExpr); +static DeclRefExpr *buildCapture(Sema &S, Expr *CaptureExpr) { + auto *CD = buildCaptureDecl( + S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr); return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), SourceLocation()); } @@ -6841,7 +6844,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClau return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - ValExpr = buildCapture(*this, ".chunk.", ValExpr); + ValExpr = buildCapture(*this, ValExpr); Decl *D = cast<DeclRefExpr>(ValExpr)->getDecl(); HelperValStmt = new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, @@ -7205,7 +7208,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus DeclRefExpr *Ref = nullptr; if (!VD) - Ref = buildCapture(*this, D->getIdentifier(), RefExpr); + Ref = buildCapture(*this, D, RefExpr); DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); PrivateCopies.push_back(VDPrivateRefExpr); @@ -7482,7 +7485,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivate RefExpr->getExprLoc()); DeclRefExpr *Ref = nullptr; if (!VD) { - Ref = buildCapture(*this, D->getIdentifier(), RefExpr); + Ref = buildCapture(*this, D, RefExpr); ExprCaptures.push_back(Ref->getDecl()); } DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); @@ -7618,7 +7621,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateC DeclRefExpr *Ref = nullptr; if (!VD) - Ref = buildCapture(*this, D->getIdentifier(), RefExpr); + Ref = buildCapture(*this, D, RefExpr); if (TopDVar.CKind != OMPC_firstprivate) DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); @@ -7640,36 +7643,18 @@ OMPClause *Sema::ActOnOpenMPSharedClause SourceLocation EndLoc) { SmallVector<Expr *, 8> Vars; for (auto &RefExpr : VarList) { - assert(RefExpr && "NULL expr in OpenMP shared clause."); - if (isa<DependentScopeDeclRefExpr>(RefExpr)) { + assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); + auto Res = getPrivateItem(*this, RefExpr); + if (Res.second) { // 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.3.2, Restrictions, p.1] - // A variable that is part of another variable (as an array or structure - // element) cannot appear in a shared unless it is a static data member - // of a C++ class. - DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); - if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name_member_expr) - << 0 << 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); + ValueDecl *D = Res.first; + if (!D) continue; - } + SourceLocation ELoc = RefExpr->getExprLoc(); + auto *VD = dyn_cast<VarDecl>(D); // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct] // Variables with the predetermined data-sharing attributes may not be @@ -7677,17 +7662,20 @@ OMPClause *Sema::ActOnOpenMPSharedClause // listed below. For these exceptions only, listing a predetermined // variable in a data-sharing attribute clause is allowed and overrides // the variable's predetermined data-sharing attributes. - DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); + DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && DVar.RefExpr) { Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPClauseName(OMPC_shared); - ReportOriginalDSA(*this, DSAStack, VD, DVar); + ReportOriginalDSA(*this, DSAStack, D, DVar); continue; } - DSAStack->addDSA(VD, DE, OMPC_shared); - Vars.push_back(DE); + DeclRefExpr *Ref = nullptr; + if (!VD) + Ref = buildCapture(*this, D, RefExpr); + DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); + Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); } if (Vars.empty()) @@ -9627,7 +9615,7 @@ OMPClause *Sema::ActOnOpenMPDistSchedule return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - ValExpr = buildCapture(*this, ".chunk.", ValExpr); + ValExpr = buildCapture(*this, ValExpr); Decl *D = cast<DeclRefExpr>(ValExpr)->getDecl(); HelperValStmt = new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, Modified: cfe/trunk/test/OpenMP/parallel_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_ast_print.cpp?rev=261820&r1=261819&r2=261820&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_ast_print.cpp Wed Feb 24 21:59:29 2016 @@ -29,6 +29,9 @@ public: #pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(T::a) for (int k = 0; k < a.a; ++k) ++this->a.a; +#pragma omp parallel shared(a) shared(this->a) shared(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; } S7 &operator=(S7 &s) { #pragma omp parallel private(a) private(this->a) @@ -37,26 +40,35 @@ public: #pragma omp parallel firstprivate(a) firstprivate(this->a) for (int k = 0; k < s.a.a; ++k) ++s.a.a; +#pragma omp parallel shared(a) shared(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; return *this; } }; // CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S1::a) // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S1::a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S1::a) // CHECK: #pragma omp parallel private(this->a) private(this->a) private(T::a) // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(T::a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(T::a) // CHECK: #pragma omp parallel private(this->a) private(this->a) // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) class S8 : public S7<S1> { S8() {} public: S8(int v) : S7<S1>(v){ -#pragma omp parallel private(a) private(this->a) private(S7<S1>::a) +#pragma omp parallel private(a) private(this->a) private(S7 < S1 > ::a) for (int k = 0; k < a.a; ++k) ++this->a.a; -#pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(S7<S1>::a) +#pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(S7 < S1 > ::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel shared(a) shared(this->a) shared(S7 < S1 > ::a) for (int k = 0; k < a.a; ++k) ++this->a.a; } @@ -67,14 +79,19 @@ public: #pragma omp parallel firstprivate(a) firstprivate(this->a) for (int k = 0; k < s.a.a; ++k) ++s.a.a; +#pragma omp parallel shared(a) shared(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; return *this; } }; // CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S7<S1>::a) // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S7<S1>::a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S7<S1>::a) // CHECK: #pragma omp parallel private(this->a) private(this->a) // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) template <class T> struct S { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits