1380e746bSIgor Kudrin //===- llvm/unittest/CodeGen/AsmPrinterDwarfTest.cpp ----------------------===//
2380e746bSIgor Kudrin //
3380e746bSIgor Kudrin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4380e746bSIgor Kudrin // See https://llvm.org/LICENSE.txt for license information.
5380e746bSIgor Kudrin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6380e746bSIgor Kudrin //
7380e746bSIgor Kudrin //===----------------------------------------------------------------------===//
8380e746bSIgor Kudrin 
9380e746bSIgor Kudrin #include "TestAsmPrinter.h"
10380e746bSIgor Kudrin #include "llvm/CodeGen/AsmPrinter.h"
11*a0ad066cSJameson Nash #include "llvm/CodeGen/MachineModuleInfo.h"
12*a0ad066cSJameson Nash #include "llvm/IR/LegacyPassManager.h"
13*a0ad066cSJameson Nash #include "llvm/IR/Module.h"
14*a0ad066cSJameson Nash #include "llvm/IR/PassManager.h"
15380e746bSIgor Kudrin #include "llvm/MC/MCContext.h"
16380e746bSIgor Kudrin #include "llvm/MC/MCSectionELF.h"
17*a0ad066cSJameson Nash #include "llvm/Target/TargetMachine.h"
18380e746bSIgor Kudrin #include "llvm/Testing/Support/Error.h"
19380e746bSIgor Kudrin 
20380e746bSIgor Kudrin using namespace llvm;
21380e746bSIgor Kudrin using testing::_;
22c3c501f5SIgor Kudrin using testing::InSequence;
23380e746bSIgor Kudrin using testing::SaveArg;
24380e746bSIgor Kudrin 
25380e746bSIgor Kudrin namespace {
26380e746bSIgor Kudrin 
27380e746bSIgor Kudrin class AsmPrinterFixtureBase : public testing::Test {
28380e746bSIgor Kudrin   void setupTestPrinter(const std::string &TripleStr, unsigned DwarfVersion,
29380e746bSIgor Kudrin                         dwarf::DwarfFormat DwarfFormat) {
30380e746bSIgor Kudrin     auto ExpectedTestPrinter =
31380e746bSIgor Kudrin         TestAsmPrinter::create(TripleStr, DwarfVersion, DwarfFormat);
32380e746bSIgor Kudrin     ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());
33380e746bSIgor Kudrin     TestPrinter = std::move(ExpectedTestPrinter.get());
34380e746bSIgor Kudrin   }
35380e746bSIgor Kudrin 
36380e746bSIgor Kudrin protected:
37380e746bSIgor Kudrin   bool init(const std::string &TripleStr, unsigned DwarfVersion,
38380e746bSIgor Kudrin             dwarf::DwarfFormat DwarfFormat) {
39380e746bSIgor Kudrin     setupTestPrinter(TripleStr, DwarfVersion, DwarfFormat);
40380e746bSIgor Kudrin     return TestPrinter != nullptr;
41380e746bSIgor Kudrin   }
42380e746bSIgor Kudrin 
43380e746bSIgor Kudrin   std::unique_ptr<TestAsmPrinter> TestPrinter;
44380e746bSIgor Kudrin };
45380e746bSIgor Kudrin 
46380e746bSIgor Kudrin class AsmPrinterEmitDwarfSymbolReferenceTest : public AsmPrinterFixtureBase {
47380e746bSIgor Kudrin protected:
48380e746bSIgor Kudrin   bool init(const std::string &TripleStr, unsigned DwarfVersion,
49380e746bSIgor Kudrin             dwarf::DwarfFormat DwarfFormat) {
50380e746bSIgor Kudrin     if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
51380e746bSIgor Kudrin       return false;
52380e746bSIgor Kudrin 
53380e746bSIgor Kudrin     // Create a symbol which will be emitted in the tests and associate it
54380e746bSIgor Kudrin     // with a section because that is required in some code paths.
55380e746bSIgor Kudrin 
56380e746bSIgor Kudrin     Val = TestPrinter->getCtx().createTempSymbol();
57380e746bSIgor Kudrin     Sec = TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0);
58380e746bSIgor Kudrin     SecBeginSymbol = Sec->getBeginSymbol();
59380e746bSIgor Kudrin     TestPrinter->getMS().SwitchSection(Sec);
60380e746bSIgor Kudrin     TestPrinter->getMS().emitLabel(Val);
61380e746bSIgor Kudrin     return true;
62380e746bSIgor Kudrin   }
63380e746bSIgor Kudrin 
64380e746bSIgor Kudrin   MCSymbol *Val = nullptr;
65380e746bSIgor Kudrin   MCSection *Sec = nullptr;
66380e746bSIgor Kudrin   MCSymbol *SecBeginSymbol = nullptr;
67380e746bSIgor Kudrin };
68380e746bSIgor Kudrin 
69380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFF) {
70380e746bSIgor Kudrin   if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))
71380e746bSIgor Kudrin     return;
72380e746bSIgor Kudrin 
73380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), EmitCOFFSecRel32(Val, 0));
74380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
75380e746bSIgor Kudrin }
76380e746bSIgor Kudrin 
77380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFFForceOffset) {
78380e746bSIgor Kudrin   if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))
79380e746bSIgor Kudrin     return;
80380e746bSIgor Kudrin 
81380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(),
82380e746bSIgor Kudrin               emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));
83380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
84380e746bSIgor Kudrin }
85380e746bSIgor Kudrin 
86380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32) {
87380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
88380e746bSIgor Kudrin     return;
89380e746bSIgor Kudrin 
90380e746bSIgor Kudrin   const MCExpr *Arg0 = nullptr;
91380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
92380e746bSIgor Kudrin       .WillOnce(SaveArg<0>(&Arg0));
93380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
94380e746bSIgor Kudrin 
95380e746bSIgor Kudrin   const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
96380e746bSIgor Kudrin   ASSERT_NE(ActualArg0, nullptr);
97380e746bSIgor Kudrin   EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
98380e746bSIgor Kudrin }
99380e746bSIgor Kudrin 
100380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32ForceOffset) {
101380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
102380e746bSIgor Kudrin     return;
103380e746bSIgor Kudrin 
104380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(),
105380e746bSIgor Kudrin               emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));
106380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
107380e746bSIgor Kudrin }
108380e746bSIgor Kudrin 
109380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64) {
110380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
111380e746bSIgor Kudrin     return;
112380e746bSIgor Kudrin 
113380e746bSIgor Kudrin   const MCExpr *Arg0 = nullptr;
114380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
115380e746bSIgor Kudrin       .WillOnce(SaveArg<0>(&Arg0));
116380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
117380e746bSIgor Kudrin 
118380e746bSIgor Kudrin   const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
119380e746bSIgor Kudrin   ASSERT_NE(ActualArg0, nullptr);
120380e746bSIgor Kudrin   EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
121380e746bSIgor Kudrin }
122380e746bSIgor Kudrin 
123380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64ForceOffset) {
124380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
125380e746bSIgor Kudrin     return;
126380e746bSIgor Kudrin 
127380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(),
128380e746bSIgor Kudrin               emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 8));
129380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
130380e746bSIgor Kudrin }
131380e746bSIgor Kudrin 
132380e746bSIgor Kudrin class AsmPrinterEmitDwarfStringOffsetTest : public AsmPrinterFixtureBase {
133380e746bSIgor Kudrin protected:
134380e746bSIgor Kudrin   bool init(const std::string &TripleStr, unsigned DwarfVersion,
135380e746bSIgor Kudrin             dwarf::DwarfFormat DwarfFormat) {
136380e746bSIgor Kudrin     if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
137380e746bSIgor Kudrin       return false;
138380e746bSIgor Kudrin 
139380e746bSIgor Kudrin     Val.Index = DwarfStringPoolEntry::NotIndexed;
140380e746bSIgor Kudrin     Val.Symbol = TestPrinter->getCtx().createTempSymbol();
141380e746bSIgor Kudrin     Val.Offset = 42;
142380e746bSIgor Kudrin     return true;
143380e746bSIgor Kudrin   }
144380e746bSIgor Kudrin 
145380e746bSIgor Kudrin   DwarfStringPoolEntry Val;
146380e746bSIgor Kudrin };
147380e746bSIgor Kudrin 
148380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF32) {
149380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
150380e746bSIgor Kudrin     return;
151380e746bSIgor Kudrin 
152380e746bSIgor Kudrin   const MCExpr *Arg0 = nullptr;
153380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
154380e746bSIgor Kudrin       .WillOnce(SaveArg<0>(&Arg0));
155380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfStringOffset(Val);
156380e746bSIgor Kudrin 
157380e746bSIgor Kudrin   const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
158380e746bSIgor Kudrin   ASSERT_NE(ActualArg0, nullptr);
159380e746bSIgor Kudrin   EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);
160380e746bSIgor Kudrin }
161380e746bSIgor Kudrin 
162380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest,
163380e746bSIgor Kudrin        DWARF32NoRelocationsAcrossSections) {
164380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
165380e746bSIgor Kudrin     return;
166380e746bSIgor Kudrin 
167380e746bSIgor Kudrin   TestPrinter->setDwarfUsesRelocationsAcrossSections(false);
168380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 4));
169380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfStringOffset(Val);
170380e746bSIgor Kudrin }
171380e746bSIgor Kudrin 
172380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF64) {
173380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
174380e746bSIgor Kudrin     return;
175380e746bSIgor Kudrin 
176380e746bSIgor Kudrin   const MCExpr *Arg0 = nullptr;
177380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
178380e746bSIgor Kudrin       .WillOnce(SaveArg<0>(&Arg0));
179380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfStringOffset(Val);
180380e746bSIgor Kudrin 
181380e746bSIgor Kudrin   const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
182380e746bSIgor Kudrin   ASSERT_NE(ActualArg0, nullptr);
183380e746bSIgor Kudrin   EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);
184380e746bSIgor Kudrin }
185380e746bSIgor Kudrin 
186380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest,
187380e746bSIgor Kudrin        DWARF64NoRelocationsAcrossSections) {
188380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
189380e746bSIgor Kudrin     return;
190380e746bSIgor Kudrin 
191380e746bSIgor Kudrin   TestPrinter->setDwarfUsesRelocationsAcrossSections(false);
192380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 8));
193380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfStringOffset(Val);
194380e746bSIgor Kudrin }
195380e746bSIgor Kudrin 
196380e746bSIgor Kudrin class AsmPrinterEmitDwarfOffsetTest : public AsmPrinterFixtureBase {
197380e746bSIgor Kudrin protected:
198380e746bSIgor Kudrin   bool init(const std::string &TripleStr, unsigned DwarfVersion,
199380e746bSIgor Kudrin             dwarf::DwarfFormat DwarfFormat) {
200380e746bSIgor Kudrin     if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
201380e746bSIgor Kudrin       return false;
202380e746bSIgor Kudrin 
203380e746bSIgor Kudrin     Label = TestPrinter->getCtx().createTempSymbol();
204380e746bSIgor Kudrin     return true;
205380e746bSIgor Kudrin   }
206380e746bSIgor Kudrin 
207380e746bSIgor Kudrin   MCSymbol *Label = nullptr;
208380e746bSIgor Kudrin   uint64_t Offset = 42;
209380e746bSIgor Kudrin };
210380e746bSIgor Kudrin 
211380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF32) {
212380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
213380e746bSIgor Kudrin     return;
214380e746bSIgor Kudrin 
215380e746bSIgor Kudrin   const MCExpr *Arg0 = nullptr;
216380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
217380e746bSIgor Kudrin       .WillOnce(SaveArg<0>(&Arg0));
218380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfOffset(Label, Offset);
219380e746bSIgor Kudrin 
220380e746bSIgor Kudrin   const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);
221380e746bSIgor Kudrin   ASSERT_NE(ActualArg0, nullptr);
222380e746bSIgor Kudrin   EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);
223380e746bSIgor Kudrin 
224380e746bSIgor Kudrin   const MCSymbolRefExpr *ActualLHS =
225380e746bSIgor Kudrin       dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());
226380e746bSIgor Kudrin   ASSERT_NE(ActualLHS, nullptr);
227380e746bSIgor Kudrin   EXPECT_EQ(&(ActualLHS->getSymbol()), Label);
228380e746bSIgor Kudrin 
229380e746bSIgor Kudrin   const MCConstantExpr *ActualRHS =
230380e746bSIgor Kudrin       dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());
231380e746bSIgor Kudrin   ASSERT_NE(ActualRHS, nullptr);
232380e746bSIgor Kudrin   EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);
233380e746bSIgor Kudrin }
234380e746bSIgor Kudrin 
235380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF64) {
236380e746bSIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
237380e746bSIgor Kudrin     return;
238380e746bSIgor Kudrin 
239380e746bSIgor Kudrin   const MCExpr *Arg0 = nullptr;
240380e746bSIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
241380e746bSIgor Kudrin       .WillOnce(SaveArg<0>(&Arg0));
242380e746bSIgor Kudrin   TestPrinter->getAP()->emitDwarfOffset(Label, Offset);
243380e746bSIgor Kudrin 
244380e746bSIgor Kudrin   const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);
245380e746bSIgor Kudrin   ASSERT_NE(ActualArg0, nullptr);
246380e746bSIgor Kudrin   EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);
247380e746bSIgor Kudrin 
248380e746bSIgor Kudrin   const MCSymbolRefExpr *ActualLHS =
249380e746bSIgor Kudrin       dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());
250380e746bSIgor Kudrin   ASSERT_NE(ActualLHS, nullptr);
251380e746bSIgor Kudrin   EXPECT_EQ(&(ActualLHS->getSymbol()), Label);
252380e746bSIgor Kudrin 
253380e746bSIgor Kudrin   const MCConstantExpr *ActualRHS =
254380e746bSIgor Kudrin       dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());
255380e746bSIgor Kudrin   ASSERT_NE(ActualRHS, nullptr);
256380e746bSIgor Kudrin   EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);
257380e746bSIgor Kudrin }
258380e746bSIgor Kudrin 
259c3c501f5SIgor Kudrin class AsmPrinterEmitDwarfLengthOrOffsetTest : public AsmPrinterFixtureBase {
260c3c501f5SIgor Kudrin protected:
261c3c501f5SIgor Kudrin   uint64_t Val = 42;
262c3c501f5SIgor Kudrin };
263c3c501f5SIgor Kudrin 
264c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF32) {
265c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
266c3c501f5SIgor Kudrin     return;
267c3c501f5SIgor Kudrin 
268c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));
269c3c501f5SIgor Kudrin   TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);
270c3c501f5SIgor Kudrin }
271c3c501f5SIgor Kudrin 
272c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF64) {
273c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
274c3c501f5SIgor Kudrin     return;
275c3c501f5SIgor Kudrin 
276c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));
277c3c501f5SIgor Kudrin   TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);
278c3c501f5SIgor Kudrin }
279c3c501f5SIgor Kudrin 
280c3c501f5SIgor Kudrin class AsmPrinterGetUnitLengthFieldByteSizeTest : public AsmPrinterFixtureBase {
281c3c501f5SIgor Kudrin };
282c3c501f5SIgor Kudrin 
283c3c501f5SIgor Kudrin TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF32) {
284c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
285c3c501f5SIgor Kudrin     return;
286c3c501f5SIgor Kudrin 
287c3c501f5SIgor Kudrin   EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 4u);
288c3c501f5SIgor Kudrin }
289c3c501f5SIgor Kudrin 
290c3c501f5SIgor Kudrin TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF64) {
291c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
292c3c501f5SIgor Kudrin     return;
293c3c501f5SIgor Kudrin 
294c3c501f5SIgor Kudrin   EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 12u);
295c3c501f5SIgor Kudrin }
296c3c501f5SIgor Kudrin 
297c3c501f5SIgor Kudrin class AsmPrinterMaybeEmitDwarf64MarkTest : public AsmPrinterFixtureBase {};
298c3c501f5SIgor Kudrin 
299c3c501f5SIgor Kudrin TEST_F(AsmPrinterMaybeEmitDwarf64MarkTest, DWARF32) {
300c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
301c3c501f5SIgor Kudrin     return;
302c3c501f5SIgor Kudrin 
303c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(_, _)).Times(0);
304c3c501f5SIgor Kudrin   TestPrinter->getAP()->maybeEmitDwarf64Mark();
305c3c501f5SIgor Kudrin }
306c3c501f5SIgor Kudrin 
307c3c501f5SIgor Kudrin TEST_F(AsmPrinterMaybeEmitDwarf64MarkTest, DWARF64) {
308c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
309c3c501f5SIgor Kudrin     return;
310c3c501f5SIgor Kudrin 
311c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
312c3c501f5SIgor Kudrin   TestPrinter->getAP()->maybeEmitDwarf64Mark();
313c3c501f5SIgor Kudrin }
314c3c501f5SIgor Kudrin 
315c3c501f5SIgor Kudrin class AsmPrinterEmitDwarfUnitLengthAsIntTest : public AsmPrinterFixtureBase {
316c3c501f5SIgor Kudrin protected:
317c3c501f5SIgor Kudrin   uint64_t Val = 42;
318c3c501f5SIgor Kudrin };
319c3c501f5SIgor Kudrin 
320c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF32) {
321c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
322c3c501f5SIgor Kudrin     return;
323c3c501f5SIgor Kudrin 
324c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));
325c3c501f5SIgor Kudrin   TestPrinter->getAP()->emitDwarfUnitLength(Val, "");
326c3c501f5SIgor Kudrin }
327c3c501f5SIgor Kudrin 
328c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF64) {
329c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
330c3c501f5SIgor Kudrin     return;
331c3c501f5SIgor Kudrin 
332c3c501f5SIgor Kudrin   InSequence S;
333c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
334c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));
335c3c501f5SIgor Kudrin 
336c3c501f5SIgor Kudrin   TestPrinter->getAP()->emitDwarfUnitLength(Val, "");
337c3c501f5SIgor Kudrin }
338c3c501f5SIgor Kudrin 
339c3c501f5SIgor Kudrin class AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest
340c3c501f5SIgor Kudrin     : public AsmPrinterFixtureBase {
341c3c501f5SIgor Kudrin protected:
342c3c501f5SIgor Kudrin   bool init(const std::string &TripleStr, unsigned DwarfVersion,
343c3c501f5SIgor Kudrin             dwarf::DwarfFormat DwarfFormat) {
344c3c501f5SIgor Kudrin     if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
345c3c501f5SIgor Kudrin       return false;
346c3c501f5SIgor Kudrin 
347c3c501f5SIgor Kudrin     Hi = TestPrinter->getCtx().createTempSymbol();
348c3c501f5SIgor Kudrin     Lo = TestPrinter->getCtx().createTempSymbol();
349c3c501f5SIgor Kudrin     return true;
350c3c501f5SIgor Kudrin   }
351c3c501f5SIgor Kudrin 
352c3c501f5SIgor Kudrin   MCSymbol *Hi = nullptr;
353c3c501f5SIgor Kudrin   MCSymbol *Lo = nullptr;
354c3c501f5SIgor Kudrin };
355c3c501f5SIgor Kudrin 
356c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF32) {
357c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
358c3c501f5SIgor Kudrin     return;
359c3c501f5SIgor Kudrin 
360c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, 4));
361c3c501f5SIgor Kudrin   TestPrinter->getAP()->emitDwarfUnitLength(Hi, Lo, "");
362c3c501f5SIgor Kudrin }
363c3c501f5SIgor Kudrin 
364c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF64) {
365c3c501f5SIgor Kudrin   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
366c3c501f5SIgor Kudrin     return;
367c3c501f5SIgor Kudrin 
368c3c501f5SIgor Kudrin   InSequence S;
369c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
370c3c501f5SIgor Kudrin   EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, 8));
371c3c501f5SIgor Kudrin 
372c3c501f5SIgor Kudrin   TestPrinter->getAP()->emitDwarfUnitLength(Hi, Lo, "");
373c3c501f5SIgor Kudrin }
374c3c501f5SIgor Kudrin 
375*a0ad066cSJameson Nash class AsmPrinterHandlerTest : public AsmPrinterFixtureBase {
376*a0ad066cSJameson Nash   class TestHandler : public AsmPrinterHandler {
377*a0ad066cSJameson Nash     AsmPrinterHandlerTest &Test;
378*a0ad066cSJameson Nash 
379*a0ad066cSJameson Nash   public:
380*a0ad066cSJameson Nash     TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {}
381*a0ad066cSJameson Nash     virtual ~TestHandler() {}
382*a0ad066cSJameson Nash     virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
383*a0ad066cSJameson Nash     virtual void beginModule(Module *M) override { Test.BeginCount++; }
384*a0ad066cSJameson Nash     virtual void endModule() override { Test.EndCount++; }
385*a0ad066cSJameson Nash     virtual void beginFunction(const MachineFunction *MF) override {}
386*a0ad066cSJameson Nash     virtual void endFunction(const MachineFunction *MF) override {}
387*a0ad066cSJameson Nash     virtual void beginInstruction(const MachineInstr *MI) override {}
388*a0ad066cSJameson Nash     virtual void endInstruction() override {}
389*a0ad066cSJameson Nash   };
390*a0ad066cSJameson Nash 
391*a0ad066cSJameson Nash protected:
392*a0ad066cSJameson Nash   bool init(const std::string &TripleStr, unsigned DwarfVersion,
393*a0ad066cSJameson Nash             dwarf::DwarfFormat DwarfFormat) {
394*a0ad066cSJameson Nash     if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
395*a0ad066cSJameson Nash       return false;
396*a0ad066cSJameson Nash 
397*a0ad066cSJameson Nash     auto *AP = TestPrinter->getAP();
398*a0ad066cSJameson Nash     AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo(
399*a0ad066cSJameson Nash         std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)),
400*a0ad066cSJameson Nash         "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc"));
401*a0ad066cSJameson Nash     LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(&AP->TM);
402*a0ad066cSJameson Nash     legacy::PassManager PM;
403*a0ad066cSJameson Nash     PM.add(new MachineModuleInfoWrapperPass(LLVMTM));
404*a0ad066cSJameson Nash     PM.add(TestPrinter->releaseAP()); // Takes ownership of destroying AP
405*a0ad066cSJameson Nash     LLVMContext Context;
406*a0ad066cSJameson Nash     std::unique_ptr<Module> M(new Module("TestModule", Context));
407*a0ad066cSJameson Nash     M->setDataLayout(LLVMTM->createDataLayout());
408*a0ad066cSJameson Nash     PM.run(*M);
409*a0ad066cSJameson Nash     // Now check that we can run it twice.
410*a0ad066cSJameson Nash     AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo(
411*a0ad066cSJameson Nash         std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)),
412*a0ad066cSJameson Nash         "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc"));
413*a0ad066cSJameson Nash     PM.run(*M);
414*a0ad066cSJameson Nash     return true;
415*a0ad066cSJameson Nash   }
416*a0ad066cSJameson Nash 
417*a0ad066cSJameson Nash   int BeginCount = 0;
418*a0ad066cSJameson Nash   int EndCount = 0;
419*a0ad066cSJameson Nash };
420*a0ad066cSJameson Nash 
421*a0ad066cSJameson Nash TEST_F(AsmPrinterHandlerTest, Basic) {
422*a0ad066cSJameson Nash   if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
423*a0ad066cSJameson Nash     return;
424*a0ad066cSJameson Nash 
425*a0ad066cSJameson Nash   ASSERT_EQ(BeginCount, 3);
426*a0ad066cSJameson Nash   ASSERT_EQ(EndCount, 3);
427*a0ad066cSJameson Nash }
428*a0ad066cSJameson Nash 
429380e746bSIgor Kudrin } // end namespace
430