@@ -1399,18 +1399,95 @@ mlir::Value Fortran::lower::genReadStatement(
1399
1399
assignMap);
1400
1400
}
1401
1401
1402
+ // / Get the file expression from the inquire spec list. Also return if the
1403
+ // / expression is a file name.
1404
+ static std::pair<const Fortran::semantics::SomeExpr *, bool >
1405
+ getInquireFileExpr (const std::list<Fortran::parser::InquireSpec> *stmt) {
1406
+ if (!stmt)
1407
+ return {nullptr , false };
1408
+ for (const auto &spec : *stmt) {
1409
+ if (auto *f = std::get_if<Fortran::parser::FileUnitNumber>(&spec.u ))
1410
+ return {Fortran::semantics::GetExpr (*f), false };
1411
+ if (auto *f = std::get_if<Fortran::parser::FileNameExpr>(&spec.u ))
1412
+ return {Fortran::semantics::GetExpr (*f), true };
1413
+ }
1414
+ // semantics should have already caught this condition
1415
+ llvm_unreachable (" inquire spec must have a file" );
1416
+ }
1417
+
1402
1418
mlir::Value Fortran::lower::genInquireStatement (
1403
1419
Fortran::lower::AbstractConverter &converter,
1404
- const Fortran::parser::InquireStmt &) {
1420
+ const Fortran::parser::InquireStmt &stmt ) {
1405
1421
auto &builder = converter.getFirOpBuilder ();
1406
1422
auto loc = converter.getCurrentLocation ();
1407
1423
mlir::FuncOp beginFunc;
1408
- // if (...
1409
- beginFunc = getIORuntimeFunc<mkIOKey (BeginInquireUnit)>(loc, builder);
1410
- // else if (...
1411
- beginFunc = getIORuntimeFunc<mkIOKey (BeginInquireFile)>(loc, builder);
1412
- // else
1413
- beginFunc = getIORuntimeFunc<mkIOKey (BeginInquireIoLength)>(loc, builder);
1414
- // TODO: implement this!
1415
- llvm::report_fatal_error (" INQUIRE statement is not implemented" );
1424
+ mlir::Value cookie;
1425
+ ConditionSpecifierInfo csi{};
1426
+ const auto *list =
1427
+ std::get_if<std::list<Fortran::parser::InquireSpec>>(&stmt.u );
1428
+ auto exprPair = getInquireFileExpr (list);
1429
+ auto inquireFileUnit = [&]() -> bool {
1430
+ return exprPair.first && !exprPair.second ;
1431
+ };
1432
+ auto inquireFileName = [&]() -> bool {
1433
+ return exprPair.first && exprPair.second ;
1434
+ };
1435
+
1436
+ // Determine which BeginInquire call to make.
1437
+ if (inquireFileUnit ()) {
1438
+ // File unit call.
1439
+ beginFunc = getIORuntimeFunc<mkIOKey (BeginInquireUnit)>(loc, builder);
1440
+ mlir::FunctionType beginFuncTy = beginFunc.getType ();
1441
+ auto unit = converter.genExprValue (exprPair.first , loc);
1442
+ auto un = builder.createConvert (loc, beginFuncTy.getInput (0 ), unit);
1443
+ auto file = getDefaultFilename (builder, loc, beginFuncTy.getInput (1 ));
1444
+ auto line = getDefaultLineNo (builder, loc, beginFuncTy.getInput (2 ));
1445
+ llvm::SmallVector<mlir::Value, 4 > beginArgs{un, file, line};
1446
+ cookie =
1447
+ builder.create <mlir::CallOp>(loc, beginFunc, beginArgs).getResult (0 );
1448
+ // Handle remaining arguments in specifier list.
1449
+ genConditionHandlerCall (converter, loc, cookie, *list, csi);
1450
+ } else if (inquireFileName ()) {
1451
+ // Filename call.
1452
+ beginFunc = getIORuntimeFunc<mkIOKey (BeginInquireFile)>(loc, builder);
1453
+ mlir::FunctionType beginFuncTy = beginFunc.getType ();
1454
+ auto file = converter.genExprValue (exprPair.first , loc);
1455
+ // Helper to query [BUFFER, LEN].
1456
+ Fortran::lower::CharacterExprHelper helper (builder, loc);
1457
+ auto dataLen = helper.materializeCharacter (file);
1458
+ auto buff =
1459
+ builder.createConvert (loc, beginFuncTy.getInput (0 ), dataLen.first );
1460
+ auto len =
1461
+ builder.createConvert (loc, beginFuncTy.getInput (1 ), dataLen.second );
1462
+ auto kindInt = helper.getCharacterKind (file.getType ());
1463
+ mlir::Value kindValue =
1464
+ builder.createIntegerConstant (loc, beginFuncTy.getInput (2 ), kindInt);
1465
+ auto sourceFile = getDefaultFilename (builder, loc, beginFuncTy.getInput (3 ));
1466
+ auto line = getDefaultLineNo (builder, loc, beginFuncTy.getInput (4 ));
1467
+ llvm::SmallVector<mlir::Value, 5 > beginArgs = {
1468
+ buff, len, kindValue, sourceFile, line,
1469
+ };
1470
+ cookie =
1471
+ builder.create <mlir::CallOp>(loc, beginFunc, beginArgs).getResult (0 );
1472
+ // Handle remaining arguments in specifier list.
1473
+ genConditionHandlerCall (converter, loc, cookie, *list, csi);
1474
+ } else {
1475
+ // Io length call.
1476
+ const auto *ioLength =
1477
+ std::get_if<Fortran::parser::InquireStmt::Iolength>(&stmt.u );
1478
+ assert (ioLength && " must have an io length" );
1479
+ beginFunc = getIORuntimeFunc<mkIOKey (BeginInquireIoLength)>(loc, builder);
1480
+ mlir::FunctionType beginFuncTy = beginFunc.getType ();
1481
+ auto file = getDefaultFilename (builder, loc, beginFuncTy.getInput (0 ));
1482
+ auto line = getDefaultLineNo (builder, loc, beginFuncTy.getInput (1 ));
1483
+ llvm::SmallVector<mlir::Value, 4 > beginArgs{file, line};
1484
+ cookie =
1485
+ builder.create <mlir::CallOp>(loc, beginFunc, beginArgs).getResult (0 );
1486
+ // Handle remaining arguments in output list.
1487
+ genConditionHandlerCall (
1488
+ converter, loc, cookie,
1489
+ std::get<std::list<Fortran::parser::OutputItem>>(ioLength->t ), csi);
1490
+ }
1491
+ // Generate end statement call.
1492
+ return genEndIO (converter, loc, cookie, csi);
1416
1493
}
0 commit comments