[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. llvm-svn: 261820
This commit is contained in:
parent
17edbdd04c
commit
b7a34b608f
|
@ -1739,16 +1739,19 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
|
|||
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::ActOnOpenMPScheduleClause(
|
|||
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::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
|
|||
|
||||
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::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
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::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
|||
|
||||
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(ArrayRef<Expr *> VarList,
|
|||
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;
|
||||
}
|
||||
ValueDecl *D = Res.first;
|
||||
if (!D)
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
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(ArrayRef<Expr *> VarList,
|
|||
// 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::ActOnOpenMPDistScheduleClause(
|
|||
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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue