[llvm] [cmake] Add possibility to use ChooseMSVCCRT.cmake when include LLVM library
[llvm-core.git] / unittests / ExecutionEngine / JITLink / JITLinkTestCommon.h
blob8e1273ed91198e08854edb6153dfe3a4d1dacb86
1 //===---- JITLinkTestCommon.h - Utilities for Orc Unit Tests ----*- 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 // Common utilities for JITLink unit tests.
11 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
15 #define LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
17 #include "llvm/ADT/Triple.h"
18 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
19 #include "llvm/MC/MCAsmBackend.h"
20 #include "llvm/MC/MCAsmInfo.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCObjectStreamer.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/MCTargetOptions.h"
30 #include "llvm/Support/Endian.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
34 #include "gtest/gtest.h"
36 namespace llvm {
38 class JITLinkTestCommon {
39 public:
41 class TestResources {
42 public:
43 static Expected<std::unique_ptr<TestResources>>
44 Create(StringRef AsmSrc, StringRef TripleStr, bool PIC, bool LargeCodeModel,
45 MCTargetOptions Options);
47 MemoryBufferRef getTestObjectBufferRef() const;
49 const MCDisassembler &getDisassembler() const { return *Dis; }
51 private:
52 TestResources(StringRef AsmSrc, StringRef TripleStr, bool PIC,
53 bool LargeCodeModel, MCTargetOptions Options, Error &Err);
55 Error initializeTripleSpecifics(Triple &TT);
56 void initializeTestSpecifics(StringRef AsmSource, const Triple &TT,
57 bool PIC, bool LargeCodeModel);
59 const Target *TheTarget = nullptr;
60 SourceMgr SrcMgr;
61 SmallVector<char, 0> ObjBuffer;
62 raw_svector_ostream ObjStream;
64 MCTargetOptions Options;
65 std::unique_ptr<MCRegisterInfo> MRI;
66 std::unique_ptr<MCAsmInfo> MAI;
67 std::unique_ptr<MCInstrInfo> MCII;
68 std::unique_ptr<MCSubtargetInfo> STI;
70 MCObjectFileInfo MOFI;
71 std::unique_ptr<MCContext> AsCtx;
72 std::unique_ptr<MCStreamer> MOS;
74 std::unique_ptr<MCContext> DisCtx;
75 std::unique_ptr<const MCDisassembler> Dis;
78 class TestJITLinkContext : public jitlink::JITLinkContext {
79 public:
80 using TestCaseFunction = std::function<void(jitlink::AtomGraph &)>;
82 using NotifyResolvedFunction = std::function<void(jitlink::AtomGraph &G)>;
84 using NotifyFinalizedFunction = std::function<void(
85 std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>)>;
87 TestJITLinkContext(TestResources &TR, TestCaseFunction TestCase);
89 StringMap<JITEvaluatedSymbol> &externals() { return Externals; }
91 TestJITLinkContext &
92 setNotifyResolved(NotifyResolvedFunction NotifyResolved);
94 TestJITLinkContext &
95 setNotifyFinalized(NotifyFinalizedFunction NotifyFinalized);
97 TestJITLinkContext &
98 setMemoryManager(std::unique_ptr<jitlink::JITLinkMemoryManager> MM);
100 jitlink::JITLinkMemoryManager &getMemoryManager() override;
102 MemoryBufferRef getObjectBuffer() const override;
104 void notifyFailed(Error Err) override;
106 void
107 lookup(const DenseSet<StringRef> &Symbols,
108 jitlink::JITLinkAsyncLookupContinuation LookupContinuation) override;
110 void notifyResolved(jitlink::AtomGraph &G) override;
112 void notifyFinalized(
113 std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> A) override;
115 Error modifyPassConfig(const Triple &TT,
116 jitlink::PassConfiguration &Config) override;
118 private:
119 TestResources &TR;
120 TestCaseFunction TestCase;
121 NotifyResolvedFunction NotifyResolved;
122 NotifyFinalizedFunction NotifyFinalized;
123 std::unique_ptr<MemoryBuffer> ObjBuffer;
124 std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
125 StringMap<JITEvaluatedSymbol> Externals;
128 JITLinkTestCommon();
130 /// Get TestResources for this target/test.
132 /// If this method fails it is likely because the target is not supported in
133 /// this build. The test should bail out without failing (possibly logging a
134 /// diagnostic).
135 Expected<std::unique_ptr<TestResources>>
136 getTestResources(StringRef AsmSrc, StringRef Triple, bool PIC,
137 bool LargeCodeModel, MCTargetOptions Options) const {
138 return TestResources::Create(AsmSrc, Triple, PIC, LargeCodeModel,
139 std::move(Options));
142 template <typename T>
143 static Expected<T> readInt(jitlink::AtomGraph &G, jitlink::DefinedAtom &A,
144 size_t Offset = 0) {
145 if (Offset + sizeof(T) > A.getContent().size())
146 return make_error<StringError>("Reading past end of atom content",
147 inconvertibleErrorCode());
148 return support::endian::read<T, 1>(A.getContent().data() + Offset,
149 G.getEndianness());
152 template <typename T>
153 static Expected<T> readInt(jitlink::AtomGraph &G, StringRef AtomName,
154 size_t Offset = 0) {
155 auto DA = G.findDefinedAtomByName(AtomName);
156 if (!DA)
157 return DA.takeError();
158 return readInt<T>(G, *DA);
161 static Expected<std::pair<MCInst, size_t>>
162 disassemble(const MCDisassembler &Dis, jitlink::DefinedAtom &Atom,
163 size_t Offset = 0);
165 static Expected<int64_t> decodeImmediateOperand(const MCDisassembler &Dis,
166 jitlink::DefinedAtom &Atom,
167 size_t OpIdx,
168 size_t Offset = 0);
170 static jitlink::Atom &atom(jitlink::AtomGraph &G, StringRef Name) {
171 return G.getAtomByName(Name);
174 static jitlink::DefinedAtom &definedAtom(jitlink::AtomGraph &G,
175 StringRef Name) {
176 return G.getDefinedAtomByName(Name);
179 static JITTargetAddress atomAddr(jitlink::AtomGraph &G, StringRef Name) {
180 return atom(G, Name).getAddress();
183 template <typename PredT>
184 static size_t countEdgesMatching(jitlink::DefinedAtom &DA,
185 const PredT &Pred) {
186 return std::count_if(DA.edges().begin(), DA.edges().end(), Pred);
189 template <typename PredT>
190 static size_t countEdgesMatching(jitlink::AtomGraph &G, StringRef Name,
191 const PredT &Pred) {
192 return countEdgesMatching(definedAtom(G, Name), Pred);
195 private:
197 static bool AreTargetsInitialized;
198 void initializeLLVMTargets();
200 DenseMap<StringRef, JITEvaluatedSymbol> Externals;
203 } // end namespace llvm
205 #endif