@@ -155,6 +155,21 @@ class Fortran::lower::CallInterfaceImpl {
155
155
FirPlaceHolder::resultEntityPosition, Property::Value);
156
156
}
157
157
158
+ void buildExplicitInterface (
159
+ const Fortran::evaluate::characteristics::Procedure &procedure) {
160
+ // Handle result
161
+ if (const std::optional<Fortran::evaluate::characteristics::FunctionResult>
162
+ &result = procedure.functionResult ) {
163
+ if (result->CanBeReturnedViaImplicitInterface ())
164
+ handleImplicitResult (*result);
165
+ else
166
+ handleExplicitResult (*result);
167
+ } else if (interface.side ().hasAlternateReturns ()) {
168
+ addFirResult (mlir::IndexType::get (&mlirContext),
169
+ FirPlaceHolder::resultEntityPosition, Property::Value);
170
+ }
171
+ }
172
+
158
173
private:
159
174
void handleImplicitResult (
160
175
const Fortran::evaluate::characteristics::FunctionResult &result) {
@@ -182,6 +197,57 @@ class Fortran::lower::CallInterfaceImpl {
182
197
}
183
198
}
184
199
200
+ void handleExplicitResult (
201
+ const Fortran::evaluate::characteristics::FunctionResult &result) {
202
+ using Attr = Fortran::evaluate::characteristics::FunctionResult::Attr;
203
+
204
+ if (result.IsProcedurePointer ())
205
+ TODO (interface.converter .getCurrentLocation (),
206
+ " procedure pointer results" );
207
+ const Fortran::evaluate::characteristics::TypeAndShape *typeAndShape =
208
+ result.GetTypeAndShape ();
209
+ assert (typeAndShape && " expect type for non proc pointer result" );
210
+ Fortran::evaluate::DynamicType dynamicType = typeAndShape->type ();
211
+ if (dynamicType.category () == Fortran::common::TypeCategory::Character) {
212
+ TODO (interface.converter .getCurrentLocation (),
213
+ " implicit result character type" );
214
+ } else if (dynamicType.category () ==
215
+ Fortran::common::TypeCategory::Derived) {
216
+ TODO (interface.converter .getCurrentLocation (),
217
+ " implicit result derived type" );
218
+ }
219
+ mlir::Type mlirType =
220
+ getConverter ().genType (dynamicType.category (), dynamicType.kind ());
221
+ fir::SequenceType::Shape bounds = getBounds (typeAndShape->shape ());
222
+ if (!bounds.empty ())
223
+ mlirType = fir::SequenceType::get (bounds, mlirType);
224
+ if (result.attrs .test (Attr::Allocatable))
225
+ mlirType = fir::BoxType::get (fir::HeapType::get (mlirType));
226
+ if (result.attrs .test (Attr::Pointer))
227
+ mlirType = fir::BoxType::get (fir::PointerType::get (mlirType));
228
+
229
+ addFirResult (mlirType, FirPlaceHolder::resultEntityPosition,
230
+ Property::Value);
231
+ }
232
+
233
+ fir::SequenceType::Shape getBounds (const Fortran::evaluate::Shape &shape) {
234
+ fir::SequenceType::Shape bounds;
235
+ for (Fortran::evaluate::MaybeExtentExpr extentExpr : shape) {
236
+ fir::SequenceType::Extent extent = fir::SequenceType::getUnknownExtent ();
237
+ if (std::optional<std::int64_t > constantExtent =
238
+ toInt64 (std::move (extentExpr)))
239
+ extent = *constantExtent;
240
+ bounds.push_back (extent);
241
+ }
242
+ return bounds;
243
+ }
244
+
245
+ template <typename A>
246
+ std::optional<std::int64_t > toInt64 (A &&expr) {
247
+ return Fortran::evaluate::ToInt64 (Fortran::evaluate::Fold (
248
+ getConverter ().getFoldingContext (), std::move (expr)));
249
+ }
250
+
185
251
void addFirResult (mlir::Type type, int entityPosition, Property p) {
186
252
interface.outputs .emplace_back (FirPlaceHolder{type, entityPosition, p});
187
253
}
@@ -201,7 +267,7 @@ void Fortran::lower::CallInterface<T>::determineInterface(
201
267
if (isImplicit)
202
268
impl.buildImplicitInterface (procedure);
203
269
else
204
- TODO_NOLOC ( " determineImplicitInterface " );
270
+ impl. buildExplicitInterface (procedure );
205
271
}
206
272
207
273
template <typename T>
0 commit comments