brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · e606456 Raw
119 lines · cpp
1//===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Unit tests for CodeGenAction.10//11//===----------------------------------------------------------------------===//12 13#include "mlir/IR/Builders.h"14#include "flang/Frontend/CompilerInstance.h"15#include "flang/Frontend/FrontendActions.h"16#include "flang/Frontend/TextDiagnosticPrinter.h"17 18#include "gtest/gtest.h"19 20#include <memory>21 22using namespace Fortran::frontend;23 24namespace test {25class DummyDialect : public ::mlir::Dialect {26  explicit DummyDialect(::mlir::MLIRContext *context)27      : ::mlir::Dialect(getDialectNamespace(), context,28            ::mlir::TypeID::get<DummyDialect>()) {29    initialize();30  }31 32  void initialize();33  friend class ::mlir::MLIRContext;34 35public:36  ~DummyDialect() override = default;37  static constexpr ::llvm::StringLiteral getDialectNamespace() {38    return ::llvm::StringLiteral("dummy");39  }40};41 42namespace dummy {43class FakeOp : public ::mlir::Op<FakeOp> {44public:45  using Op::Op;46 47  static llvm::StringRef getOperationName() { return "dummy.fake"; }48 49  static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { return {}; }50 51  static void build(52      ::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState) {}53 54  static FakeOp create(55      ::mlir::OpBuilder &odsBuilder, ::mlir::Location location) {56    ::mlir::OperationState state(location, getOperationName());57    build(odsBuilder, state);58    auto res = ::llvm::dyn_cast<FakeOp>(odsBuilder.create(state));59    assert(res && "builder didn't return the right type");60    return res;61  }62};63} // namespace dummy64} // namespace test65 66MLIR_DECLARE_EXPLICIT_TYPE_ID(::test::DummyDialect)67MLIR_DEFINE_EXPLICIT_TYPE_ID(::test::DummyDialect)68 69namespace test {70 71void DummyDialect::initialize() { addOperations<::test::dummy::FakeOp>(); }72} // namespace test73 74// A test CodeGenAction to verify that we gracefully handle failure to convert75// from MLIR to LLVM IR.76class LLVMConversionFailureCodeGenAction : public CodeGenAction {77public:78  LLVMConversionFailureCodeGenAction()79      : CodeGenAction(BackendActionTy::Backend_EmitLL) {80    mlirCtx = std::make_unique<mlir::MLIRContext>();81    mlirCtx->loadDialect<test::DummyDialect>();82 83    mlir::Location loc(mlir::UnknownLoc::get(mlirCtx.get()));84    mlirModule = mlir::ModuleOp::create(loc, "mod");85 86    mlir::OpBuilder builder(mlirCtx.get());87    builder.setInsertionPointToStart(&mlirModule->getRegion().front());88    // Create a fake op to trip conversion to LLVM.89    test::dummy::FakeOp::create(builder, loc);90 91    llvmCtx = std::make_unique<llvm::LLVMContext>();92  }93};94 95TEST(CodeGenAction, GracefullyHandleLLVMConversionFailure) {96  std::string diagnosticOutput;97  llvm::raw_string_ostream diagnosticsOS(diagnosticOutput);98  clang::DiagnosticOptions diagOpts;99  auto diagPrinter = std::make_unique<Fortran::frontend::TextDiagnosticPrinter>(100      diagnosticsOS, diagOpts);101 102  CompilerInstance ci;103  ci.createDiagnostics(diagPrinter.get(), /*ShouldOwnClient=*/false);104  ci.setInvocation(std::make_shared<CompilerInvocation>());105  ci.setOutputStream(std::make_unique<llvm::raw_null_ostream>());106  ci.getInvocation().getCodeGenOpts().OptimizationLevel = 0;107 108  FrontendInputFile file("/dev/null", InputKind());109 110  LLVMConversionFailureCodeGenAction action;111  action.setInstance(&ci);112  action.setCurrentInput(file);113 114  consumeError(action.execute());115  ASSERT_EQ(diagnosticOutput,116      "error: Lowering to LLVM IR failed\n"117      "error: failed to create the LLVM module\n");118}119