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