================
@@ -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

Reply via email to