1 | //===--- unittests/CodeGen/TestAsmPrinter.cpp -------------------*- C++ -*-===// |
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 "TestAsmPrinter.h" |
10 | #include "llvm/CodeGen/AsmPrinter.h" |
11 | #include "llvm/MC/MCAsmInfo.h" |
12 | #include "llvm/MC/MCContext.h" |
13 | #include "llvm/MC/TargetRegistry.h" |
14 | #include "llvm/Target/TargetLoweringObjectFile.h" |
15 | #include "llvm/Target/TargetMachine.h" |
16 | #include "llvm/TargetParser/Triple.h" |
17 | |
18 | using namespace llvm; |
19 | using ::testing::StrictMock; |
20 | |
21 | // Note: a non-const reference argument cannot be passed through |
22 | // testing::StrictMock, thus, we pass a pointer and dereference it here. |
23 | MockMCStreamer::MockMCStreamer(MCContext *Ctx) : MCStreamer(*Ctx) {} |
24 | |
25 | MockMCStreamer::~MockMCStreamer() = default; |
26 | |
27 | TestAsmPrinter::TestAsmPrinter() = default; |
28 | |
29 | TestAsmPrinter::~TestAsmPrinter() = default; |
30 | |
31 | llvm::Expected<std::unique_ptr<TestAsmPrinter>> |
32 | TestAsmPrinter::create(const std::string &TripleStr, uint16_t DwarfVersion, |
33 | dwarf::DwarfFormat DwarfFormat) { |
34 | std::string ErrorStr; |
35 | const Target *TheTarget = TargetRegistry::lookupTarget(Triple: TripleStr, Error&: ErrorStr); |
36 | if (!TheTarget) |
37 | return std::unique_ptr<TestAsmPrinter>(); |
38 | |
39 | std::unique_ptr<TestAsmPrinter> TestPrinter(new TestAsmPrinter); |
40 | if (llvm::Error E = |
41 | TestPrinter->init(TheTarget, TripleStr, DwarfVersion, DwarfFormat)) |
42 | return std::move(E); |
43 | |
44 | return std::move(TestPrinter); |
45 | } |
46 | |
47 | // Note:: based on dwarfgen::Generator::init() from |
48 | // llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp |
49 | llvm::Error TestAsmPrinter::init(const Target *TheTarget, StringRef TripleName, |
50 | uint16_t DwarfVersion, |
51 | dwarf::DwarfFormat DwarfFormat) { |
52 | TM.reset(p: TheTarget->createTargetMachine(TT: TripleName, CPU: "" , Features: "" , Options: TargetOptions(), |
53 | RM: std::nullopt)); |
54 | if (!TM) |
55 | return make_error<StringError>(Args: "no target machine for target " + TripleName, |
56 | Args: inconvertibleErrorCode()); |
57 | |
58 | Triple TheTriple(TripleName); |
59 | MC.reset(p: new MCContext(TheTriple, TM->getMCAsmInfo(), TM->getMCRegisterInfo(), |
60 | TM->getMCSubtargetInfo())); |
61 | TM->getObjFileLowering()->Initialize(ctx&: *MC, TM: *TM); |
62 | MC->setObjectFileInfo(TM->getObjFileLowering()); |
63 | |
64 | MS = new StrictMock<MockMCStreamer>(MC.get()); |
65 | |
66 | Asm.reset( |
67 | p: TheTarget->createAsmPrinter(TM&: *TM, Streamer: std::unique_ptr<MockMCStreamer>(MS))); |
68 | if (!Asm) |
69 | return make_error<StringError>(Args: "no asm printer for target " + TripleName, |
70 | Args: inconvertibleErrorCode()); |
71 | |
72 | // Set the DWARF version correctly on all classes that we use. |
73 | MC->setDwarfVersion(DwarfVersion); |
74 | Asm->setDwarfVersion(DwarfVersion); |
75 | |
76 | // Set the DWARF format. |
77 | MC->setDwarfFormat(DwarfFormat); |
78 | |
79 | return Error::success(); |
80 | } |
81 | |
82 | void TestAsmPrinter::setDwarfUsesRelocationsAcrossSections(bool Enable) { |
83 | Asm->setDwarfUsesRelocationsAcrossSections(Enable); |
84 | } |
85 | |