diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -465,6 +465,20 @@ } }; +/// Lower `fir.boxproc_host` operation. Extracts the host pointer from the +/// boxproc. +/// TODO: Part of supporting Fortran 2003 procedure pointers. +struct BoxProcHostOpConversion : public FIROpConversion { + using FIROpConversion::FIROpConversion; + + mlir::LogicalResult + matchAndRewrite(fir::BoxProcHostOp boxprochost, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + return rewriter.notifyMatchFailure( + boxprochost, "fir.boxproc_host codegen is not implemented yet"); + } +}; + // `fir.call` -> `llvm.call` struct CallOpConversion : public FIROpConversion { using FIROpConversion::FIROpConversion; @@ -636,6 +650,19 @@ } }; +/// Lower `fir.emboxproc` operation. Creates a procedure box. +/// TODO: Part of supporting Fortran 2003 procedure pointers. +struct EmboxProcOpConversion : public FIROpConversion { + using FIROpConversion::FIROpConversion; + + mlir::LogicalResult + matchAndRewrite(fir::EmboxProcOp emboxproc, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + return rewriter.notifyMatchFailure( + emboxproc, "fir.emboxproc codegen is not implemented yet"); + } +}; + /// Lower `fir.has_value` operation to `llvm.return` operation. struct HasValueOpConversion : public FIROpConversion { using FIROpConversion::FIROpConversion; @@ -966,6 +993,20 @@ } }; +/// Lower `fir.unboxproc` operation. Unbox a procedure box value, yielding its +/// components. +/// TODO: Part of supporting Fortran 2003 procedure pointers. +struct UnboxProcOpConversion : public FIROpConversion { + using FIROpConversion::FIROpConversion; + + mlir::LogicalResult + matchAndRewrite(fir::UnboxProcOp unboxproc, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + return rewriter.notifyMatchFailure( + unboxproc, "fir.unboxproc codegen is not implemented yet"); + } +}; + /// convert to LLVM IR dialect `undef` struct UndefOpConversion : public FIROpConversion { using FIROpConversion::FIROpConversion; @@ -1414,14 +1455,15 @@ AbsentOpConversion, AddcOpConversion, AddrOfOpConversion, AllocaOpConversion, BoxAddrOpConversion, BoxDimsOpConversion, BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion, - BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion, - ConvertOpConversion, DispatchOpConversion, DispatchTableOpConversion, - DTEntryOpConversion, DivcOpConversion, ExtractValueOpConversion, - HasValueOpConversion, GlobalOpConversion, InsertOnRangeOpConversion, - InsertValueOpConversion, IsPresentOpConversion, LoadOpConversion, - NegcOpConversion, MulcOpConversion, SelectCaseOpConversion, - SelectOpConversion, SelectRankOpConversion, StoreOpConversion, - SubcOpConversion, UndefOpConversion, UnreachableOpConversion, + BoxIsPtrOpConversion, BoxProcHostOpConversion, BoxRankOpConversion, + CallOpConversion, ConvertOpConversion, DispatchOpConversion, + DispatchTableOpConversion, DTEntryOpConversion, DivcOpConversion, + EmboxProcOpConversion, ExtractValueOpConversion, HasValueOpConversion, + GlobalOpConversion, InsertOnRangeOpConversion, InsertValueOpConversion, + IsPresentOpConversion, LoadOpConversion, NegcOpConversion, + MulcOpConversion, SelectCaseOpConversion, SelectOpConversion, + SelectRankOpConversion, StoreOpConversion, SubcOpConversion, + UnboxProcOpConversion, UndefOpConversion, UnreachableOpConversion, ZeroOpConversion>(typeConverter); mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern); mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter, diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h --- a/flang/lib/Optimizer/CodeGen/TypeConverter.h +++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h @@ -54,6 +54,11 @@ LLVM_DEBUG(llvm::dbgs() << "type convert: " << boxchar << '\n'); return convertType(specifics->boxcharMemoryType(boxchar.getEleTy())); }); + addConversion([&](BoxProcType boxproc) { + // TODO: Support for this type will be added later when the Fortran 2003 + // procedure pointer feature is implemented. + return llvm::None; + }); addConversion( [&](fir::CharacterType charTy) { return convertCharType(charTy); }); addConversion([&](HeapType heap) { return convertPointerLike(heap); }); diff --git a/flang/test/Fir/convert-to-llvm-invalid.fir b/flang/test/Fir/convert-to-llvm-invalid.fir --- a/flang/test/Fir/convert-to-llvm-invalid.fir +++ b/flang/test/Fir/convert-to-llvm-invalid.fir @@ -50,3 +50,49 @@ ^bb3: return } + +// ----- + +// Test that the type `fir.boxproc` fails to be legalized. +// Not implemented yet. + +// expected-error@+1{{failed to legalize operation 'builtin.func'}} +func private @foo0(%arg0: !fir.boxproc<() -> ()>) + +// ----- + +// Test that `fir.emboxproc` fails to be legalized. +// Not implemented yet. + +func private @method_impl(i32) + +func @emboxproc_test() { + %host_vars = fir.alloca tuple +// expected-error@+1{{failed to legalize operation 'fir.emboxproc'}} + %bproc = fir.emboxproc @method_impl, %host_vars : ((i32) -> (), !fir.ref>) -> !fir.boxproc<(i32) -> ()> + return +} + +// ----- + +// Test that `fir.unboxproc` fails to be legalized. +// Not implemented yet. + +func @unboxproc_test() { + %bproc = fir.call @get_bproc() : () -> (!fir.boxproc<(i32) -> ()>) +// expected-error@+1{{failed to legalize operation 'fir.unboxproc'}} + %ubproc:2 = fir.unboxproc %bproc : (!fir.boxproc<(i32) -> ()>) -> ((i32) -> (), !fir.ref>) + return +} + +// ----- + +// Test that `fir.boxproc_host` fails to be legalized. +// Not implemented yet. + +func @boxproc_host_test() { + %bproc = fir.call @get_bproc() : () -> (!fir.boxproc<(i32) -> ()>) +// expected-error@+1{{failed to legalize operation 'fir.boxproc_host'}} + %host_tuple = fir.boxproc_host %bproc : (!fir.boxproc<(i32) -> ()>) -> (!fir.ref>) + return +}