//===--- unittests/CodeGen/TestAsmPrinter.cpp -------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "TestAsmPrinter.h" #include "llvm/ADT/Triple.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; using ::testing::StrictMock; // Note: a non-const reference argument cannot be passed through // testing::StrictMock, thus, we pass a pointer and dereference it here. MockMCStreamer::MockMCStreamer(MCContext *Ctx) : MCStreamer(*Ctx) {} MockMCStreamer::~MockMCStreamer() = default; TestAsmPrinter::TestAsmPrinter() = default; TestAsmPrinter::~TestAsmPrinter() = default; llvm::Expected> TestAsmPrinter::create(const std::string &TripleStr, uint16_t DwarfVersion, dwarf::DwarfFormat DwarfFormat) { std::string ErrorStr; const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrorStr); if (!TheTarget) return std::unique_ptr(); std::unique_ptr TestPrinter(new TestAsmPrinter); if (llvm::Error E = TestPrinter->init(TheTarget, TripleStr, DwarfVersion, DwarfFormat)) return std::move(E); return std::move(TestPrinter); } // Note:: based on dwarfgen::Generator::init() from // llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp llvm::Error TestAsmPrinter::init(const Target *TheTarget, StringRef TripleName, uint16_t DwarfVersion, dwarf::DwarfFormat DwarfFormat) { TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), None)); if (!TM) return make_error("no target machine for target " + TripleName, inconvertibleErrorCode()); MC.reset(new MCContext(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), TM->getObjFileLowering())); TM->getObjFileLowering()->Initialize(*MC, *TM); MS = new StrictMock(MC.get()); Asm.reset( TheTarget->createAsmPrinter(*TM, std::unique_ptr(MS))); if (!Asm) return make_error("no asm printer for target " + TripleName, inconvertibleErrorCode()); // Set the DWARF version correctly on all classes that we use. MC->setDwarfVersion(DwarfVersion); Asm->setDwarfVersion(DwarfVersion); // Set the DWARF format. MC->setDwarfFormat(DwarfFormat); return Error::success(); } void TestAsmPrinter::setDwarfUsesRelocationsAcrossSections(bool Enable) { struct HackMCAsmInfo : MCAsmInfo { void setDwarfUsesRelocationsAcrossSections(bool Enable) { DwarfUsesRelocationsAcrossSections = Enable; } }; static_cast(const_cast(TM->getMCAsmInfo())) ->setDwarfUsesRelocationsAcrossSections(Enable); }