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 if (!TestPrinter) 35 GTEST_SKIP(); 36 } 37 38 dwarf::Form Form; 39 unsigned Size; 40 std::unique_ptr<TestAsmPrinter> TestPrinter; 41 }; 42 43 struct DIEExprFixture : public DIEFixtureBase { 44 void SetUp() override { 45 DIEFixtureBase::SetUp(); 46 if (!TestPrinter) 47 return; 48 49 Val = MCConstantExpr::create(42, TestPrinter->getCtx()); 50 } 51 52 const MCExpr *Val = nullptr; 53 }; 54 55 TEST_P(DIEExprFixture, SizeOf) { 56 DIEExpr Tst(Val); 57 EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); 58 } 59 60 TEST_P(DIEExprFixture, EmitValue) { 61 DIEExpr Tst(Val); 62 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(Val, Size, _)); 63 Tst.emitValue(TestPrinter->getAP(), Form); 64 } 65 66 INSTANTIATE_TEST_SUITE_P( 67 DIETestParams, DIEExprFixture, 68 testing::Values( 69 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 70 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, 71 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 72 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, 73 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 74 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u})); 75 76 struct DIELabelFixture : public DIEFixtureBase { 77 void SetUp() override { 78 DIEFixtureBase::SetUp(); 79 if (!TestPrinter) 80 return; 81 82 Val = TestPrinter->getCtx().createTempSymbol(); 83 } 84 85 const MCSymbol *Val = nullptr; 86 }; 87 88 TEST_P(DIELabelFixture, SizeOf) { 89 DIELabel Tst(Val); 90 EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); 91 } 92 93 TEST_P(DIELabelFixture, EmitValue) { 94 DIELabel Tst(Val); 95 96 const MCExpr *Arg0 = nullptr; 97 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, Size, _)) 98 .WillOnce(SaveArg<0>(&Arg0)); 99 Tst.emitValue(TestPrinter->getAP(), Form); 100 101 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 102 ASSERT_NE(ActualArg0, nullptr); 103 EXPECT_EQ(&(ActualArg0->getSymbol()), Val); 104 } 105 106 INSTANTIATE_TEST_SUITE_P( 107 DIETestParams, DIELabelFixture, 108 testing::Values( 109 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 110 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, 111 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 112 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_strp, 4u}, 113 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_addr, 8u}, 114 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, 115 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 116 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}, 117 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_strp, 8u}, 118 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_addr, 8u})); 119 120 struct DIEDeltaFixture : public DIEFixtureBase { 121 void SetUp() override { 122 DIEFixtureBase::SetUp(); 123 if (!TestPrinter) 124 return; 125 126 Hi = TestPrinter->getCtx().createTempSymbol(); 127 Lo = TestPrinter->getCtx().createTempSymbol(); 128 } 129 130 const MCSymbol *Hi = nullptr; 131 const MCSymbol *Lo = nullptr; 132 }; 133 134 TEST_P(DIEDeltaFixture, SizeOf) { 135 DIEDelta Tst(Hi, Lo); 136 EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); 137 } 138 139 TEST_P(DIEDeltaFixture, EmitValue) { 140 DIEDelta Tst(Hi, Lo); 141 EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, Size)); 142 Tst.emitValue(TestPrinter->getAP(), Form); 143 } 144 145 INSTANTIATE_TEST_SUITE_P( 146 DIETestParams, DIEDeltaFixture, 147 testing::Values( 148 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 149 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u}, 150 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 151 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u}, 152 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 153 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u})); 154 155 struct DIELocListFixture : public DIEFixtureBase { 156 void SetUp() override { DIEFixtureBase::SetUp(); } 157 }; 158 159 TEST_P(DIELocListFixture, SizeOf) { 160 DIELocList Tst(999); 161 EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form)); 162 } 163 164 INSTANTIATE_TEST_SUITE_P( 165 DIETestParams, DIELocListFixture, 166 testing::Values( 167 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_loclistx, 2u}, 168 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u}, 169 DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u}, 170 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_loclistx, 2u}, 171 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u}, 172 DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u})); 173 174 } // end namespace 175