================
@@ -4672,39 +4672,69 @@ static bool
buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
SmallVectorImpl<CapturedStmt::Capture> &Captures,
SmallVectorImpl<Expr *> &CaptureInits) {
+ llvm::SmallPtrSet<VarDecl *, 4> CapturedDecomposed;
for (const sema::Capture &Cap : RSI->Captures) {
if (Cap.isInvalid())
continue;
+ ValueDecl *CapVar = nullptr;
+ if (Cap.isVariableCapture()) {
+ CapVar = Cap.getVariable();
+ if (auto *BD = dyn_cast<BindingDecl>(CapVar)) {
+ VarDecl *DD = cast<VarDecl>(BD->getDecomposedDecl());
+ if (!CapturedDecomposed.insert(DD).second) {
+ continue; // Skip duplicate.
+ }
+ CapVar = DD;
+ }
+ }
+
// Form the initializer for the capture.
ExprResult Init = S.BuildCaptureInit(Cap, Cap.getLocation(),
RSI->CapRegionKind == CR_OpenMP);
// FIXME: Bail out now if the capture is not used and the initializer has
// no side-effects.
- // Create a field for this capture.
- FieldDecl *Field = S.BuildCaptureField(RSI->TheRecordDecl, Cap);
+ // Build the capture field. For OpenMP BindingDecl captures redirected
+ // to their DecompositionDecl, the field type must use the
+ // DecompositionDecl's type (e.g. int[2]) not the BindingDecl's type (e.g.
+ // int).
+ FieldDecl *Field = nullptr;
+ if (RSI->CapRegionKind == CR_OpenMP && CapVar &&
+ CapVar != Cap.getVariable() && isa<DecompositionDecl>(CapVar)) {
+ // Manually build a reference field with the DecompositionDecl's type.
+ QualType DDType = cast<VarDecl>(CapVar)->getType();
+ QualType RefType = S.Context.getLValueReferenceType(DDType);
+ TypeSourceInfo *TSI =
+ S.Context.getTrivialTypeSourceInfo(RefType, Cap.getLocation());
+ Field = FieldDecl::Create(S.Context, RSI->TheRecordDecl,
+ Cap.getLocation(), Cap.getLocation(),
+ /*Id=*/nullptr, RefType, TSI,
+ /*BW=*/nullptr, /*Mutable=*/false,
ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ RSI->TheRecordDecl->addDecl(Field);
+ } else {
+ Field = S.BuildCaptureField(RSI->TheRecordDecl, Cap);
+ }
// Add the capture to our list of captures.
if (Cap.isThisCapture()) {
- Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),
- CapturedStmt::VCK_This));
+ Captures.push_back(
+ CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_This));
} else if (Cap.isVLATypeCapture()) {
Captures.push_back(
CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_VLAType));
} else {
assert(Cap.isVariableCapture() && "unknown kind of capture");
if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP)
- S.OpenMP().setOpenMPCaptureKind(Field, Cap.getVariable(),
- RSI->OpenMPLevel);
-
- Captures.push_back(CapturedStmt::Capture(
- Cap.getLocation(),
- Cap.isReferenceCapture() ? CapturedStmt::VCK_ByRef
- : CapturedStmt::VCK_ByCopy,
- cast<VarDecl>(Cap.getVariable())));
+ S.OpenMP().setOpenMPCaptureKind(Field, CapVar, RSI->OpenMPLevel);
----------------
alexey-bataev wrote:
`setOpenMPCaptureKind(Field, CapVar, ...)` is now passing the
`DecompositionDecl` for binding captures. The DSA stack tracks DSA per
`BindingDecl` (the user-visible name in `firstprivate(a)` etc.), not per
`DecompositionDecl`. With this change, `hasExplicitDSA(DD, ...)` will not find
DSAs registered for `a`/`b`. Pass `Cap.getVariable()` (the original
`BindingDecl`) here, or look up DSA on both.
https://github.com/llvm/llvm-project/pull/190832
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits