[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / CodeGen / AsmPrinterDwarfTest.cpp
blobb900e34fdd634d046af6cc0ea63ccde01a1f5c4d
1 //===- llvm/unittest/CodeGen/AsmPrinterDwarfTest.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 //===----------------------------------------------------------------------===//
9 #include "TestAsmPrinter.h"
10 #include "llvm/BinaryFormat/ELF.h"
11 #include "llvm/CodeGen/AsmPrinter.h"
12 #include "llvm/CodeGen/MachineModuleInfo.h"
13 #include "llvm/IR/LegacyPassManager.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/IR/PassManager.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCSectionELF.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Testing/Support/Error.h"
21 using namespace llvm;
22 using testing::_;
23 using testing::InSequence;
24 using testing::SaveArg;
26 namespace {
28 class AsmPrinterFixtureBase : public testing::Test {
29 void setupTestPrinter(const std::string &TripleStr, unsigned DwarfVersion,
30 dwarf::DwarfFormat DwarfFormat) {
31 auto ExpectedTestPrinter =
32 TestAsmPrinter::create(TripleStr, DwarfVersion, DwarfFormat);
33 ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());
34 TestPrinter = std::move(ExpectedTestPrinter.get());
37 protected:
38 bool init(const std::string &TripleStr, unsigned DwarfVersion,
39 dwarf::DwarfFormat DwarfFormat) {
40 setupTestPrinter(TripleStr, DwarfVersion, DwarfFormat);
41 return TestPrinter != nullptr;
44 std::unique_ptr<TestAsmPrinter> TestPrinter;
47 class AsmPrinterEmitDwarfSymbolReferenceTest : public AsmPrinterFixtureBase {
48 protected:
49 bool init(const std::string &TripleStr, unsigned DwarfVersion,
50 dwarf::DwarfFormat DwarfFormat) {
51 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
52 return false;
54 // AsmPrinter::emitDwarfSymbolReference(Label, true) gets the associated
55 // section from `Label` to find its BeginSymbol.
56 // Prepare the test symbol `Val` accordingly.
58 Val = TestPrinter->getCtx().createTempSymbol();
59 MCSection *Sec =
60 TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0);
61 SecBeginSymbol = Sec->getBeginSymbol();
62 TestPrinter->getMS().switchSection(Sec);
63 Val->setFragment(&Sec->getDummyFragment());
65 return true;
68 MCSymbol *Val = nullptr;
69 MCSymbol *SecBeginSymbol = nullptr;
72 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFF) {
73 if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))
74 GTEST_SKIP();
76 EXPECT_CALL(TestPrinter->getMS(), emitCOFFSecRel32(Val, 0));
77 TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
80 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFFForceOffset) {
81 if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))
82 GTEST_SKIP();
84 EXPECT_CALL(TestPrinter->getMS(),
85 emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));
86 TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
89 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32) {
90 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
91 GTEST_SKIP();
93 const MCExpr *Arg0 = nullptr;
94 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
95 .WillOnce(SaveArg<0>(&Arg0));
96 TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
98 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
99 ASSERT_NE(ActualArg0, nullptr);
100 EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
103 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32ForceOffset) {
104 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
105 GTEST_SKIP();
107 EXPECT_CALL(TestPrinter->getMS(),
108 emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));
109 TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
112 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64) {
113 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
114 GTEST_SKIP();
116 const MCExpr *Arg0 = nullptr;
117 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
118 .WillOnce(SaveArg<0>(&Arg0));
119 TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
121 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
122 ASSERT_NE(ActualArg0, nullptr);
123 EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
126 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64ForceOffset) {
127 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
128 GTEST_SKIP();
130 EXPECT_CALL(TestPrinter->getMS(),
131 emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 8));
132 TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
135 class AsmPrinterEmitDwarfStringOffsetTest : public AsmPrinterFixtureBase {
136 protected:
137 bool init(const std::string &TripleStr, unsigned DwarfVersion,
138 dwarf::DwarfFormat DwarfFormat) {
139 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
140 return false;
142 Val.Index = DwarfStringPoolEntry::NotIndexed;
143 Val.Symbol = TestPrinter->getCtx().createTempSymbol();
144 Val.Offset = 42;
145 return true;
148 DwarfStringPoolEntry Val;
151 TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF32) {
152 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
153 GTEST_SKIP();
155 const MCExpr *Arg0 = nullptr;
156 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
157 .WillOnce(SaveArg<0>(&Arg0));
158 TestPrinter->getAP()->emitDwarfStringOffset(Val);
160 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
161 ASSERT_NE(ActualArg0, nullptr);
162 EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);
165 TEST_F(AsmPrinterEmitDwarfStringOffsetTest,
166 DWARF32NoRelocationsAcrossSections) {
167 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
168 GTEST_SKIP();
170 TestPrinter->setDwarfUsesRelocationsAcrossSections(false);
171 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 4));
172 TestPrinter->getAP()->emitDwarfStringOffset(Val);
175 TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF64) {
176 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
177 GTEST_SKIP();
179 const MCExpr *Arg0 = nullptr;
180 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
181 .WillOnce(SaveArg<0>(&Arg0));
182 TestPrinter->getAP()->emitDwarfStringOffset(Val);
184 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
185 ASSERT_NE(ActualArg0, nullptr);
186 EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);
189 TEST_F(AsmPrinterEmitDwarfStringOffsetTest,
190 DWARF64NoRelocationsAcrossSections) {
191 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
192 GTEST_SKIP();
194 TestPrinter->setDwarfUsesRelocationsAcrossSections(false);
195 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 8));
196 TestPrinter->getAP()->emitDwarfStringOffset(Val);
199 class AsmPrinterEmitDwarfOffsetTest : public AsmPrinterFixtureBase {
200 protected:
201 bool init(const std::string &TripleStr, unsigned DwarfVersion,
202 dwarf::DwarfFormat DwarfFormat) {
203 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
204 return false;
206 Label = TestPrinter->getCtx().createTempSymbol();
207 return true;
210 MCSymbol *Label = nullptr;
211 uint64_t Offset = 42;
214 TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF32) {
215 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
216 GTEST_SKIP();
218 const MCExpr *Arg0 = nullptr;
219 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
220 .WillOnce(SaveArg<0>(&Arg0));
221 TestPrinter->getAP()->emitDwarfOffset(Label, Offset);
223 const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);
224 ASSERT_NE(ActualArg0, nullptr);
225 EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);
227 const MCSymbolRefExpr *ActualLHS =
228 dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());
229 ASSERT_NE(ActualLHS, nullptr);
230 EXPECT_EQ(&(ActualLHS->getSymbol()), Label);
232 const MCConstantExpr *ActualRHS =
233 dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());
234 ASSERT_NE(ActualRHS, nullptr);
235 EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);
238 TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF64) {
239 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
240 GTEST_SKIP();
242 const MCExpr *Arg0 = nullptr;
243 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
244 .WillOnce(SaveArg<0>(&Arg0));
245 TestPrinter->getAP()->emitDwarfOffset(Label, Offset);
247 const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);
248 ASSERT_NE(ActualArg0, nullptr);
249 EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);
251 const MCSymbolRefExpr *ActualLHS =
252 dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());
253 ASSERT_NE(ActualLHS, nullptr);
254 EXPECT_EQ(&(ActualLHS->getSymbol()), Label);
256 const MCConstantExpr *ActualRHS =
257 dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());
258 ASSERT_NE(ActualRHS, nullptr);
259 EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);
262 class AsmPrinterEmitDwarfLengthOrOffsetTest : public AsmPrinterFixtureBase {
263 protected:
264 uint64_t Val = 42;
267 TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF32) {
268 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
269 GTEST_SKIP();
271 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));
272 TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);
275 TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF64) {
276 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
277 GTEST_SKIP();
279 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));
280 TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);
283 class AsmPrinterGetUnitLengthFieldByteSizeTest : public AsmPrinterFixtureBase {
286 TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF32) {
287 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
288 GTEST_SKIP();
290 EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 4u);
293 TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF64) {
294 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
295 GTEST_SKIP();
297 EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 12u);
300 class AsmPrinterEmitDwarfUnitLengthAsIntTest : public AsmPrinterFixtureBase {
301 protected:
302 uint64_t Val = 42;
305 TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF32) {
306 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
307 GTEST_SKIP();
309 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));
310 TestPrinter->getAP()->emitDwarfUnitLength(Val, "");
313 TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF64) {
314 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
315 GTEST_SKIP();
317 InSequence S;
318 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
319 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));
321 TestPrinter->getAP()->emitDwarfUnitLength(Val, "");
324 class AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest
325 : public AsmPrinterFixtureBase {
326 protected:
327 bool init(const std::string &TripleStr, unsigned DwarfVersion,
328 dwarf::DwarfFormat DwarfFormat) {
329 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
330 return false;
332 return true;
336 TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF32) {
337 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
338 GTEST_SKIP();
340 InSequence S;
341 const MCSymbol *Hi = nullptr;
342 const MCSymbol *Lo = nullptr;
343 EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 4))
344 .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo)));
345 MCSymbol *LTmp = nullptr;
346 EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _))
347 .WillOnce(SaveArg<0>(&LTmp));
349 MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", "");
350 EXPECT_NE(Lo, nullptr);
351 EXPECT_EQ(Lo, LTmp);
352 EXPECT_NE(Hi, nullptr);
353 EXPECT_EQ(Hi, HTmp);
356 TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF64) {
357 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
358 GTEST_SKIP();
360 InSequence S;
361 const MCSymbol *Hi = nullptr;
362 const MCSymbol *Lo = nullptr;
363 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
364 EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 8))
365 .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo)));
366 MCSymbol *LTmp = nullptr;
367 EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _))
368 .WillOnce(SaveArg<0>(&LTmp));
370 MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", "");
371 EXPECT_NE(Lo, nullptr);
372 EXPECT_EQ(Lo, LTmp);
373 EXPECT_NE(Hi, nullptr);
374 EXPECT_EQ(Hi, HTmp);
377 class AsmPrinterHandlerTest : public AsmPrinterFixtureBase {
378 class TestHandler : public AsmPrinterHandler {
379 AsmPrinterHandlerTest &Test;
381 public:
382 TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {}
383 virtual ~TestHandler() {}
384 virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
385 virtual void beginModule(Module *M) override { Test.BeginCount++; }
386 virtual void endModule() override { Test.EndCount++; }
387 virtual void beginFunction(const MachineFunction *MF) override {}
388 virtual void endFunction(const MachineFunction *MF) override {}
389 virtual void beginInstruction(const MachineInstr *MI) override {}
390 virtual void endInstruction() override {}
393 protected:
394 bool init(const std::string &TripleStr, unsigned DwarfVersion,
395 dwarf::DwarfFormat DwarfFormat) {
396 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
397 return false;
399 auto *AP = TestPrinter->getAP();
400 AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo(
401 std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)),
402 "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc"));
403 LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(&AP->TM);
404 legacy::PassManager PM;
405 PM.add(new MachineModuleInfoWrapperPass(LLVMTM));
406 PM.add(TestPrinter->releaseAP()); // Takes ownership of destroying AP
407 LLVMContext Context;
408 std::unique_ptr<Module> M(new Module("TestModule", Context));
409 M->setDataLayout(LLVMTM->createDataLayout());
410 PM.run(*M);
411 // Now check that we can run it twice.
412 AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo(
413 std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)),
414 "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc"));
415 PM.run(*M);
416 return true;
419 int BeginCount = 0;
420 int EndCount = 0;
423 TEST_F(AsmPrinterHandlerTest, Basic) {
424 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
425 GTEST_SKIP();
427 ASSERT_EQ(BeginCount, 3);
428 ASSERT_EQ(EndCount, 3);
431 } // end namespace