jyu2 updated this revision to Diff 441765.
jyu2 added a comment.
Thank Alexey for the review. This is remove check for omp region just use
hasDSA.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D127803/new/
https://reviews.llvm.org/D127803
Files:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/test/OpenMP/default_firstprivate_ast_print.cpp
clang/test/OpenMP/default_private_ast_print.cpp
Index: clang/test/OpenMP/default_private_ast_print.cpp
===================================================================
--- clang/test/OpenMP/default_private_ast_print.cpp
+++ clang/test/OpenMP/default_private_ast_print.cpp
@@ -96,4 +96,57 @@
// DUMP-NEXT: -DeclRefExpr {{.*}} 'a'
// DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
}
+
+void zoo(int);
+struct A {
+ int z;
+ int f;
+ A();
+ ~A();
+ void foo() {
+#pragma omp parallel private(z) default(private)
+ {
+ z++;
+ f++;
+ zoo(z + f);
+ f++;
+ }
+ }
+ // PRINT: #pragma omp parallel private(this->z) default(private)
+ // DUMP: -OMPParallelDirective
+ // DUMP-NEXT: -OMPPrivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP-NEXT: -OMPPrivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+ // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+ void bar() {
+#pragma omp parallel private(z) default(private)
+ {
+#pragma omp parallel private(z) default(private)
+ {
+ z++;
+ f++;
+ zoo(z + f);
+ f++;
+ }
+ }
+ }
+ // PRINT: #pragma omp parallel private(this->z) default(private)
+ // PRINT: #pragma omp parallel private(this->z) default(private)
+ // DUMP: -OMPParallelDirective
+ // DUMP-NEXT: -OMPPrivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP: -OMPParallelDirective
+ // DUMP-NEXT: -OMPPrivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP-NEXT: -OMPPrivateClause {{.*}} <implicit>
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+ // DUMP: -CXXThisExpr
+ // DUMP: -MemberExpr
+ // DUMP-NEXT: -CXXThisExpr
+ // DUMP: -CXXThisExpr
+};
#endif // HEADER
Index: clang/test/OpenMP/default_firstprivate_ast_print.cpp
===================================================================
--- clang/test/OpenMP/default_firstprivate_ast_print.cpp
+++ clang/test/OpenMP/default_firstprivate_ast_print.cpp
@@ -38,22 +38,31 @@
void apply() {
#pragma omp parallel default(firstprivate)
{
- targetDev++;
+ [=]() -> int {
+ return targetDev++;
+ }();
}
// PRINT: #pragma omp parallel default(firstprivate)
// PRINT-NEXT: {
- // PRINT-NEXT: this->targetDev++;
- // CHECK-NEXT: }
+ // PRINT-NEXT: [=]() -> int {
+ // PRINT-NEXT: return this->targetDev++;
+ // PRINT-NEXT: }();
+ // PRINT-NEXT: }
// DUMP: -OMPParallelDirective
- // DUMP->NEXT: -OMPDefaultClause
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP-NOT: -OMPFirstprivateClause
}
// PRINT: template<> void apply<32U>()
// PRINT: #pragma omp parallel default(firstprivate)
// PRINT-NEXT: {
- // PRINT-NEXT: this->targetDev++;
+ // PRINT-NEXT: [=]() -> int {
+ // PRINT-NEXT: return this->targetDev++;
+ // PRINT-NEXT: }();
// CHECK-NEXT: }
// DUMP: -OMPParallelDirective
// DUMP-NEXT: -OMPDefaultClause
+ // DUMP-NEXT: -OMPFirstprivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'targetDev'
};
void use_template() {
@@ -99,4 +108,60 @@
// DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
// DUMP-NEXT: -DeclRefExpr {{.*}} 'y'
}
+void zoo(int);
+struct A {
+ int z;
+ int f;
+ A();
+ ~A();
+ void foo() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+ {
+ z++;
+ f++;
+ zoo(z + f);
+ f++;
+ }
+ }
+ // PRINT: #pragma omp parallel firstprivate(this->z) default(firstprivate)
+ // DUMP: -OMPParallelDirective
+ // DUMP-NEXT: -OMPFirstprivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP-NEXT: -OMPFirstprivateClause {{.*}} <implicit>
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+ // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+ void bar() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+ {
+#pragma omp parallel private(z) default(firstprivate)
+ {
+ z++;
+ f++;
+ zoo(z + f);
+ f++;
+ }
+ }
+ }
+ // PRINT: #pragma omp parallel firstprivate(this->z) default(firstprivate)
+ // PRINT: #pragma omp parallel private(this->z) default(firstprivate)
+ // DUMP: -OMPParallelDirective
+ // DUMP-NEXT: -OMPFirstprivateClause
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP: -OMPParallelDirective
+ // DUMP-NEXT: -OMPPrivateClaus
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+ // DUMP-NEXT: -OMPDefaultClause
+ // DUMP-NEXT: -OMPFirstprivateClause {{.*}} <implicit>
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+ // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+ // DUMP: -MemberExpr {{.*}}
+ // DUMP-NEXT: -CXXThisExpr
+ // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+ // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+};
#endif // HEADER
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -11097,11 +11097,15 @@
FoundDecl == E->getFoundDecl() &&
!E->hasExplicitTemplateArgs()) {
- // Mark it referenced in the new context regardless.
- // FIXME: this is a bit instantiation-specific.
- SemaRef.MarkMemberReferenced(E);
-
- return E;
+ // Skip for member expression of (this->f), rebuilt thisi->f is needed
+ // for Openmp where the field need to be privatizized in the case.
+ if (!(isa<CXXThisExpr>(E->getBase()) &&
+ getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) {
+ // Mark it referenced in the new context regardless.
+ // FIXME: this is a bit instantiation-specific.
+ SemaRef.MarkMemberReferenced(E);
+ return E;
+ }
}
TemplateArgumentListInfo TransArgs;
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -196,6 +196,22 @@
llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
UsesAllocatorsDecls;
+ /// Data is required on creating capture fields for implicit
+ /// default first|private clause.
+ struct ImplicitDefaultFDInfoTy {
+ /// Field decl.
+ const FieldDecl *FD = nullptr;
+ /// Nesting stack level
+ size_t StackLevel = 0;
+ /// Capture variable decl.
+ VarDecl *VD = nullptr;
+ ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
+ VarDecl *VD)
+ : FD(FD), StackLevel(StackLevel), VD(VD) {}
+ };
+ /// List of captured fields
+ llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
+ ImplicitDefaultFirstprivateFDs;
Expr *DeclareMapperVar = nullptr;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
@@ -577,7 +593,9 @@
/// predicate.
const DSAVarData
hasDSA(ValueDecl *D,
- const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool,
+ DefaultDataSharingAttributes)>
+ CPred,
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
bool FromParent) const;
/// Checks if the specified variables has data-sharing attributes which
@@ -1120,6 +1138,52 @@
const SharingMapTy *Top = getTopOfStackOrNull();
return Top ? Top->DeclareMapperVar : nullptr;
}
+ /// get captured field from ImplicitDefaultFirstprivateFDs
+ VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
+ const_iterator I = begin();
+ const_iterator EndI = end();
+ size_t StackLevel = getStackSize();
+ for (; I != EndI; ++I) {
+ if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
+ break;
+ StackLevel--;
+ }
+ assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
+ if (I == EndI)
+ return nullptr;
+ for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
+ if (IFD.FD == FD && IFD.StackLevel == StackLevel)
+ return IFD.VD;
+ return nullptr;
+ }
+ /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
+ bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
+ const_iterator I = begin();
+ const_iterator EndI = end();
+ for (; I != EndI; ++I)
+ if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
+ break;
+ if (I == EndI)
+ return false;
+ for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
+ if (IFD.VD == VD)
+ return true;
+ return false;
+ }
+ /// Store capture FD info in ImplicitDefaultFirstprivateFDs
+ void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
+ iterator I = begin();
+ const_iterator EndI = end();
+ size_t StackLevel = getStackSize();
+ for (; I != EndI; ++I) {
+ if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
+ I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
+ break;
+ }
+ StackLevel--;
+ }
+ assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
+ }
};
bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
@@ -1815,7 +1879,9 @@
const DSAStackTy::DSAVarData
DSAStackTy::hasDSA(ValueDecl *D,
- const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool,
+ DefaultDataSharingAttributes)>
+ CPred,
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
bool FromParent) const {
if (isStackEmpty())
@@ -1831,7 +1897,7 @@
continue;
const_iterator NewI = I;
DSAVarData DVar = getDSA(NewI, D);
- if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
+ if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
return DVar;
}
return {};
@@ -2203,6 +2269,26 @@
false);
}
+bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+ DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
+ D,
+ [](OpenMPClauseKind C, bool AppliedToPointee,
+ DefaultDataSharingAttributes DefaultAttr) {
+ return isOpenMPPrivate(C) && !AppliedToPointee &&
+ (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
+ },
+ [](OpenMPDirectiveKind) { return true; },
+ DSAStack->isClauseParsingMode());
+ if (DVarPrivate.CKind != OMPC_unknown)
+ return true;
+ return false;
+}
+
+static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
+ Expr *CaptureExpr, bool WithInit,
+ DeclContext *CurContext,
+ bool AsExpression);
+
VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
unsigned StopAt) {
assert(LangOpts.OpenMP && "OpenMP is not allowed");
@@ -2301,7 +2387,7 @@
// default(none) clause and not used in any clause.
DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
D,
- [](OpenMPClauseKind C, bool AppliedToPointee) {
+ [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
return isOpenMPPrivate(C) && !AppliedToPointee;
},
[](OpenMPDirectiveKind) { return true; },
@@ -2313,6 +2399,45 @@
DSAStack->getDefaultDSA() != DSA_firstprivate) ||
DVarTop.CKind == OMPC_shared))
return nullptr;
+ auto *FD = dyn_cast<FieldDecl>(D);
+ if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
+ !DVarPrivate.PrivateCopy) {
+ DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
+ D,
+ [](OpenMPClauseKind C, bool AppliedToPointee,
+ DefaultDataSharingAttributes DefaultAttr) {
+ return isOpenMPPrivate(C) && !AppliedToPointee &&
+ (DefaultAttr == DSA_firstprivate ||
+ DefaultAttr == DSA_private);
+ },
+ [](OpenMPDirectiveKind) { return true; },
+ DSAStack->isClauseParsingMode());
+ if (DVarPrivate.CKind == OMPC_unknown)
+ return nullptr;
+
+ VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
+ if (VD)
+ return VD;
+ if (getCurrentThisType().isNull())
+ return nullptr;
+ Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
+ /*IsImplicit=*/true);
+ const CXXScopeSpec CS = CXXScopeSpec();
+ Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
+ NestedNameSpecifierLoc(), SourceLocation(), FD,
+ DeclAccessPair::make(FD, FD->getAccess()),
+ /*HadMultipleCandidates=*/false,
+ DeclarationNameInfo(), FD->getType(),
+ VK_LValue, OK_Ordinary);
+ OMPCapturedExprDecl *CD = buildCaptureDecl(
+ *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
+ CurContext->getParent(), /*AsExpression=*/false);
+ DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
+ *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
+ VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
+ DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
+ return VD;
+ }
if (DVarPrivate.CKind != OMPC_unknown ||
(VD && (DSAStack->getDefaultDSA() == DSA_none ||
DSAStack->getDefaultDSA() == DSA_private ||
@@ -2344,6 +2469,23 @@
OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
unsigned CapLevel) const {
assert(LangOpts.OpenMP && "OpenMP is not allowed");
+ if (DSAStack->getCurrentDirective() != OMPD_unknown &&
+ (!DSAStack->isClauseParsingMode() ||
+ DSAStack->getParentDirective() != OMPD_unknown)) {
+ DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
+ D,
+ [](OpenMPClauseKind C, bool AppliedToPointee,
+ DefaultDataSharingAttributes DefaultAttr) {
+ return isOpenMPPrivate(C) && !AppliedToPointee &&
+ DefaultAttr == DSA_private;
+ },
+ [](OpenMPDirectiveKind) { return true; },
+ DSAStack->isClauseParsingMode());
+ if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
+ DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
+ !DSAStack->isLoopControlVariable(D).first)
+ return OMPC_private;
+ }
if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
bool IsTriviallyCopyable =
D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
@@ -3524,7 +3666,8 @@
if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
// Check the datasharing rules for the expressions in the clauses.
if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
- !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) {
+ !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
+ !Stack->isImplicitDefaultFirstprivateFD(VD))) {
if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
Visit(CED->getInit());
@@ -3533,10 +3676,12 @@
} else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
// Do not analyze internal variables and do not enclose them into
// implicit clauses.
- return;
+ if (!Stack->isImplicitDefaultFirstprivateFD(VD))
+ return;
VD = VD->getCanonicalDecl();
// Skip internally declared variables.
if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
+ !Stack->isImplicitDefaultFirstprivateFD(VD) &&
!Stack->isImplicitTaskFirstprivate(VD))
return;
// Skip allocators in uses_allocators clauses.
@@ -3554,6 +3699,7 @@
if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
(Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
+ !Stack->isImplicitDefaultFirstprivateFD(VD) &&
!Stack->isImplicitTaskFirstprivate(VD))
return;
@@ -4419,6 +4565,7 @@
static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
Expr *CaptureExpr, bool WithInit,
+ DeclContext *CurContext,
bool AsExpression) {
assert(CaptureExpr);
ASTContext &C = S.getASTContext();
@@ -4437,11 +4584,11 @@
}
WithInit = true;
}
- auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
+ auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
CaptureExpr->getBeginLoc());
if (!WithInit)
CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
- S.CurContext->addHiddenDecl(CED);
+ CurContext->addHiddenDecl(CED);
Sema::TentativeAnalysisScope Trap(S);
S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
return CED;
@@ -4454,6 +4601,7 @@
CD = cast<OMPCapturedExprDecl>(VD);
else
CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
+ S.CurContext,
/*AsExpression=*/false);
return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
CaptureExpr->getExprLoc());
@@ -4464,7 +4612,7 @@
if (!Ref) {
OMPCapturedExprDecl *CD = buildCaptureDecl(
S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
- /*WithInit=*/true, /*AsExpression=*/true);
+ /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
CaptureExpr->getExprLoc());
}
@@ -17361,6 +17509,8 @@
SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
SmallVector<Expr *, 8> PrivateCopies;
+ bool IsImplicitClause =
+ StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
for (Expr *RefExpr : VarList) {
assert(RefExpr && "NULL expr in OpenMP private clause.");
SourceLocation ELoc;
@@ -17475,9 +17625,17 @@
*this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
DeclRefExpr *Ref = nullptr;
- if (!VD && !CurContext->isDependentContext())
- Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
- DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
+ if (!VD && !CurContext->isDependentContext()) {
+ auto *FD = dyn_cast<FieldDecl>(D);
+ VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
+ if (VD)
+ Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
+ RefExpr->getExprLoc());
+ else
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
+ }
+ if (!IsImplicitClause)
+ DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
Vars.push_back((VD || CurContext->isDependentContext())
? RefExpr->IgnoreParens()
: Ref);
@@ -17750,8 +17908,14 @@
if (TopDVar.CKind == OMPC_lastprivate) {
Ref = TopDVar.PrivateCopy;
} else {
- Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
- if (!isOpenMPCapturedDecl(D))
+ auto *FD = dyn_cast<FieldDecl>(D);
+ VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
+ if (VD)
+ Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
+ RefExpr->getExprLoc());
+ else
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
+ if (VD || !isOpenMPCapturedDecl(D))
ExprCaptures.push_back(Ref->getDecl());
}
}
@@ -18021,7 +18185,7 @@
return true;
DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
VD,
- [](OpenMPClauseKind C, bool AppliedToPointee) {
+ [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
return isOpenMPPrivate(C) && !AppliedToPointee;
},
[](OpenMPDirectiveKind) { return true; },
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -10725,6 +10725,13 @@
/// constructs.
VarDecl *isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo = false,
unsigned StopAt = 0);
+
+ /// The member expression(this->fd) needs to be rebuilt in the template
+ /// instantiation to generate private copy for OpenMP when default
+ /// clause is used. The function will return true if default
+ /// cluse is used.
+ bool isOpenMPRebuildMemberExpr(ValueDecl *D);
+
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
ExprObjectKind OK, SourceLocation Loc);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits