//===- llvm/unittest/CodeGen/DIETest.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/DIE.h" #include "TestAsmPrinter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/Testing/Support/Error.h" using namespace llvm; using testing::_; using testing::SaveArg; namespace { using DIETestParams = std::tuple; class DIEFixtureBase : public testing::TestWithParam { protected: void SetUp() override { unsigned Version; dwarf::DwarfFormat Format; std::tie(Version, Format, Form, Size) = GetParam(); auto ExpectedTestPrinter = TestAsmPrinter::create("x86_64-pc-linux", Version, Format); ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded()); TestPrinter = std::move(ExpectedTestPrinter.get()); } dwarf::Form Form; unsigned Size; std::unique_ptr TestPrinter; }; struct DIEExprFixture : public DIEFixtureBase { void SetUp() override { DIEFixtureBase::SetUp(); if (!TestPrinter) return; Val = MCConstantExpr::create(42, TestPrinter->getCtx()); } const MCExpr *Val = nullptr; }; TEST_P(DIEExprFixture, SizeOf) { if (!TestPrinter) return; DIEExpr Tst(Val); EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); } TEST_P(DIEExprFixture, EmitValue) { if (!TestPrinter) return; DIEExpr Tst(Val); EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(Val, Size, _)); Tst.emitValue(TestPrinter->getAP(), Form); } INSTANTIATE_TEST_CASE_P( DIETestParams, DIEExprFixture, testing::Values( DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}), ); struct DIELabelFixture : public DIEFixtureBase { void SetUp() override { DIEFixtureBase::SetUp(); if (!TestPrinter) return; Val = TestPrinter->getCtx().createTempSymbol(); } const MCSymbol *Val = nullptr; }; TEST_P(DIELabelFixture, SizeOf) { if (!TestPrinter) return; DIELabel Tst(Val); EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); } TEST_P(DIELabelFixture, EmitValue) { if (!TestPrinter) return; DIELabel Tst(Val); const MCExpr *Arg0 = nullptr; EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, Size, _)) .WillOnce(SaveArg<0>(&Arg0)); Tst.emitValue(TestPrinter->getAP(), Form); const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null(Arg0); ASSERT_NE(ActualArg0, nullptr); EXPECT_EQ(&(ActualArg0->getSymbol()), Val); } INSTANTIATE_TEST_CASE_P( DIETestParams, DIELabelFixture, testing::Values( DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_strp, 4u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_addr, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_strp, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_addr, 8u}), ); struct DIEDeltaFixture : public DIEFixtureBase { void SetUp() override { DIEFixtureBase::SetUp(); if (!TestPrinter) return; Hi = TestPrinter->getCtx().createTempSymbol(); Lo = TestPrinter->getCtx().createTempSymbol(); } const MCSymbol *Hi = nullptr; const MCSymbol *Lo = nullptr; }; TEST_P(DIEDeltaFixture, SizeOf) { if (!TestPrinter) return; DIEDelta Tst(Hi, Lo); EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); } TEST_P(DIEDeltaFixture, EmitValue) { if (!TestPrinter) return; DIEDelta Tst(Hi, Lo); EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, Size)); Tst.emitValue(TestPrinter->getAP(), Form); } INSTANTIATE_TEST_CASE_P( DIETestParams, DIEDeltaFixture, testing::Values( DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}), ); struct DIELocListFixture : public DIEFixtureBase { void SetUp() override { DIEFixtureBase::SetUp(); } }; TEST_P(DIELocListFixture, SizeOf) { if (!TestPrinter) return; DIELocList Tst(999); EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); } INSTANTIATE_TEST_CASE_P( DIETestParams, DIELocListFixture, testing::Values( DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_loclistx, 2u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_loclistx, 2u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}), ); } // end namespace