[clang] [OpenMP] Support capturing structured bindings in OpenMP regions. (PR #190832)
Zahira Ammarguellat via cfe-commits
cfe-commits at lists.llvm.org
Fri May 1 13:17:10 PDT 2026
================
@@ -3589,6 +3589,51 @@ 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=*/false, NameInfo, AggregType,
+ VK_LValue);
+ LValue CapLVal = EmitLValue(DRE);
+
+ // 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);
+ } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(BindingExpr)) {
----------------
zahiraam wrote:
`EmitLValue(BD->getBinding())` crashes because the `DeclRefExpr` inside the binding expression resolves to a pointer with the wrong element type (element type is` i32` not `[N x i32]`), causing `EmitArraySubscriptExpr` to emit an invalid multi-index GEP. Computing this manually correctly uses the already-fixed-up `CapLVal` address as the base.
https://github.com/llvm/llvm-project/pull/190832
More information about the cfe-commits
mailing list