diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -1385,7 +1385,74 @@ hlfir::Entity lhs) { if constexpr (TC1 == Fortran::common::TypeCategory::Character && TC2 == TC1) { - TODO(loc, "character conversion in HLFIR"); + // TODO(loc, "character conversion in HLFIR"); + // REMEMBER: lhs = fromBuffer; rhs = toBuffer + + // need kindmap ala: + auto kindMap = builder.getKindMap(); + // need address of fromBuffer + // already taken care (?) of since Entity inherits from mlir::Value + // hlfir::Entity fromAddr{lhs}; + // need type of fromBuffer + mlir::Type fromTy = lhs.getFortranElementType(); + // need length of the fromBuffer + mlir::Value bufferSize = genCharLength(loc, builder, lhs); + // get number of bits needed to store the fromBuffer + auto fromBits = kindMap.getCharacterBitsize( + fir::unwrapRefType(fromTy).cast().getFKind()); + // get toTy + mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC1, + KIND, /*params=*/std::nullopt); + + // get number of bits needed to store in toBuffer + auto toBits = + kindMap.getCharacterBitsize(ty.cast().getFKind()); + // account for if the from.KIND is bigger than to.KIND + if (toBits < fromBits) { + // Scale by relative ratio to give a buffer of the same length. + auto ratio = builder.createIntegerConstant(loc, bufferSize.getType(), + fromBits / toBits); + bufferSize = + builder.create(loc, bufferSize, ratio); + } + // allocate space on the stack for toBuffer + auto dest = + builder.create(loc, ty, mlir::ValueRange{bufferSize}); + + // account for if the type is of fir::CharacterType + if (auto charTy = fromTy.dyn_cast()) { + // boxchar is a value, not a variable. Turn it into a temporary. + // As a value, it ought to have a constant LEN value. + // assert(charTy.hasConstantLen() && "must have constant length"); + // can't create hlfir::Entity + // hlfir::Entity tmp{builder.createTemporary(loc, charTy)}; + mlir::Value tmp{ + builder.createTemporary(loc, charTy, {}, {}, bufferSize, {})}; + builder.create(loc, lhs, tmp); + // fromAddr{tmp}; + builder.create( + loc, tmp, genCharLength(loc, builder, lhs), dest); + auto varOp = + hlfir::EntityWithAttributes{builder.create( + loc, tmp, "ctor.temp", /*shape=*/nullptr, + /*typeparams=*/mlir::ValueRange{}, + fir::FortranVariableFlagsAttr{})}; + return hlfir::EntityWithAttributes{varOp}; + } else { + builder.create( + loc, lhs, genCharLength(loc, builder, lhs), dest); + } + + // return a hlfir::Entity, which I think we can just do something ala: + // fir::CharBoxValue res{dest, genCharLength(loc, builder, lhs)}; + // builder.create(loc, ty, dest, + // genCharLength(loc, builder, lhs)); + // mlir::Type newType = res.getBuffer().getType(); + // assert(fir::isa_trivial(ty) || fir::isa_char(ty) && "you done goofed"); + // assert(fir::isa_trivial(newType) || + // fir::isa_char(newType) && "you done goofed"); + // return hlfir::EntityWithAttributes{res.getBuffer()}; + return hlfir::EntityWithAttributes{dest}; } mlir::Type type = Fortran::lower::getFIRType(builder.getContext(), TC1, KIND, /*params=*/std::nullopt);