================
@@ -3589,6 +3589,50 @@ static bool 
canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
   }
 }
 
+/// Emit an LValue for a structured binding captured in an OpenMP region.
+/// Handles extracting individual bindings from the captured decomposed
+/// declaration (struct fields, array elements, etc.).
+LValue CodeGenFunction::EmitOMPCapturedBindingLValue(const BindingDecl *BD) {
+  assert(CapturedStmtInfo &&
+         CapturedStmtInfo->getKind() == CapturedRegionKind::CR_OpenMP &&
+         CGM.getLangOpts().OpenMP);
+  auto *DD = cast<VarDecl>(BD->getDecomposedDecl());
+  QualType AggregType = DD->getType();
+  if (AggregType->isReferenceType())
+    AggregType = AggregType->getPointeeType();
+  DeclarationNameInfo NameInfo(DD->getDeclName(), SourceLocation());
+  DeclRefExpr *DRE = DeclRefExpr::Create(
+      getContext(), NestedNameSpecifierLoc(), SourceLocation(), DD,
+      /*RefersToEnclosingVariableOrCapture=*/true, NameInfo, AggregType,
+      VK_LValue);
+  LValue CapLVal = EmitLValue(DRE);
+  QualType CanonType = AggregType.getCanonicalType();
+  llvm::Type *StructTy = CGM.getTypes().ConvertTypeForMem(CanonType);
+  Address Addr = CapLVal.getAddress();
+  if (Addr.getElementType() != StructTy) {
+    Addr = Addr.withElementType(StructTy);
+    CapLVal = MakeAddrLValue(Addr, CanonType, CapLVal.getBaseInfo(),
+                             CapLVal.getTBAAInfo());
+  }
+  // Extract the specific binding from the decomposed object.
+  Expr *BindingExpr = BD->getBinding()->IgnoreImplicit();
+  if (auto *ME = dyn_cast<MemberExpr>(BindingExpr)) {
+    // Struct/union: access field.
+    FieldDecl *Field = cast<FieldDecl>(ME->getMemberDecl());
+    return EmitLValueForField(CapLVal, Field);
+  }
+  if (dyn_cast<ArraySubscriptExpr>(BindingExpr)) {
----------------
alexey-bataev wrote:

`dyn_cast<ArraySubscriptExpr>(BindingExpr)` discards the casted pointer. Use 
`isa<ArraySubscriptExpr>(BindingExpr)` for a boolean check, or assign and use 
the result. Also: for the array path you immediately call 
`EmitLValue(BD->getBinding(), NotKnownNonNull)`, which throws away the 
carefully constructed `CapLVal` above. So the `EmitLValue(DRE)` and the 
element-type fixup at lines 3608-3616 are dead work for array bindings. Either 
restructure so the fixup is only done for the struct path, or actually use 
`CapLVal` (e.g. via a manual GEP using `EmitScalarExpr(ASE->getIdx())`).

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