46struct PreparedActualArgument {
49 std::optional<mlir::Value> isPresent)
50 : actual{actual}, isPresent{isPresent} {}
51 PreparedActualArgument(hlfir::ElementalAddrOp vectorSubscriptedActual)
52 : actual{vectorSubscriptedActual}, isPresent{std::nullopt} {}
53 void setElementalIndices(mlir::ValueRange &indices) {
54 oneBasedElementalIndices = &indices;
61 mlir::Type getFortranElementType() {
62 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
63 return hlfir::getFortranElementType(actualEntity->getType());
65 std::get<hlfir::ElementalAddrOp>(actual).getElementEntity();
66 return hlfir::getFortranElementType(entity.getType());
69 void derefPointersAndAllocatables(mlir::Location loc,
71 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
72 actual = hlfir::derefPointersAndAllocatables(loc, builder, *actualEntity);
76 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
77 actual = hlfir::loadTrivialScalar(loc, builder, *actualEntity);
84 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual)) {
85 if (!actualEntity->isVariable() && actualEntity->isArray()) {
86 mlir::Type storageType = actualEntity->getType();
87 hlfir::AssociateOp associate = hlfir::genAssociateExpr(
88 loc, builder, *actualEntity, storageType,
"adapt.impure_arg_eval");
96 bool isArray()
const {
97 return std::holds_alternative<hlfir::ElementalAddrOp>(actual) ||
98 std::get<hlfir::Entity>(actual).isArray();
102 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
103 return hlfir::genShape(loc, builder, *actualEntity);
104 return std::get<hlfir::ElementalAddrOp>(actual).getShape();
108 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
109 return hlfir::genCharLength(loc, builder, *actualEntity);
110 auto typeParams = std::get<hlfir::ElementalAddrOp>(actual).getTypeparams();
111 assert(typeParams.size() == 1 &&
112 "failed to retrieve vector subscripted character length");
113 return typeParams[0];
116 void genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
117 llvm::SmallVectorImpl<mlir::Value> &result) {
118 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual)) {
119 hlfir::genLengthParameters(loc, builder, *actualEntity, result);
122 for (mlir::Value len :
123 std::get<hlfir::ElementalAddrOp>(actual).getTypeparams())
124 result.push_back(len);
130 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
131 return *actualEntity;
132 TODO(loc,
"polymorphic vector subscripts");
135 bool handleDynamicOptional()
const {
return isPresent.has_value(); }
136 mlir::Value getIsPresent()
const {
137 assert(handleDynamicOptional() &&
"not a dynamic optional");
141 void resetOptionalAspect() { isPresent = std::nullopt; }
144 std::variant<hlfir::Entity, hlfir::ElementalAddrOp> actual;
145 mlir::ValueRange *oneBasedElementalIndices{
nullptr};
149 std::optional<mlir::Value> isPresent;