1 //===--- OrcCAPITest.cpp - Unit tests for the OrcJIT v2 C API ---*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm-c/Core.h"
10 #include "llvm-c/Error.h"
11 #include "llvm-c/LLJIT.h"
12 #include "llvm-c/Orc.h"
13 #include "gtest/gtest.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IRReader/IRReader.h"
20 #include "llvm/Support/Error.h"
21 #include "llvm/Support/SourceMgr.h"
25 using namespace llvm::orc
;
27 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule
, LLVMOrcThreadSafeModuleRef
)
29 // OrcCAPITestBase contains several helper methods and pointers for unit tests
30 // written for the LLVM-C API. It provides the following helpers:
32 // 1. Jit: an LLVMOrcLLJIT instance which is freed upon test exit
33 // 2. ExecutionSession: the LLVMOrcExecutionSession for the JIT
34 // 3. MainDylib: the main JITDylib for the LLJIT instance
35 // 4. materializationUnitFn: function pointer to an empty function, used for
36 // materialization unit testing
37 // 5. definitionGeneratorFn: function pointer for a basic
38 // LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction
39 // 6. createTestModule: helper method for creating a basic thread-safe-module
40 class OrcCAPITestBase
: public testing::Test
{
42 LLVMOrcLLJITRef Jit
= nullptr;
43 LLVMOrcExecutionSessionRef ExecutionSession
= nullptr;
44 LLVMOrcJITDylibRef MainDylib
= nullptr;
47 static void SetUpTestCase() {
48 LLVMInitializeNativeTarget();
49 LLVMInitializeNativeAsmParser();
50 LLVMInitializeNativeAsmPrinter();
52 // Attempt to set up a JIT instance once to verify that we can.
53 LLVMOrcJITTargetMachineBuilderRef JTMB
= nullptr;
54 if (LLVMErrorRef E
= LLVMOrcJITTargetMachineBuilderDetectHost(&JTMB
)) {
55 // If setup fails then disable these tests.
57 TargetSupported
= false;
61 // Capture the target triple. We'll use it for both verification that
62 // this target is *supposed* to be supported, and error messages in
63 // the case that it fails anyway.
64 char *TT
= LLVMOrcJITTargetMachineBuilderGetTargetTriple(JTMB
);
66 LLVMDisposeMessage(TT
);
68 if (!isSupported(TargetTriple
)) {
69 // If this triple isn't supported then bail out.
70 TargetSupported
= false;
71 LLVMOrcDisposeJITTargetMachineBuilder(JTMB
);
75 LLVMOrcLLJITBuilderRef Builder
= LLVMOrcCreateLLJITBuilder();
76 LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder
, JTMB
);
78 if (LLVMErrorRef E
= LLVMOrcCreateLLJIT(&J
, Builder
)) {
79 // If setup fails then disable these tests.
80 TargetSupported
= false;
85 LLVMOrcDisposeLLJIT(J
);
86 TargetSupported
= true;
89 void SetUp() override
{
93 LLVMOrcJITTargetMachineBuilderRef JTMB
= nullptr;
94 LLVMErrorRef E1
= LLVMOrcJITTargetMachineBuilderDetectHost(&JTMB
);
95 assert(E1
== LLVMErrorSuccess
&& "Expected call to detect host to succeed");
98 LLVMOrcLLJITBuilderRef Builder
= LLVMOrcCreateLLJITBuilder();
99 LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder
, JTMB
);
100 LLVMErrorRef E2
= LLVMOrcCreateLLJIT(&Jit
, Builder
);
101 assert(E2
== LLVMErrorSuccess
&&
102 "Expected call to create LLJIT to succeed");
104 ExecutionSession
= LLVMOrcLLJITGetExecutionSession(Jit
);
105 MainDylib
= LLVMOrcLLJITGetMainJITDylib(Jit
);
107 void TearDown() override
{
108 LLVMOrcDisposeLLJIT(Jit
);
113 static bool isSupported(StringRef Triple
) {
114 // TODO: Print error messages in failure logs, use them to audit this list.
115 // Some architectures may be unsupportable or missing key components, but
116 // some may just be failing due to bugs in this testcase.
117 if (Triple
.startswith("armv7") || Triple
.startswith("armv8l"))
119 llvm::Triple
T(Triple
);
120 if (T
.isOSAIX() && T
.isPPC64())
125 static void materializationUnitFn() {}
127 // Stub definition generator, where all Names are materialized from the
128 // materializationUnitFn() test function and defined into the JIT Dylib
130 definitionGeneratorFn(LLVMOrcDefinitionGeneratorRef G
, void *Ctx
,
131 LLVMOrcLookupStateRef
*LS
, LLVMOrcLookupKind K
,
132 LLVMOrcJITDylibRef JD
, LLVMOrcJITDylibLookupFlags F
,
133 LLVMOrcCLookupSet Names
, size_t NamesCount
) {
134 for (size_t I
= 0; I
< NamesCount
; I
++) {
135 LLVMOrcCLookupSetElement Element
= Names
[I
];
136 LLVMOrcJITTargetAddress Addr
=
137 (LLVMOrcJITTargetAddress
)(&materializationUnitFn
);
138 LLVMJITSymbolFlags Flags
= {LLVMJITSymbolGenericFlagsWeak
, 0};
139 LLVMJITEvaluatedSymbol Sym
= {Addr
, Flags
};
140 LLVMOrcRetainSymbolStringPoolEntry(Element
.Name
);
141 LLVMJITCSymbolMapPair Pair
= {Element
.Name
, Sym
};
142 LLVMJITCSymbolMapPair Pairs
[] = {Pair
};
143 LLVMOrcMaterializationUnitRef MU
= LLVMOrcAbsoluteSymbols(Pairs
, 1);
144 LLVMErrorRef Err
= LLVMOrcJITDylibDefine(JD
, MU
);
148 return LLVMErrorSuccess
;
151 static Error
createSMDiagnosticError(llvm::SMDiagnostic
&Diag
) {
154 raw_string_ostream
OS(Msg
);
157 return make_error
<StringError
>(std::move(Msg
), inconvertibleErrorCode());
160 // Create an LLVM IR module from the given StringRef.
161 static Expected
<std::unique_ptr
<Module
>>
162 parseTestModule(LLVMContext
&Ctx
, StringRef Source
, StringRef Name
) {
163 assert(TargetSupported
&&
164 "Attempted to create module for unsupported target");
166 if (auto M
= parseIR(MemoryBufferRef(Source
, Name
), Err
, Ctx
))
168 return createSMDiagnosticError(Err
);
171 // returns the sum of its two parameters
172 static LLVMOrcThreadSafeModuleRef
createTestModule(StringRef Source
,
174 auto Ctx
= std::make_unique
<LLVMContext
>();
175 auto M
= cantFail(parseTestModule(*Ctx
, Source
, Name
));
176 return wrap(new ThreadSafeModule(std::move(M
), std::move(Ctx
)));
179 static LLVMMemoryBufferRef
createTestObject(StringRef Source
,
181 auto Ctx
= std::make_unique
<LLVMContext
>();
182 auto M
= cantFail(parseTestModule(*Ctx
, Source
, Name
));
184 auto JTMB
= cantFail(JITTargetMachineBuilder::detectHost());
185 M
->setDataLayout(cantFail(JTMB
.getDefaultDataLayoutForTarget()));
186 auto TM
= cantFail(JTMB
.createTargetMachine());
188 SimpleCompiler
SC(*TM
);
189 auto ObjBuffer
= cantFail(SC(*M
));
190 return wrap(ObjBuffer
.release());
193 static std::string TargetTriple
;
194 static bool TargetSupported
;
197 std::string
OrcCAPITestBase::TargetTriple
;
198 bool OrcCAPITestBase::TargetSupported
= false;
202 constexpr StringRef SumExample
=
204 define i32 @sum(i32 %x, i32 %y) {
206 %r = add nsw i32 %x, %y
211 } // end anonymous namespace.
213 // Consumes the given error ref and returns the string error message.
214 static std::string
toString(LLVMErrorRef E
) {
215 char *ErrMsg
= LLVMGetErrorMessage(E
);
216 std::string
Result(ErrMsg
);
217 LLVMDisposeErrorMessage(ErrMsg
);
221 TEST_F(OrcCAPITestBase
, SymbolStringPoolUniquing
) {
222 LLVMOrcSymbolStringPoolEntryRef E1
=
223 LLVMOrcExecutionSessionIntern(ExecutionSession
, "aaa");
224 LLVMOrcSymbolStringPoolEntryRef E2
=
225 LLVMOrcExecutionSessionIntern(ExecutionSession
, "aaa");
226 LLVMOrcSymbolStringPoolEntryRef E3
=
227 LLVMOrcExecutionSessionIntern(ExecutionSession
, "bbb");
228 const char *SymbolName
= LLVMOrcSymbolStringPoolEntryStr(E1
);
229 ASSERT_EQ(E1
, E2
) << "String pool entries are not unique";
230 ASSERT_NE(E1
, E3
) << "Unique symbol pool entries are equal";
231 ASSERT_STREQ("aaa", SymbolName
) << "String value of symbol is not equal";
232 LLVMOrcReleaseSymbolStringPoolEntry(E1
);
233 LLVMOrcReleaseSymbolStringPoolEntry(E2
);
234 LLVMOrcReleaseSymbolStringPoolEntry(E3
);
237 TEST_F(OrcCAPITestBase
, JITDylibLookup
) {
238 LLVMOrcJITDylibRef DoesNotExist
=
239 LLVMOrcExecutionSessionGetJITDylibByName(ExecutionSession
, "test");
240 ASSERT_FALSE(!!DoesNotExist
);
241 LLVMOrcJITDylibRef L1
=
242 LLVMOrcExecutionSessionCreateBareJITDylib(ExecutionSession
, "test");
243 LLVMOrcJITDylibRef L2
=
244 LLVMOrcExecutionSessionGetJITDylibByName(ExecutionSession
, "test");
245 ASSERT_EQ(L1
, L2
) << "Located JIT Dylib is not equal to original";
248 TEST_F(OrcCAPITestBase
, MaterializationUnitCreation
) {
249 LLVMOrcSymbolStringPoolEntryRef Name
=
250 LLVMOrcLLJITMangleAndIntern(Jit
, "test");
251 LLVMJITSymbolFlags Flags
= {LLVMJITSymbolGenericFlagsWeak
, 0};
252 LLVMOrcJITTargetAddress Addr
=
253 (LLVMOrcJITTargetAddress
)(&materializationUnitFn
);
254 LLVMJITEvaluatedSymbol Sym
= {Addr
, Flags
};
255 LLVMJITCSymbolMapPair Pair
= {Name
, Sym
};
256 LLVMJITCSymbolMapPair Pairs
[] = {Pair
};
257 LLVMOrcMaterializationUnitRef MU
= LLVMOrcAbsoluteSymbols(Pairs
, 1);
258 LLVMOrcJITDylibDefine(MainDylib
, MU
);
259 LLVMOrcJITTargetAddress OutAddr
;
260 if (LLVMErrorRef E
= LLVMOrcLLJITLookup(Jit
, &OutAddr
, "test"))
261 FAIL() << "Failed to look up \"test\" symbol (triple = " << TargetTriple
262 << "): " << toString(E
);
263 ASSERT_EQ(Addr
, OutAddr
);
266 TEST_F(OrcCAPITestBase
, DefinitionGenerators
) {
267 LLVMOrcDefinitionGeneratorRef Gen
=
268 LLVMOrcCreateCustomCAPIDefinitionGenerator(&definitionGeneratorFn
,
270 LLVMOrcJITDylibAddGenerator(MainDylib
, Gen
);
271 LLVMOrcJITTargetAddress OutAddr
;
272 if (LLVMErrorRef E
= LLVMOrcLLJITLookup(Jit
, &OutAddr
, "test"))
273 FAIL() << "The DefinitionGenerator did not create symbol \"test\" "
274 << "(triple = " << TargetTriple
<< "): " << toString(E
);
275 LLVMOrcJITTargetAddress ExpectedAddr
=
276 (LLVMOrcJITTargetAddress
)(&materializationUnitFn
);
277 ASSERT_EQ(ExpectedAddr
, OutAddr
);
280 TEST_F(OrcCAPITestBase
, ResourceTrackerDefinitionLifetime
) {
281 // This test case ensures that all symbols loaded into a JITDylib with a
282 // ResourceTracker attached are cleared from the JITDylib once the RT is
284 LLVMOrcResourceTrackerRef RT
=
285 LLVMOrcJITDylibCreateResourceTracker(MainDylib
);
286 LLVMOrcThreadSafeModuleRef TSM
= createTestModule(SumExample
, "sum.ll");
287 if (LLVMErrorRef E
= LLVMOrcLLJITAddLLVMIRModuleWithRT(Jit
, RT
, TSM
))
288 FAIL() << "Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
289 << "): " << toString(E
);
290 LLVMOrcJITTargetAddress TestFnAddr
;
291 if (LLVMErrorRef E
= LLVMOrcLLJITLookup(Jit
, &TestFnAddr
, "sum"))
292 FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple
293 << "): " << toString(E
);
294 ASSERT_TRUE(!!TestFnAddr
);
295 LLVMOrcResourceTrackerRemove(RT
);
296 LLVMOrcJITTargetAddress OutAddr
;
297 LLVMErrorRef Err
= LLVMOrcLLJITLookup(Jit
, &OutAddr
, "sum");
299 LLVMConsumeError(Err
);
301 ASSERT_FALSE(OutAddr
);
302 LLVMOrcReleaseResourceTracker(RT
);
305 TEST_F(OrcCAPITestBase
, ResourceTrackerTransfer
) {
306 LLVMOrcResourceTrackerRef DefaultRT
=
307 LLVMOrcJITDylibGetDefaultResourceTracker(MainDylib
);
308 LLVMOrcResourceTrackerRef RT2
=
309 LLVMOrcJITDylibCreateResourceTracker(MainDylib
);
310 LLVMOrcThreadSafeModuleRef TSM
= createTestModule(SumExample
, "sum.ll");
311 if (LLVMErrorRef E
= LLVMOrcLLJITAddLLVMIRModuleWithRT(Jit
, DefaultRT
, TSM
))
312 FAIL() << "Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
313 << "): " << toString(E
);
314 LLVMOrcJITTargetAddress Addr
;
315 if (LLVMErrorRef E
= LLVMOrcLLJITLookup(Jit
, &Addr
, "sum"))
316 FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple
317 << "): " << toString(E
);
318 LLVMOrcResourceTrackerTransferTo(DefaultRT
, RT2
);
319 LLVMErrorRef Err
= LLVMOrcLLJITLookup(Jit
, &Addr
, "sum");
321 LLVMOrcReleaseResourceTracker(RT2
);
324 TEST_F(OrcCAPITestBase
, AddObjectBuffer
) {
325 LLVMOrcObjectLayerRef ObjLinkingLayer
= LLVMOrcLLJITGetObjLinkingLayer(Jit
);
326 LLVMMemoryBufferRef ObjBuffer
= createTestObject(SumExample
, "sum.ll");
328 if (LLVMErrorRef E
= LLVMOrcObjectLayerAddObjectFile(ObjLinkingLayer
,
329 MainDylib
, ObjBuffer
))
330 FAIL() << "Failed to add object file to ObjLinkingLayer (triple = "
331 << TargetTriple
<< "): " << toString(E
);
333 LLVMOrcJITTargetAddress SumAddr
;
334 if (LLVMErrorRef E
= LLVMOrcLLJITLookup(Jit
, &SumAddr
, "sum"))
335 FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple
336 << "): " << toString(E
);
337 ASSERT_TRUE(!!SumAddr
);
340 TEST_F(OrcCAPITestBase
, ExecutionTest
) {
341 using SumFunctionType
= int32_t (*)(int32_t, int32_t);
343 // This test performs OrcJIT compilation of a simple sum module
344 LLVMInitializeNativeAsmPrinter();
345 LLVMOrcThreadSafeModuleRef TSM
= createTestModule(SumExample
, "sum.ll");
346 if (LLVMErrorRef E
= LLVMOrcLLJITAddLLVMIRModule(Jit
, MainDylib
, TSM
))
347 FAIL() << "Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
348 << ")" << toString(E
);
349 LLVMOrcJITTargetAddress TestFnAddr
;
350 if (LLVMErrorRef E
= LLVMOrcLLJITLookup(Jit
, &TestFnAddr
, "sum"))
351 FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple
352 << "): " << toString(E
);
353 auto *SumFn
= (SumFunctionType
)(TestFnAddr
);
354 int32_t Result
= SumFn(1, 1);
355 ASSERT_EQ(2, Result
);
358 void Destroy(void *Ctx
) {}
362 void Materialize(void *Ctx
, LLVMOrcMaterializationResponsibilityRef MR
) {
363 LLVMOrcJITDylibRef JD
=
364 LLVMOrcMaterializationResponsibilityGetTargetDylib(MR
);
367 LLVMOrcExecutionSessionRef ES
=
368 LLVMOrcMaterializationResponsibilityGetExecutionSession(MR
);
371 LLVMOrcSymbolStringPoolEntryRef InitSym
=
372 LLVMOrcMaterializationResponsibilityGetInitializerSymbol(MR
);
373 ASSERT_TRUE(!InitSym
);
376 LLVMOrcCSymbolFlagsMapPairs Symbols
=
377 LLVMOrcMaterializationResponsibilityGetSymbols(MR
, &NumSymbols
);
379 ASSERT_TRUE(!!Symbols
);
380 ASSERT_EQ(NumSymbols
, (size_t)1);
382 LLVMOrcSymbolStringPoolEntryRef
*RequestedSymbols
=
383 LLVMOrcMaterializationResponsibilityGetRequestedSymbols(MR
, &NumSymbols
);
385 ASSERT_TRUE(!!RequestedSymbols
);
386 ASSERT_EQ(NumSymbols
, (size_t)1);
388 LLVMOrcCSymbolFlagsMapPair TargetSym
= Symbols
[0];
390 ASSERT_EQ(RequestedSymbols
[0], TargetSym
.Name
);
391 LLVMOrcRetainSymbolStringPoolEntry(TargetSym
.Name
);
393 LLVMOrcDisposeCSymbolFlagsMap(Symbols
);
394 LLVMOrcDisposeSymbols(RequestedSymbols
);
396 LLVMOrcJITTargetAddress Addr
= (LLVMOrcJITTargetAddress
)(&TargetFn
);
398 LLVMJITSymbolFlags Flags
= {
399 LLVMJITSymbolGenericFlagsExported
| LLVMJITSymbolGenericFlagsCallable
, 0};
400 ASSERT_EQ(TargetSym
.Flags
.GenericFlags
, Flags
.GenericFlags
);
401 ASSERT_EQ(TargetSym
.Flags
.TargetFlags
, Flags
.TargetFlags
);
403 LLVMJITEvaluatedSymbol Sym
= {Addr
, Flags
};
405 LLVMOrcLLJITRef J
= (LLVMOrcLLJITRef
)Ctx
;
407 LLVMOrcSymbolStringPoolEntryRef OtherSymbol
=
408 LLVMOrcLLJITMangleAndIntern(J
, "other");
409 LLVMOrcSymbolStringPoolEntryRef DependencySymbol
=
410 LLVMOrcLLJITMangleAndIntern(J
, "dependency");
412 LLVMOrcRetainSymbolStringPoolEntry(OtherSymbol
);
413 LLVMOrcRetainSymbolStringPoolEntry(DependencySymbol
);
414 LLVMOrcCSymbolFlagsMapPair NewSymbols
[] = {
415 {OtherSymbol
, Flags
},
416 {DependencySymbol
, Flags
},
418 LLVMOrcMaterializationResponsibilityDefineMaterializing(MR
, NewSymbols
, 2);
420 LLVMOrcRetainSymbolStringPoolEntry(OtherSymbol
);
421 LLVMOrcMaterializationResponsibilityRef OtherMR
= NULL
;
423 LLVMErrorRef Err
= LLVMOrcMaterializationResponsibilityDelegate(
424 MR
, &OtherSymbol
, 1, &OtherMR
);
426 char *ErrMsg
= LLVMGetErrorMessage(Err
);
427 fprintf(stderr
, "Error: %s\n", ErrMsg
);
428 LLVMDisposeErrorMessage(ErrMsg
);
429 LLVMOrcMaterializationResponsibilityFailMaterialization(MR
);
430 LLVMOrcDisposeMaterializationResponsibility(MR
);
436 LLVMJITCSymbolMapPair OtherPair
= {OtherSymbol
, Sym
};
437 LLVMOrcMaterializationUnitRef OtherMU
= LLVMOrcAbsoluteSymbols(&OtherPair
, 1);
438 // OtherSymbol is no longer owned by us
441 LLVMOrcMaterializationResponsibilityReplace(OtherMR
, OtherMU
);
443 char *ErrMsg
= LLVMGetErrorMessage(Err
);
444 fprintf(stderr
, "Error: %s\n", ErrMsg
);
445 LLVMDisposeErrorMessage(ErrMsg
);
447 LLVMOrcMaterializationResponsibilityFailMaterialization(OtherMR
);
448 LLVMOrcMaterializationResponsibilityFailMaterialization(MR
);
450 LLVMOrcDisposeMaterializationResponsibility(OtherMR
);
451 LLVMOrcDisposeMaterializationResponsibility(MR
);
452 LLVMOrcDisposeMaterializationUnit(OtherMU
);
456 LLVMOrcDisposeMaterializationResponsibility(OtherMR
);
458 // FIXME: Implement async lookup
459 // A real test of the dependence tracking in the success case would require
460 // async lookups. You could:
461 // 1. Materialize foo, making foo depend on other.
462 // 2. In the caller, verify that the lookup callback for foo has not run (due
463 // to the dependence)
464 // 3. Materialize other by looking it up.
465 // 4. In the caller, verify that the lookup callback for foo has now run.
467 LLVMOrcRetainSymbolStringPoolEntry(TargetSym
.Name
);
468 LLVMOrcRetainSymbolStringPoolEntry(DependencySymbol
);
469 LLVMOrcCDependenceMapPair Dependency
= {JD
, {&DependencySymbol
, 1}};
470 LLVMOrcMaterializationResponsibilityAddDependencies(MR
, TargetSym
.Name
,
473 LLVMOrcRetainSymbolStringPoolEntry(DependencySymbol
);
474 LLVMOrcMaterializationResponsibilityAddDependenciesForAll(MR
, &Dependency
, 1);
477 LLVMJITCSymbolMapPair Pair
= {DependencySymbol
, Sym
};
478 LLVMOrcMaterializationResponsibilityNotifyResolved(MR
, &Pair
, 1);
479 // DependencySymbol no longer owned by us
481 Pair
= {TargetSym
.Name
, Sym
};
482 LLVMOrcMaterializationResponsibilityNotifyResolved(MR
, &Pair
, 1);
484 LLVMOrcMaterializationResponsibilityNotifyEmitted(MR
);
485 LLVMOrcDisposeMaterializationResponsibility(MR
);
489 TEST_F(OrcCAPITestBase
, MaterializationResponsibility
) {
490 LLVMJITSymbolFlags Flags
= {
491 LLVMJITSymbolGenericFlagsExported
| LLVMJITSymbolGenericFlagsCallable
, 0};
492 LLVMOrcCSymbolFlagsMapPair Sym
= {LLVMOrcLLJITMangleAndIntern(Jit
, "foo"),
495 LLVMOrcMaterializationUnitRef MU
= LLVMOrcCreateCustomMaterializationUnit(
496 "MU", (void *)Jit
, &Sym
, 1, NULL
, &Materialize
, NULL
, &Destroy
);
497 LLVMOrcJITDylibRef JD
= LLVMOrcLLJITGetMainJITDylib(Jit
);
498 LLVMOrcJITDylibDefine(JD
, MU
);
500 LLVMOrcJITTargetAddress Addr
;
501 if (LLVMErrorRef Err
= LLVMOrcLLJITLookup(Jit
, &Addr
, "foo")) {
502 FAIL() << "foo was not materialized " << toString(Err
);
505 ASSERT_EQ(Addr
, (LLVMOrcJITTargetAddress
)&TargetFn
);
507 if (LLVMErrorRef Err
= LLVMOrcLLJITLookup(Jit
, &Addr
, "other")) {
508 FAIL() << "other was not materialized " << toString(Err
);
511 ASSERT_EQ(Addr
, (LLVMOrcJITTargetAddress
)&TargetFn
);
513 if (LLVMErrorRef Err
= LLVMOrcLLJITLookup(Jit
, &Addr
, "dependency")) {
514 FAIL() << "dependency was not materialized " << toString(Err
);
517 ASSERT_EQ(Addr
, (LLVMOrcJITTargetAddress
)&TargetFn
);