summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaOpenMP.cpp')
-rw-r--r--lib/Sema/SemaOpenMP.cpp51
1 files changed, 36 insertions, 15 deletions
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index b34bb3388d71..0880b2d79060 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1290,9 +1290,14 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) {
}
if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
- IsByRef = !DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
- Level, /*NotLastprivate=*/true);
+ IsByRef =
+ !DSAStack->hasExplicitDSA(
+ D,
+ [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
+ Level, /*NotLastprivate=*/true) &&
+ // If the variable is artificial and must be captured by value - try to
+ // capture by value.
+ !(isa<OMPCapturedExprDecl>(D) && D->hasAttr<OMPCaptureKindAttr>());
}
// When passing data by copy, we need to make sure it fits the uintptr size
@@ -2321,10 +2326,11 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
ASTContext &C = S.getASTContext();
Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
QualType Ty = Init->getType();
+ Attr *OMPCaptureKind = nullptr;
if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
- if (S.getLangOpts().CPlusPlus)
+ if (S.getLangOpts().CPlusPlus) {
Ty = C.getLValueReferenceType(Ty);
- else {
+ } else {
Ty = C.getPointerType(Ty);
ExprResult Res =
S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
@@ -2333,11 +2339,16 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
Init = Res.get();
}
WithInit = true;
+ } else if (AsExpression) {
+ // This variable must be captured by value.
+ OMPCaptureKind = OMPCaptureKindAttr::CreateImplicit(C, OMPC_unknown);
}
auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
CaptureExpr->getLocStart());
if (!WithInit)
CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
+ if (OMPCaptureKind)
+ CED->addAttr(OMPCaptureKind);
S.CurContext->addHiddenDecl(CED);
S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
return CED;
@@ -2346,31 +2357,34 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
bool WithInit) {
OMPCapturedExprDecl *CD;
- if (auto *VD = S.IsOpenMPCapturedDecl(D))
+ if (auto *VD = S.IsOpenMPCapturedDecl(D)) {
CD = cast<OMPCapturedExprDecl>(VD);
- else
+ } else {
CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
/*AsExpression=*/false);
+ }
return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
CaptureExpr->getExprLoc());
}
static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
+ CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
if (!Ref) {
- auto *CD =
- buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
- CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true);
+ OMPCapturedExprDecl *CD = buildCaptureDecl(
+ S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
+ /*WithInit=*/true, /*AsExpression=*/true);
Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
CaptureExpr->getExprLoc());
}
ExprResult Res = Ref;
if (!S.getLangOpts().CPlusPlus &&
CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
- Ref->getType()->isPointerType())
+ Ref->getType()->isPointerType()) {
Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
- if (!Res.isUsable())
- return ExprError();
- return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
+ if (!Res.isUsable())
+ return ExprError();
+ }
+ return S.DefaultLvalueConversion(Res.get());
}
namespace {
@@ -8117,12 +8131,13 @@ OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
if (Val.isInvalid())
return nullptr;
- ValExpr = MakeFullExpr(Val.get()).get();
+ ValExpr = Val.get();
OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
CaptureRegion =
getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);
@@ -8239,6 +8254,7 @@ OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
OpenMPDirectiveKind CaptureRegion =
getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);
@@ -8666,6 +8682,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClause(
DSAStack->getCurrentDirective(), OMPC_schedule) !=
OMPD_unknown &&
!CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);
@@ -11355,6 +11372,7 @@ OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
OpenMPDirectiveKind CaptureRegion =
getOpenMPCaptureRegionForClause(DKind, OMPC_device);
if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);
@@ -12378,6 +12396,7 @@ OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
OpenMPDirectiveKind CaptureRegion =
getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);
@@ -12404,6 +12423,7 @@ OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
OpenMPDirectiveKind CaptureRegion =
getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);
@@ -12514,6 +12534,7 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause(
DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
OMPD_unknown &&
!CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
llvm::MapVector<Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
HelperValStmt = buildPreInits(Context, Captures);