18#ifndef FORTRAN_LOWER_HLFIRINTRINSICS_H
19#define FORTRAN_LOWER_HLFIRINTRINSICS_H
21#include "flang/Optimizer/Builder/HLFIRTools.h"
22#include "flang/Optimizer/Builder/Todo.h"
23#include "flang/Optimizer/HLFIR/HLFIROps.h"
24#include "llvm/ADT/SmallVector.h"
38struct IntrinsicArgumentLoweringRules;
49 std::optional<mlir::Value> isPresent)
50 : actual{actual}, isPresent{isPresent} {}
52 : actual{vectorSubscriptedActual}, isPresent{std::nullopt} {}
53 void setElementalIndices(mlir::ValueRange &indices) {
54 oneBasedElementalIndices = &indices;
61 void derefPointersAndAllocatables(mlir::Location loc,
63 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
64 actual = hlfir::derefPointersAndAllocatables(loc, builder, *actualEntity);
68 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
69 actual = hlfir::loadTrivialScalar(loc, builder, *actualEntity);
76 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual)) {
77 if (!actualEntity->isVariable() && actualEntity->isArray()) {
78 mlir::Type storageType = actualEntity->getType();
79 hlfir::AssociateOp associate = hlfir::genAssociateExpr(
80 loc, builder, *actualEntity, storageType,
"adapt.impure_arg_eval");
88 bool isArray()
const {
89 return std::holds_alternative<hlfir::ElementalAddrOp>(actual) ||
90 std::get<hlfir::Entity>(actual).
isArray();
94 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
95 return hlfir::genShape(loc, builder, *actualEntity);
96 return std::get<hlfir::ElementalAddrOp>(actual).getShape();
100 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
101 return hlfir::genCharLength(loc, builder, *actualEntity);
102 auto typeParams = std::get<hlfir::ElementalAddrOp>(actual).getTypeparams();
103 assert(typeParams.size() == 1 &&
104 "failed to retrieve vector subscripted character length");
105 return typeParams[0];
111 if (
auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
112 return *actualEntity;
113 TODO(loc,
"polymorphic vector subscripts");
116 bool handleDynamicOptional()
const {
return isPresent.has_value(); }
117 mlir::Value getIsPresent()
const {
118 assert(handleDynamicOptional() &&
"not a dynamic optional");
122 void resetOptionalAspect() { isPresent = std::nullopt; }
125 std::variant<hlfir::Entity, hlfir::ElementalAddrOp> actual;
126 mlir::ValueRange *oneBasedElementalIndices{
nullptr};
130 std::optional<mlir::Value> isPresent;
138std::optional<hlfir::EntityWithAttributes> lowerHlfirIntrinsic(
142 mlir::Type stmtResultType);
Definition: FIRBuilder.h:55
Definition: HLFIRTools.h:51
bool isArray() const
Is this an array or an assumed ranked entity?
Definition: HLFIRTools.h:73
Definition: AbstractConverter.h:59
Definition: AbstractConverter.h:31
@ Value
Lower argument to a value. Mainly intended for scalar arguments.
Definition: AbstractConverter.h:27
Definition: HlfirIntrinsics.h:46
mlir::Value getPolymorphicMold(mlir::Location loc) const
Definition: HlfirIntrinsics.h:110
hlfir::Entity getActual(mlir::Location loc, fir::FirOpBuilder &builder) const
Definition: ConvertCall.cpp:2797
hlfir::AssociateOp associateIfArrayExpr(mlir::Location loc, fir::FirOpBuilder &builder)
Definition: HlfirIntrinsics.h:74
This is shared by intrinsics and intrinsic module procedures.
Definition: IntrinsicCall.h:529