================
@@ -3595,6 +3595,75 @@ 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 && "Expected to be inside a captured region");
+ assert(CapturedStmtInfo->getKind() == CapturedRegionKind::CR_OpenMP &&
+ "Expected OpenMP captured region");
+ assert(CGM.getLangOpts().OpenMP && "Expected OpenMP to be enabled");
+
+ if (auto It = LocalDeclMap.find(BD->getCanonicalDecl());
+ It != LocalDeclMap.end())
+ return MakeAddrLValue(It->second, BD->getType());
+
+ const auto *DD = cast<VarDecl>(BD->getDecomposedDecl());
+
+ // Check if the original variable (what DD decomposes) has been mapped.
+ // If so, use the original variable instead of DD to avoid capturing DD.
+ const VarDecl *TargetDecl = DD;
+ if (const auto *DecompDecl = dyn_cast<DecompositionDecl>(DD)) {
+ if (const VarDecl *OrigVar = DecompDecl->getOriginalVar().Var) {
+ auto It = LocalDeclMap.find(OrigVar->getCanonicalDecl());
+ if (It != LocalDeclMap.end())
+ // Original variable is mapped, use it instead.
+ TargetDecl = OrigVar;
+ }
+ }
+
+ // Use getNonReferenceType() because we need the actual object type, not the
+ // reference type. DeclRefExpr with VK_LValue requires a non-reference type
+ // (AST invariant). EmitDeclRefLValue will load any reference for us.
+ QualType DREType = TargetDecl->getType().getNonReferenceType();
+ DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(TargetDecl),
+ /*RefersToEnclosingVariableOrCapture=*/true, DREType,
+ VK_LValue, SourceLocation());
+ LValue BaseLVal = EmitDeclRefLValue(&DRE);
+
+ // Ensure the Address has the correct element type for DD's type.
+ // EmitDeclRefLValue might return an address with a different element type
+ // if TargetDecl != DD or if reference unwrapping occurred.
+ Address BaseAddr = BaseLVal.getAddress();
+ QualType DDType = DD->getType();
+ llvm::Type *ExpectedTy = CGM.getTypes().ConvertTypeForMem(DDType);
+ if (BaseAddr.getElementType() != ExpectedTy)
+ BaseAddr = BaseAddr.withElementType(ExpectedTy);
+
+ // Now emit the binding expression (array subscript, member access, etc.)
+ // by temporarily installing the decomposed storage address, then routing
+ // through EmitLValue for the binding expression.
+ Expr *BindingExpr = BD->getBinding();
+ auto It = LocalDeclMap.find(DD);
+ bool WasMapped = It != LocalDeclMap.end();
+ Address SavedAddr = WasMapped ? It->second : Address::invalid();
+ if (WasMapped)
----------------
alexey-bataev wrote:
```suggestion
Address MapAddr = BaseAddr;
if (DD->getType()->isReferenceType()) {
RawAddress RefSlot = CreateMemTemp(DD->getType(), "omp.binding.ref");
Builder.CreateStore(BaseAddr.emitRawPointer(*this), RefSlot);
MapAddr = RefSlot;
}
if (WasMapped)
```
https://github.com/llvm/llvm-project/pull/190832
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits