xref: /llvm-project/flang/unittests/Frontend/CodeGenActionTest.cpp (revision c870632ef6162fbdccaad8cd09420728220ad344)
110317da2SKareem Ergawy //===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//
210317da2SKareem Ergawy //
310317da2SKareem Ergawy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
410317da2SKareem Ergawy // See https://llvm.org/LICENSE.txt for license information.
510317da2SKareem Ergawy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610317da2SKareem Ergawy //
710317da2SKareem Ergawy //===----------------------------------------------------------------------===//
810317da2SKareem Ergawy //
910317da2SKareem Ergawy // Unit tests for CodeGenAction.
1010317da2SKareem Ergawy //
1110317da2SKareem Ergawy //===----------------------------------------------------------------------===//
1210317da2SKareem Ergawy 
1310317da2SKareem Ergawy #include "mlir/IR/Builders.h"
1410317da2SKareem Ergawy #include "flang/Frontend/CompilerInstance.h"
1510317da2SKareem Ergawy #include "flang/Frontend/FrontendActions.h"
1610317da2SKareem Ergawy #include "flang/Frontend/TextDiagnosticPrinter.h"
1710317da2SKareem Ergawy 
1810317da2SKareem Ergawy #include "gtest/gtest.h"
1910317da2SKareem Ergawy 
2010317da2SKareem Ergawy #include <memory>
2110317da2SKareem Ergawy 
2210317da2SKareem Ergawy using namespace Fortran::frontend;
2310317da2SKareem Ergawy 
2410317da2SKareem Ergawy namespace test {
2510317da2SKareem Ergawy class DummyDialect : public ::mlir::Dialect {
2610317da2SKareem Ergawy   explicit DummyDialect(::mlir::MLIRContext *context)
2710317da2SKareem Ergawy       : ::mlir::Dialect(getDialectNamespace(), context,
2810317da2SKareem Ergawy             ::mlir::TypeID::get<DummyDialect>()) {
2910317da2SKareem Ergawy     initialize();
3010317da2SKareem Ergawy   }
3110317da2SKareem Ergawy 
3210317da2SKareem Ergawy   void initialize();
3310317da2SKareem Ergawy   friend class ::mlir::MLIRContext;
3410317da2SKareem Ergawy 
3510317da2SKareem Ergawy public:
3610317da2SKareem Ergawy   ~DummyDialect() override = default;
3710317da2SKareem Ergawy   static constexpr ::llvm::StringLiteral getDialectNamespace() {
3810317da2SKareem Ergawy     return ::llvm::StringLiteral("dummy");
3910317da2SKareem Ergawy   }
4010317da2SKareem Ergawy };
4110317da2SKareem Ergawy 
4210317da2SKareem Ergawy namespace dummy {
4310317da2SKareem Ergawy class FakeOp : public ::mlir::Op<FakeOp> {
4410317da2SKareem Ergawy public:
4510317da2SKareem Ergawy   using Op::Op;
4610317da2SKareem Ergawy 
4710317da2SKareem Ergawy   static llvm::StringRef getOperationName() { return "dummy.fake"; }
4810317da2SKareem Ergawy 
4910317da2SKareem Ergawy   static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { return {}; }
5010317da2SKareem Ergawy 
5110317da2SKareem Ergawy   static void build(
5210317da2SKareem Ergawy       ::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState) {}
5310317da2SKareem Ergawy };
5410317da2SKareem Ergawy } // namespace dummy
5510317da2SKareem Ergawy } // namespace test
5610317da2SKareem Ergawy 
5710317da2SKareem Ergawy MLIR_DECLARE_EXPLICIT_TYPE_ID(::test::DummyDialect)
5810317da2SKareem Ergawy MLIR_DEFINE_EXPLICIT_TYPE_ID(::test::DummyDialect)
5910317da2SKareem Ergawy 
6010317da2SKareem Ergawy namespace test {
6110317da2SKareem Ergawy 
6210317da2SKareem Ergawy void DummyDialect::initialize() { addOperations<::test::dummy::FakeOp>(); }
6310317da2SKareem Ergawy } // namespace test
6410317da2SKareem Ergawy 
6510317da2SKareem Ergawy // A test CodeGenAction to verify that we gracefully handle failure to convert
6610317da2SKareem Ergawy // from MLIR to LLVM IR.
6710317da2SKareem Ergawy class LLVMConversionFailureCodeGenAction : public CodeGenAction {
6810317da2SKareem Ergawy public:
6910317da2SKareem Ergawy   LLVMConversionFailureCodeGenAction()
7010317da2SKareem Ergawy       : CodeGenAction(BackendActionTy::Backend_EmitLL) {
7110317da2SKareem Ergawy     mlirCtx = std::make_unique<mlir::MLIRContext>();
7210317da2SKareem Ergawy     mlirCtx->loadDialect<test::DummyDialect>();
7310317da2SKareem Ergawy 
7410317da2SKareem Ergawy     mlir::Location loc(mlir::UnknownLoc::get(mlirCtx.get()));
75*c870632eSMatthias Springer     mlirModule = mlir::ModuleOp::create(loc, "mod");
7610317da2SKareem Ergawy 
7710317da2SKareem Ergawy     mlir::OpBuilder builder(mlirCtx.get());
7810317da2SKareem Ergawy     builder.setInsertionPointToStart(&mlirModule->getRegion().front());
7910317da2SKareem Ergawy     // Create a fake op to trip conversion to LLVM.
8010317da2SKareem Ergawy     builder.create<test::dummy::FakeOp>(loc);
8110317da2SKareem Ergawy 
8210317da2SKareem Ergawy     llvmCtx = std::make_unique<llvm::LLVMContext>();
8310317da2SKareem Ergawy   }
8410317da2SKareem Ergawy };
8510317da2SKareem Ergawy 
8610317da2SKareem Ergawy TEST(CodeGenAction, GracefullyHandleLLVMConversionFailure) {
8710317da2SKareem Ergawy   std::string diagnosticOutput;
8810317da2SKareem Ergawy   llvm::raw_string_ostream diagnosticsOS(diagnosticOutput);
8910317da2SKareem Ergawy   auto diagPrinter = std::make_unique<Fortran::frontend::TextDiagnosticPrinter>(
9010317da2SKareem Ergawy       diagnosticsOS, new clang::DiagnosticOptions());
9110317da2SKareem Ergawy 
9210317da2SKareem Ergawy   CompilerInstance ci;
9310317da2SKareem Ergawy   ci.createDiagnostics(diagPrinter.get(), /*ShouldOwnClient=*/false);
9410317da2SKareem Ergawy   ci.setInvocation(std::make_shared<CompilerInvocation>());
9510317da2SKareem Ergawy   ci.setOutputStream(std::make_unique<llvm::raw_null_ostream>());
9610317da2SKareem Ergawy   ci.getInvocation().getCodeGenOpts().OptimizationLevel = 0;
9710317da2SKareem Ergawy 
9810317da2SKareem Ergawy   FrontendInputFile file("/dev/null", InputKind());
9910317da2SKareem Ergawy 
10010317da2SKareem Ergawy   LLVMConversionFailureCodeGenAction action;
10110317da2SKareem Ergawy   action.setInstance(&ci);
10210317da2SKareem Ergawy   action.setCurrentInput(file);
10310317da2SKareem Ergawy 
10410317da2SKareem Ergawy   consumeError(action.execute());
105d5dd7d23SYoungsuk Kim   ASSERT_EQ(diagnosticOutput,
10610317da2SKareem Ergawy       "error: Lowering to LLVM IR failed\n"
10710317da2SKareem Ergawy       "error: failed to create the LLVM module\n");
10810317da2SKareem Ergawy }
109