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