summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/CodeGen/CodeGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/CodeGen/CodeGen.cpp')
-rw-r--r--flang/lib/Optimizer/CodeGen/CodeGen.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 1611de9e6389..15fcc09c6219 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -660,6 +660,31 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
auto loc = convert.getLoc();
auto i1Type = mlir::IntegerType::get(convert.getContext(), 1);
+ if (mlir::isa<fir::RecordType>(toFirTy)) {
+ // Convert to compatible BIND(C) record type.
+ // Double check that the record types are compatible (it should have
+ // already been checked by the verifier).
+ assert(mlir::cast<fir::RecordType>(fromFirTy).getTypeList() ==
+ mlir::cast<fir::RecordType>(toFirTy).getTypeList() &&
+ "incompatible record types");
+
+ auto toStTy = mlir::cast<mlir::LLVM::LLVMStructType>(toTy);
+ mlir::Value val = rewriter.create<mlir::LLVM::UndefOp>(loc, toStTy);
+ auto indexTypeMap = toStTy.getSubelementIndexMap();
+ assert(indexTypeMap.has_value() && "invalid record type");
+
+ for (auto [attr, type] : indexTypeMap.value()) {
+ int64_t index = mlir::cast<mlir::IntegerAttr>(attr).getInt();
+ auto extVal =
+ rewriter.create<mlir::LLVM::ExtractValueOp>(loc, op0, index);
+ val =
+ rewriter.create<mlir::LLVM::InsertValueOp>(loc, val, extVal, index);
+ }
+
+ rewriter.replaceOp(convert, val);
+ return mlir::success();
+ }
+
if (mlir::isa<fir::LogicalType>(fromFirTy) ||
mlir::isa<fir::LogicalType>(toFirTy)) {
// By specification fir::LogicalType value may be any number,