• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ADT/Triple.h"
11 #include "llvm/CodeGen/AsmPrinter.h"
12 #include "llvm/MC/MCAsmInfo.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/Support/TargetRegistry.h"
15 #include "llvm/Target/TargetLoweringObjectFile.h"
16 #include "llvm/Target/TargetMachine.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.
MockMCStreamer(MCContext * Ctx)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>>
create(const std::string & TripleStr,uint16_t DwarfVersion,dwarf::DwarfFormat DwarfFormat)32 TestAsmPrinter::create(const std::string &TripleStr, uint16_t DwarfVersion,
33                        dwarf::DwarfFormat DwarfFormat) {
34   std::string ErrorStr;
35   const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, 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
init(const Target * TheTarget,StringRef TripleName,uint16_t DwarfVersion,dwarf::DwarfFormat DwarfFormat)49 llvm::Error TestAsmPrinter::init(const Target *TheTarget, StringRef TripleName,
50                                  uint16_t DwarfVersion,
51                                  dwarf::DwarfFormat DwarfFormat) {
52   TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
53                                           None));
54   if (!TM)
55     return make_error<StringError>("no target machine for target " + TripleName,
56                                    inconvertibleErrorCode());
57 
58   MC.reset(new MCContext(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
59                          TM->getObjFileLowering()));
60   TM->getObjFileLowering()->Initialize(*MC, *TM);
61 
62   MS = new StrictMock<MockMCStreamer>(MC.get());
63 
64   Asm.reset(
65       TheTarget->createAsmPrinter(*TM, std::unique_ptr<MockMCStreamer>(MS)));
66   if (!Asm)
67     return make_error<StringError>("no asm printer for target " + TripleName,
68                                    inconvertibleErrorCode());
69 
70   // Set the DWARF version correctly on all classes that we use.
71   MC->setDwarfVersion(DwarfVersion);
72   Asm->setDwarfVersion(DwarfVersion);
73 
74   // Set the DWARF format.
75   MC->setDwarfFormat(DwarfFormat);
76 
77   return Error::success();
78 }
79 
setDwarfUsesRelocationsAcrossSections(bool Enable)80 void TestAsmPrinter::setDwarfUsesRelocationsAcrossSections(bool Enable) {
81   struct HackMCAsmInfo : MCAsmInfo {
82     void setDwarfUsesRelocationsAcrossSections(bool Enable) {
83       DwarfUsesRelocationsAcrossSections = Enable;
84     }
85   };
86   static_cast<HackMCAsmInfo *>(const_cast<MCAsmInfo *>(TM->getMCAsmInfo()))
87       ->setDwarfUsesRelocationsAcrossSections(Enable);
88 }
89