1 //===- llvm/unittest/CodeGen/DIETest.cpp ----------------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/CodeGen/DIE.h" 10 #include "TestAsmPrinter.h" 11 #include "llvm/CodeGen/AsmPrinter.h" 12 #include "llvm/MC/MCContext.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/Testing/Support/Error.h" 15 16 using namespace llvm; 17 using testing::_; 18 using testing::SaveArg; 19 20 namespace { 21 22 using DIETestParams = 23 std::tuple<unsigned, dwarf::DwarfFormat, dwarf::Form, unsigned>; 24 25 class DIEFixtureBase : public testing::TestWithParam<DIETestParams> { 26 protected: 27 void SetUp() override { 28 unsigned Version; 29 dwarf::DwarfFormat Format; 30 std::tie(Version, Format, Form, Size) = GetParam(); 31 auto ExpectedTestPrinter = 32 TestAsmPrinter::create("x86_64-pc-linux", Version, Format); 33 ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded()); 34 TestPrinter = std::move(ExpectedTestPrinter.get()); 35 if (!TestPrinter) 36 GTEST_SKIP(); 37 } 38 39 dwarf::Form Form; 40 unsigned Size; 41 std::unique_ptr<TestAsmPrinter> TestPrinter; 42 }; 43 44 struct DIEExprFixture : public DIEFixtureBase { 45 void SetUp() override { 46 DIEFixtureBase::SetUp(); 47 if (!TestPrinter) 48 return; 49 50 Val = MCConstantExpr::create(42, TestPrinter->getCtx()); 51 } 52 53 const MCExpr *Val = nullptr; 54 }; 55 56 TEST_P(DIEExprFixture, SizeOf) { 57 DIEExpr Tst(Val); 58 EXPECT_EQ(Size, Tst.sizeOf(TestPrinter->getAP()->getDwarfFormParams(), Form)); 59 } 60 61 TEST_P(DIEExprFixture, EmitValue) { 62 DIEExpr Tst(Val); 63 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(Val, Size, _)); 64 Tst.emitValue(TestPrinter->getAP(), Form); 65 } 66 67 INSTANTIATE_TEST_SUITE_P( 68 DIETestParams, DIEExprFixture, 69 testing::Values( 70 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 71 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, 72 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 73 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, 74 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 75 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u})); 76 77 struct DIELabelFixture : public DIEFixtureBase { 78 void SetUp() override { 79 DIEFixtureBase::SetUp(); 80 if (!TestPrinter) 81 return; 82 83 Val = TestPrinter->getCtx().createTempSymbol(); 84 } 85 86 const MCSymbol *Val = nullptr; 87 }; 88 89 TEST_P(DIELabelFixture, SizeOf) { 90 DIELabel Tst(Val); 91 EXPECT_EQ(Size, Tst.sizeOf(TestPrinter->getAP()->getDwarfFormParams(), Form)); 92 } 93 94 TEST_P(DIELabelFixture, EmitValue) { 95 DIELabel Tst(Val); 96 97 const MCExpr *Arg0 = nullptr; 98 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, Size, _)) 99 .WillOnce(SaveArg<0>(&Arg0)); 100 Tst.emitValue(TestPrinter->getAP(), Form); 101 102 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 103 ASSERT_NE(ActualArg0, nullptr); 104 EXPECT_EQ(&(ActualArg0->getSymbol()), Val); 105 } 106 107 INSTANTIATE_TEST_SUITE_P( 108 DIETestParams, DIELabelFixture, 109 testing::Values( 110 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 111 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, 112 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 113 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_strp, 4u}, 114 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_addr, 8u}, 115 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, 116 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 117 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}, 118 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_strp, 8u}, 119 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_addr, 8u})); 120 121 struct DIEDeltaFixture : public DIEFixtureBase { 122 void SetUp() override { 123 DIEFixtureBase::SetUp(); 124 if (!TestPrinter) 125 return; 126 127 Hi = TestPrinter->getCtx().createTempSymbol(); 128 Lo = TestPrinter->getCtx().createTempSymbol(); 129 } 130 131 const MCSymbol *Hi = nullptr; 132 const MCSymbol *Lo = nullptr; 133 }; 134 135 TEST_P(DIEDeltaFixture, SizeOf) { 136 DIEDelta Tst(Hi, Lo); 137 EXPECT_EQ(Size, Tst.sizeOf(TestPrinter->getAP()->getDwarfFormParams(), Form)); 138 } 139 140 TEST_P(DIEDeltaFixture, EmitValue) { 141 DIEDelta Tst(Hi, Lo); 142 EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, Size)); 143 Tst.emitValue(TestPrinter->getAP(), Form); 144 } 145 146 INSTANTIATE_TEST_SUITE_P( 147 DIETestParams, DIEDeltaFixture, 148 testing::Values( 149 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 150 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, 151 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 152 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, 153 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 154 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u})); 155 156 struct DIELocListFixture : public DIEFixtureBase { 157 void SetUp() override { DIEFixtureBase::SetUp(); } 158 }; 159 160 TEST_P(DIELocListFixture, SizeOf) { 161 DIELocList Tst(999); 162 EXPECT_EQ(Size, Tst.sizeOf(TestPrinter->getAP()->getDwarfFormParams(), Form)); 163 } 164 165 INSTANTIATE_TEST_SUITE_P( 166 DIETestParams, DIELocListFixture, 167 testing::Values( 168 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_loclistx, 2u}, 169 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 170 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 171 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_loclistx, 2u}, 172 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 173 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u})); 174 175 } // end namespace 176