diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-17 10:50:17 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-17 10:50:17 +0000 |
commit | e122da19eab39f1272dcd76b08b028a0134f9cd5 (patch) | |
tree | f40d864a901bac9ba5e814984b2830d75b9efab3 /clang/lib/Sema/SemaOpenMP.cpp | |
parent | 34223a7e5d1053c5d6c9fc7fbef363b5d9f2f8d8 (diff) | |
download | bcm5719-llvm-e122da19eab39f1272dcd76b08b028a0134f9cd5.tar.gz bcm5719-llvm-e122da19eab39f1272dcd76b08b028a0134f9cd5.zip |
[OPENMP 4.5] Allow to use private data members in 'copyprivate' clause.
OpenMP 4.5 allows privatization of non-static data members in non-static
member functions. This patch adds support of private data members in
'copyprivate' clauses.
llvm-svn: 263706
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 74 |
1 files changed, 31 insertions, 43 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 56ab8ae3da9..826f0690935 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -8929,52 +8929,37 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, SmallVector<Expr *, 8> DstExprs; SmallVector<Expr *, 8> AssignmentOps; for (auto &RefExpr : VarList) { - assert(RefExpr && "NULL expr in OpenMP copyprivate clause."); - if (isa<DependentScopeDeclRefExpr>(RefExpr)) { + assert(RefExpr && "NULL expr in OpenMP linear clause."); + SourceLocation ELoc; + SourceRange ERange; + Expr *SimpleRefExpr = RefExpr; + auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, + /*AllowArraySection=*/false); + if (Res.second) { // It will be analyzed later. Vars.push_back(RefExpr); SrcExprs.push_back(nullptr); DstExprs.push_back(nullptr); AssignmentOps.push_back(nullptr); - 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_member_expr) - << 0 << RefExpr->getSourceRange(); + ValueDecl *D = Res.first; + if (!D) 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); - SrcExprs.push_back(nullptr); - DstExprs.push_back(nullptr); - AssignmentOps.push_back(nullptr); - continue; - } + QualType Type = D->getType(); + auto *VD = dyn_cast<VarDecl>(D); // 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, false); + if (!VD || !DSAStack->isThreadPrivate(VD)) { + auto DVar = DSAStack->getTopDSA(D, false); if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && DVar.RefExpr) { Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPClauseName(OMPC_copyprivate); - ReportOriginalDSA(*this, DSAStack, VD, DVar); + ReportOriginalDSA(*this, DSAStack, D, DVar); continue; } @@ -8982,12 +8967,12 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, // 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, false); + DVar = DSAStack->getImplicitDSA(D, false); 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); + ReportOriginalDSA(*this, DSAStack, D, DVar); continue; } } @@ -8999,10 +8984,11 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, << getOpenMPClauseName(OMPC_copyprivate) << Type << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); bool IsDecl = + !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), + Diag(D->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + << D; continue; } @@ -9013,27 +8999,29 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, Type = Context.getBaseElementType(Type.getNonReferenceType()) .getUnqualifiedType(); auto *SrcVD = - buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src", - VD->hasAttrs() ? &VD->getAttrs() : nullptr); - auto *PseudoSrcExpr = - buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc()); + buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", + D->hasAttrs() ? &D->getAttrs() : nullptr); + auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); auto *DstVD = - buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst", - VD->hasAttrs() ? &VD->getAttrs() : nullptr); + buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", + D->hasAttrs() ? &D->getAttrs() : nullptr); auto *PseudoDstExpr = - buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); - auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, + buildDeclRefExpr(*this, DstVD, Type, ELoc); + auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); if (AssignmentOp.isInvalid()) continue; - AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), + AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; // No need to mark vars as copyprivate, they are already threadprivate or // implicitly private. - Vars.push_back(DE); + assert(VD || IsOpenMPCapturedDecl(D)); + Vars.push_back( + VD ? RefExpr->IgnoreParens() + : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); SrcExprs.push_back(PseudoSrcExpr); DstExprs.push_back(PseudoDstExpr); AssignmentOps.push_back(AssignmentOp.get()); |