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" 10*ef736a1cSserge-sans-paille #include "llvm/BinaryFormat/ELF.h" 11380e746bSIgor Kudrin #include "llvm/CodeGen/AsmPrinter.h" 12a0ad066cSJameson Nash #include "llvm/CodeGen/MachineModuleInfo.h" 13a0ad066cSJameson Nash #include "llvm/IR/LegacyPassManager.h" 14a0ad066cSJameson Nash #include "llvm/IR/Module.h" 15a0ad066cSJameson Nash #include "llvm/IR/PassManager.h" 16380e746bSIgor Kudrin #include "llvm/MC/MCContext.h" 17380e746bSIgor Kudrin #include "llvm/MC/MCSectionELF.h" 18a0ad066cSJameson Nash #include "llvm/Target/TargetMachine.h" 19380e746bSIgor Kudrin #include "llvm/Testing/Support/Error.h" 20380e746bSIgor Kudrin 21380e746bSIgor Kudrin using namespace llvm; 22380e746bSIgor Kudrin using testing::_; 23c3c501f5SIgor Kudrin using testing::InSequence; 24380e746bSIgor Kudrin using testing::SaveArg; 25380e746bSIgor Kudrin 26380e746bSIgor Kudrin namespace { 27380e746bSIgor Kudrin 28380e746bSIgor Kudrin class AsmPrinterFixtureBase : public testing::Test { 29380e746bSIgor Kudrin void setupTestPrinter(const std::string &TripleStr, unsigned DwarfVersion, 30380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 31380e746bSIgor Kudrin auto ExpectedTestPrinter = 32380e746bSIgor Kudrin TestAsmPrinter::create(TripleStr, DwarfVersion, DwarfFormat); 33380e746bSIgor Kudrin ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded()); 34380e746bSIgor Kudrin TestPrinter = std::move(ExpectedTestPrinter.get()); 35380e746bSIgor Kudrin } 36380e746bSIgor Kudrin 37380e746bSIgor Kudrin protected: 38380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 39380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 40380e746bSIgor Kudrin setupTestPrinter(TripleStr, DwarfVersion, DwarfFormat); 41380e746bSIgor Kudrin return TestPrinter != nullptr; 42380e746bSIgor Kudrin } 43380e746bSIgor Kudrin 44380e746bSIgor Kudrin std::unique_ptr<TestAsmPrinter> TestPrinter; 45380e746bSIgor Kudrin }; 46380e746bSIgor Kudrin 47380e746bSIgor Kudrin class AsmPrinterEmitDwarfSymbolReferenceTest : public AsmPrinterFixtureBase { 48380e746bSIgor Kudrin protected: 49380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 50380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 51380e746bSIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 52380e746bSIgor Kudrin return false; 53380e746bSIgor Kudrin 54d39bc36bSChen Zheng // AsmPrinter::emitDwarfSymbolReference(Label, true) gets the associated 55d39bc36bSChen Zheng // section from `Label` to find its BeginSymbol. 56d39bc36bSChen Zheng // Prepare the test symbol `Val` accordingly. 57380e746bSIgor Kudrin 58380e746bSIgor Kudrin Val = TestPrinter->getCtx().createTempSymbol(); 59d39bc36bSChen Zheng MCSection *Sec = 60d39bc36bSChen Zheng TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0); 61380e746bSIgor Kudrin SecBeginSymbol = Sec->getBeginSymbol(); 62380e746bSIgor Kudrin TestPrinter->getMS().SwitchSection(Sec); 63d39bc36bSChen Zheng Val->setFragment(&Sec->getDummyFragment()); 64d39bc36bSChen Zheng 65380e746bSIgor Kudrin return true; 66380e746bSIgor Kudrin } 67380e746bSIgor Kudrin 68380e746bSIgor Kudrin MCSymbol *Val = nullptr; 69380e746bSIgor Kudrin MCSymbol *SecBeginSymbol = nullptr; 70380e746bSIgor Kudrin }; 71380e746bSIgor Kudrin 72380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFF) { 73380e746bSIgor Kudrin if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32)) 745bbf1feaSIgor Kudrin GTEST_SKIP(); 75380e746bSIgor Kudrin 76380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), EmitCOFFSecRel32(Val, 0)); 77380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, false); 78380e746bSIgor Kudrin } 79380e746bSIgor Kudrin 80380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFFForceOffset) { 81380e746bSIgor Kudrin if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32)) 825bbf1feaSIgor Kudrin GTEST_SKIP(); 83380e746bSIgor Kudrin 84380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), 85380e746bSIgor Kudrin emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4)); 86380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, true); 87380e746bSIgor Kudrin } 88380e746bSIgor Kudrin 89380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32) { 90380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 915bbf1feaSIgor Kudrin GTEST_SKIP(); 92380e746bSIgor Kudrin 93380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 94380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _)) 95380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 96380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, false); 97380e746bSIgor Kudrin 98380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 99380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 100380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val); 101380e746bSIgor Kudrin } 102380e746bSIgor Kudrin 103380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32ForceOffset) { 104380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 1055bbf1feaSIgor Kudrin GTEST_SKIP(); 106380e746bSIgor Kudrin 107380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), 108380e746bSIgor Kudrin emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4)); 109380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, true); 110380e746bSIgor Kudrin } 111380e746bSIgor Kudrin 112380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64) { 113380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 1145bbf1feaSIgor Kudrin GTEST_SKIP(); 115380e746bSIgor Kudrin 116380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 117380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _)) 118380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 119380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, false); 120380e746bSIgor Kudrin 121380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 122380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 123380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val); 124380e746bSIgor Kudrin } 125380e746bSIgor Kudrin 126380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64ForceOffset) { 127380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 1285bbf1feaSIgor Kudrin GTEST_SKIP(); 129380e746bSIgor Kudrin 130380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), 131380e746bSIgor Kudrin emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 8)); 132380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, true); 133380e746bSIgor Kudrin } 134380e746bSIgor Kudrin 135380e746bSIgor Kudrin class AsmPrinterEmitDwarfStringOffsetTest : public AsmPrinterFixtureBase { 136380e746bSIgor Kudrin protected: 137380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 138380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 139380e746bSIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 140380e746bSIgor Kudrin return false; 141380e746bSIgor Kudrin 142380e746bSIgor Kudrin Val.Index = DwarfStringPoolEntry::NotIndexed; 143380e746bSIgor Kudrin Val.Symbol = TestPrinter->getCtx().createTempSymbol(); 144380e746bSIgor Kudrin Val.Offset = 42; 145380e746bSIgor Kudrin return true; 146380e746bSIgor Kudrin } 147380e746bSIgor Kudrin 148380e746bSIgor Kudrin DwarfStringPoolEntry Val; 149380e746bSIgor Kudrin }; 150380e746bSIgor Kudrin 151380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF32) { 152380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 1535bbf1feaSIgor Kudrin GTEST_SKIP(); 154380e746bSIgor Kudrin 155380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 156380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _)) 157380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 158380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 159380e746bSIgor Kudrin 160380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 161380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 162380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol); 163380e746bSIgor Kudrin } 164380e746bSIgor Kudrin 165380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, 166380e746bSIgor Kudrin DWARF32NoRelocationsAcrossSections) { 167380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 1685bbf1feaSIgor Kudrin GTEST_SKIP(); 169380e746bSIgor Kudrin 170380e746bSIgor Kudrin TestPrinter->setDwarfUsesRelocationsAcrossSections(false); 171380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 4)); 172380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 173380e746bSIgor Kudrin } 174380e746bSIgor Kudrin 175380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF64) { 176380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 1775bbf1feaSIgor Kudrin GTEST_SKIP(); 178380e746bSIgor Kudrin 179380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 180380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _)) 181380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 182380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 183380e746bSIgor Kudrin 184380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 185380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 186380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol); 187380e746bSIgor Kudrin } 188380e746bSIgor Kudrin 189380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, 190380e746bSIgor Kudrin DWARF64NoRelocationsAcrossSections) { 191380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 1925bbf1feaSIgor Kudrin GTEST_SKIP(); 193380e746bSIgor Kudrin 194380e746bSIgor Kudrin TestPrinter->setDwarfUsesRelocationsAcrossSections(false); 195380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 8)); 196380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 197380e746bSIgor Kudrin } 198380e746bSIgor Kudrin 199380e746bSIgor Kudrin class AsmPrinterEmitDwarfOffsetTest : public AsmPrinterFixtureBase { 200380e746bSIgor Kudrin protected: 201380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 202380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 203380e746bSIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 204380e746bSIgor Kudrin return false; 205380e746bSIgor Kudrin 206380e746bSIgor Kudrin Label = TestPrinter->getCtx().createTempSymbol(); 207380e746bSIgor Kudrin return true; 208380e746bSIgor Kudrin } 209380e746bSIgor Kudrin 210380e746bSIgor Kudrin MCSymbol *Label = nullptr; 211380e746bSIgor Kudrin uint64_t Offset = 42; 212380e746bSIgor Kudrin }; 213380e746bSIgor Kudrin 214380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF32) { 215380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 2165bbf1feaSIgor Kudrin GTEST_SKIP(); 217380e746bSIgor Kudrin 218380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 219380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _)) 220380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 221380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfOffset(Label, Offset); 222380e746bSIgor Kudrin 223380e746bSIgor Kudrin const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0); 224380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 225380e746bSIgor Kudrin EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add); 226380e746bSIgor Kudrin 227380e746bSIgor Kudrin const MCSymbolRefExpr *ActualLHS = 228380e746bSIgor Kudrin dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS()); 229380e746bSIgor Kudrin ASSERT_NE(ActualLHS, nullptr); 230380e746bSIgor Kudrin EXPECT_EQ(&(ActualLHS->getSymbol()), Label); 231380e746bSIgor Kudrin 232380e746bSIgor Kudrin const MCConstantExpr *ActualRHS = 233380e746bSIgor Kudrin dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS()); 234380e746bSIgor Kudrin ASSERT_NE(ActualRHS, nullptr); 235380e746bSIgor Kudrin EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset); 236380e746bSIgor Kudrin } 237380e746bSIgor Kudrin 238380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF64) { 239380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 2405bbf1feaSIgor Kudrin GTEST_SKIP(); 241380e746bSIgor Kudrin 242380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 243380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _)) 244380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 245380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfOffset(Label, Offset); 246380e746bSIgor Kudrin 247380e746bSIgor Kudrin const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0); 248380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 249380e746bSIgor Kudrin EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add); 250380e746bSIgor Kudrin 251380e746bSIgor Kudrin const MCSymbolRefExpr *ActualLHS = 252380e746bSIgor Kudrin dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS()); 253380e746bSIgor Kudrin ASSERT_NE(ActualLHS, nullptr); 254380e746bSIgor Kudrin EXPECT_EQ(&(ActualLHS->getSymbol()), Label); 255380e746bSIgor Kudrin 256380e746bSIgor Kudrin const MCConstantExpr *ActualRHS = 257380e746bSIgor Kudrin dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS()); 258380e746bSIgor Kudrin ASSERT_NE(ActualRHS, nullptr); 259380e746bSIgor Kudrin EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset); 260380e746bSIgor Kudrin } 261380e746bSIgor Kudrin 262c3c501f5SIgor Kudrin class AsmPrinterEmitDwarfLengthOrOffsetTest : public AsmPrinterFixtureBase { 263c3c501f5SIgor Kudrin protected: 264c3c501f5SIgor Kudrin uint64_t Val = 42; 265c3c501f5SIgor Kudrin }; 266c3c501f5SIgor Kudrin 267c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF32) { 268c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 2695bbf1feaSIgor Kudrin GTEST_SKIP(); 270c3c501f5SIgor Kudrin 271c3c501f5SIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4)); 272c3c501f5SIgor Kudrin TestPrinter->getAP()->emitDwarfLengthOrOffset(Val); 273c3c501f5SIgor Kudrin } 274c3c501f5SIgor Kudrin 275c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF64) { 276c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 2775bbf1feaSIgor Kudrin GTEST_SKIP(); 278c3c501f5SIgor Kudrin 279c3c501f5SIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8)); 280c3c501f5SIgor Kudrin TestPrinter->getAP()->emitDwarfLengthOrOffset(Val); 281c3c501f5SIgor Kudrin } 282c3c501f5SIgor Kudrin 283c3c501f5SIgor Kudrin class AsmPrinterGetUnitLengthFieldByteSizeTest : public AsmPrinterFixtureBase { 284c3c501f5SIgor Kudrin }; 285c3c501f5SIgor Kudrin 286c3c501f5SIgor Kudrin TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF32) { 287c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 2885bbf1feaSIgor Kudrin GTEST_SKIP(); 289c3c501f5SIgor Kudrin 290c3c501f5SIgor Kudrin EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 4u); 291c3c501f5SIgor Kudrin } 292c3c501f5SIgor Kudrin 293c3c501f5SIgor Kudrin TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF64) { 294c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 2955bbf1feaSIgor Kudrin GTEST_SKIP(); 296c3c501f5SIgor Kudrin 297c3c501f5SIgor Kudrin EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 12u); 298c3c501f5SIgor Kudrin } 299c3c501f5SIgor Kudrin 300c3c501f5SIgor Kudrin class AsmPrinterEmitDwarfUnitLengthAsIntTest : public AsmPrinterFixtureBase { 301c3c501f5SIgor Kudrin protected: 302c3c501f5SIgor Kudrin uint64_t Val = 42; 303c3c501f5SIgor Kudrin }; 304c3c501f5SIgor Kudrin 305c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF32) { 306c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 3075bbf1feaSIgor Kudrin GTEST_SKIP(); 308c3c501f5SIgor Kudrin 309c3c501f5SIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4)); 310c3c501f5SIgor Kudrin TestPrinter->getAP()->emitDwarfUnitLength(Val, ""); 311c3c501f5SIgor Kudrin } 312c3c501f5SIgor Kudrin 313c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF64) { 314c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 3155bbf1feaSIgor Kudrin GTEST_SKIP(); 316c3c501f5SIgor Kudrin 317c3c501f5SIgor Kudrin InSequence S; 318c3c501f5SIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4)); 319c3c501f5SIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8)); 320c3c501f5SIgor Kudrin 321c3c501f5SIgor Kudrin TestPrinter->getAP()->emitDwarfUnitLength(Val, ""); 322c3c501f5SIgor Kudrin } 323c3c501f5SIgor Kudrin 324c3c501f5SIgor Kudrin class AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest 325c3c501f5SIgor Kudrin : public AsmPrinterFixtureBase { 326c3c501f5SIgor Kudrin protected: 327c3c501f5SIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 328c3c501f5SIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 329c3c501f5SIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 330c3c501f5SIgor Kudrin return false; 331c3c501f5SIgor Kudrin 332c3c501f5SIgor Kudrin return true; 333c3c501f5SIgor Kudrin } 334c3c501f5SIgor Kudrin }; 335c3c501f5SIgor Kudrin 336c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF32) { 337c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 3385bbf1feaSIgor Kudrin GTEST_SKIP(); 339c3c501f5SIgor Kudrin 340d39bc36bSChen Zheng InSequence S; 341d39bc36bSChen Zheng const MCSymbol *Hi = nullptr; 342d39bc36bSChen Zheng const MCSymbol *Lo = nullptr; 343d39bc36bSChen Zheng EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 4)) 344d39bc36bSChen Zheng .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo))); 345d39bc36bSChen Zheng MCSymbol *LTmp = nullptr; 346d39bc36bSChen Zheng EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _)) 347d39bc36bSChen Zheng .WillOnce(SaveArg<0>(<mp)); 348d39bc36bSChen Zheng 349d39bc36bSChen Zheng MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", ""); 350d39bc36bSChen Zheng EXPECT_NE(Lo, nullptr); 351d39bc36bSChen Zheng EXPECT_EQ(Lo, LTmp); 352d39bc36bSChen Zheng EXPECT_NE(Hi, nullptr); 353d39bc36bSChen Zheng EXPECT_EQ(Hi, HTmp); 354c3c501f5SIgor Kudrin } 355c3c501f5SIgor Kudrin 356c3c501f5SIgor Kudrin TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF64) { 357c3c501f5SIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 3585bbf1feaSIgor Kudrin GTEST_SKIP(); 359c3c501f5SIgor Kudrin 360c3c501f5SIgor Kudrin InSequence S; 361d39bc36bSChen Zheng const MCSymbol *Hi = nullptr; 362d39bc36bSChen Zheng const MCSymbol *Lo = nullptr; 363c3c501f5SIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4)); 364d39bc36bSChen Zheng EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 8)) 365d39bc36bSChen Zheng .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo))); 366d39bc36bSChen Zheng MCSymbol *LTmp = nullptr; 367d39bc36bSChen Zheng EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _)) 368d39bc36bSChen Zheng .WillOnce(SaveArg<0>(<mp)); 369c3c501f5SIgor Kudrin 370d39bc36bSChen Zheng MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", ""); 371d39bc36bSChen Zheng EXPECT_NE(Lo, nullptr); 372d39bc36bSChen Zheng EXPECT_EQ(Lo, LTmp); 373d39bc36bSChen Zheng EXPECT_NE(Hi, nullptr); 374d39bc36bSChen Zheng EXPECT_EQ(Hi, HTmp); 375c3c501f5SIgor Kudrin } 376c3c501f5SIgor Kudrin 377a0ad066cSJameson Nash class AsmPrinterHandlerTest : public AsmPrinterFixtureBase { 378a0ad066cSJameson Nash class TestHandler : public AsmPrinterHandler { 379a0ad066cSJameson Nash AsmPrinterHandlerTest &Test; 380a0ad066cSJameson Nash 381a0ad066cSJameson Nash public: 382a0ad066cSJameson Nash TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {} 383a0ad066cSJameson Nash virtual ~TestHandler() {} 384a0ad066cSJameson Nash virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {} 385a0ad066cSJameson Nash virtual void beginModule(Module *M) override { Test.BeginCount++; } 386a0ad066cSJameson Nash virtual void endModule() override { Test.EndCount++; } 387a0ad066cSJameson Nash virtual void beginFunction(const MachineFunction *MF) override {} 388a0ad066cSJameson Nash virtual void endFunction(const MachineFunction *MF) override {} 389a0ad066cSJameson Nash virtual void beginInstruction(const MachineInstr *MI) override {} 390a0ad066cSJameson Nash virtual void endInstruction() override {} 391a0ad066cSJameson Nash }; 392a0ad066cSJameson Nash 393a0ad066cSJameson Nash protected: 394a0ad066cSJameson Nash bool init(const std::string &TripleStr, unsigned DwarfVersion, 395a0ad066cSJameson Nash dwarf::DwarfFormat DwarfFormat) { 396a0ad066cSJameson Nash if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 397a0ad066cSJameson Nash return false; 398a0ad066cSJameson Nash 399a0ad066cSJameson Nash auto *AP = TestPrinter->getAP(); 400a0ad066cSJameson Nash AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo( 401a0ad066cSJameson Nash std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)), 402a0ad066cSJameson Nash "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc")); 403a0ad066cSJameson Nash LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(&AP->TM); 404a0ad066cSJameson Nash legacy::PassManager PM; 405a0ad066cSJameson Nash PM.add(new MachineModuleInfoWrapperPass(LLVMTM)); 406a0ad066cSJameson Nash PM.add(TestPrinter->releaseAP()); // Takes ownership of destroying AP 407a0ad066cSJameson Nash LLVMContext Context; 408a0ad066cSJameson Nash std::unique_ptr<Module> M(new Module("TestModule", Context)); 409a0ad066cSJameson Nash M->setDataLayout(LLVMTM->createDataLayout()); 410a0ad066cSJameson Nash PM.run(*M); 411a0ad066cSJameson Nash // Now check that we can run it twice. 412a0ad066cSJameson Nash AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo( 413a0ad066cSJameson Nash std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)), 414a0ad066cSJameson Nash "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc")); 415a0ad066cSJameson Nash PM.run(*M); 416a0ad066cSJameson Nash return true; 417a0ad066cSJameson Nash } 418a0ad066cSJameson Nash 419a0ad066cSJameson Nash int BeginCount = 0; 420a0ad066cSJameson Nash int EndCount = 0; 421a0ad066cSJameson Nash }; 422a0ad066cSJameson Nash 423a0ad066cSJameson Nash TEST_F(AsmPrinterHandlerTest, Basic) { 424a0ad066cSJameson Nash if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 4255bbf1feaSIgor Kudrin GTEST_SKIP(); 426a0ad066cSJameson Nash 427a0ad066cSJameson Nash ASSERT_EQ(BeginCount, 3); 428a0ad066cSJameson Nash ASSERT_EQ(EndCount, 3); 429a0ad066cSJameson Nash } 430a0ad066cSJameson Nash 431380e746bSIgor Kudrin } // end namespace 432