[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / unittests / ExecutionEngine / Orc / OrcCAPITest.cpp
blob72faccd795b710d530e2441fb56f74fa8fefe8b7
1 //===--- OrcCAPITest.cpp - Unit tests for the OrcJIT v2 C API ---*- 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 //===----------------------------------------------------------------------===//
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"
22 #include <string>
24 using namespace llvm;
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 {
41 protected:
42 LLVMOrcLLJITRef Jit = nullptr;
43 LLVMOrcExecutionSessionRef ExecutionSession = nullptr;
44 LLVMOrcJITDylibRef MainDylib = nullptr;
46 public:
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.
56 LLVMConsumeError(E);
57 TargetSupported = false;
58 return;
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);
65 TargetTriple = TT;
66 LLVMDisposeMessage(TT);
68 if (!isSupported(TargetTriple)) {
69 // If this triple isn't supported then bail out.
70 TargetSupported = false;
71 LLVMOrcDisposeJITTargetMachineBuilder(JTMB);
72 return;
75 LLVMOrcLLJITBuilderRef Builder = LLVMOrcCreateLLJITBuilder();
76 LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB);
77 LLVMOrcLLJITRef J;
78 if (LLVMErrorRef E = LLVMOrcCreateLLJIT(&J, Builder)) {
79 // If setup fails then disable these tests.
80 TargetSupported = false;
81 LLVMConsumeError(E);
82 return;
85 LLVMOrcDisposeLLJIT(J);
86 TargetSupported = true;
89 void SetUp() override {
90 if (!TargetSupported)
91 GTEST_SKIP();
93 LLVMOrcJITTargetMachineBuilderRef JTMB = nullptr;
94 LLVMErrorRef E1 = LLVMOrcJITTargetMachineBuilderDetectHost(&JTMB);
95 assert(E1 == LLVMErrorSuccess && "Expected call to detect host to succeed");
96 (void)E1;
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");
103 (void)E2;
104 ExecutionSession = LLVMOrcLLJITGetExecutionSession(Jit);
105 MainDylib = LLVMOrcLLJITGetMainJITDylib(Jit);
107 void TearDown() override {
108 LLVMOrcDisposeLLJIT(Jit);
109 Jit = nullptr;
112 protected:
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"))
118 return false;
119 llvm::Triple T(Triple);
120 if (T.isOSAIX() && T.isPPC64())
121 return false;
122 return true;
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
129 static LLVMErrorRef
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);
145 if (Err)
146 return Err;
148 return LLVMErrorSuccess;
151 static Error createSMDiagnosticError(llvm::SMDiagnostic &Diag) {
152 std::string Msg;
154 raw_string_ostream OS(Msg);
155 Diag.print("", OS);
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");
165 SMDiagnostic Err;
166 if (auto M = parseIR(MemoryBufferRef(Source, Name), Err, Ctx))
167 return std::move(M);
168 return createSMDiagnosticError(Err);
171 // returns the sum of its two parameters
172 static LLVMOrcThreadSafeModuleRef createTestModule(StringRef Source,
173 StringRef Name) {
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,
180 StringRef Name) {
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;
200 namespace {
202 constexpr StringRef SumExample =
204 define i32 @sum(i32 %x, i32 %y) {
205 entry:
206 %r = add nsw i32 %x, %y
207 ret i32 %r
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);
218 return Result;
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,
269 nullptr);
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
283 // removed.
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");
298 ASSERT_TRUE(Err);
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");
320 ASSERT_FALSE(Err);
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) {}
360 void TargetFn() {}
362 void Materialize(void *Ctx, LLVMOrcMaterializationResponsibilityRef MR) {
363 LLVMOrcJITDylibRef JD =
364 LLVMOrcMaterializationResponsibilityGetTargetDylib(MR);
365 ASSERT_TRUE(!!JD);
367 LLVMOrcExecutionSessionRef ES =
368 LLVMOrcMaterializationResponsibilityGetExecutionSession(MR);
369 ASSERT_TRUE(!!ES);
371 LLVMOrcSymbolStringPoolEntryRef InitSym =
372 LLVMOrcMaterializationResponsibilityGetInitializerSymbol(MR);
373 ASSERT_TRUE(!InitSym);
375 size_t NumSymbols;
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);
425 if (Err) {
426 char *ErrMsg = LLVMGetErrorMessage(Err);
427 fprintf(stderr, "Error: %s\n", ErrMsg);
428 LLVMDisposeErrorMessage(ErrMsg);
429 LLVMOrcMaterializationResponsibilityFailMaterialization(MR);
430 LLVMOrcDisposeMaterializationResponsibility(MR);
431 return;
434 assert(OtherMR);
436 LLVMJITCSymbolMapPair OtherPair = {OtherSymbol, Sym};
437 LLVMOrcMaterializationUnitRef OtherMU = LLVMOrcAbsoluteSymbols(&OtherPair, 1);
438 // OtherSymbol is no longer owned by us
440 LLVMErrorRef Err =
441 LLVMOrcMaterializationResponsibilityReplace(OtherMR, OtherMU);
442 if (Err) {
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);
453 return;
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,
471 &Dependency, 1);
473 LLVMOrcRetainSymbolStringPoolEntry(DependencySymbol);
474 LLVMOrcMaterializationResponsibilityAddDependenciesForAll(MR, &Dependency, 1);
476 // See FIXME above
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);
486 return;
489 TEST_F(OrcCAPITestBase, MaterializationResponsibility) {
490 LLVMJITSymbolFlags Flags = {
491 LLVMJITSymbolGenericFlagsExported | LLVMJITSymbolGenericFlagsCallable, 0};
492 LLVMOrcCSymbolFlagsMapPair Sym = {LLVMOrcLLJITMangleAndIntern(Jit, "foo"),
493 Flags};
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);
504 ASSERT_TRUE(!!Addr);
505 ASSERT_EQ(Addr, (LLVMOrcJITTargetAddress)&TargetFn);
507 if (LLVMErrorRef Err = LLVMOrcLLJITLookup(Jit, &Addr, "other")) {
508 FAIL() << "other was not materialized " << toString(Err);
510 ASSERT_TRUE(!!Addr);
511 ASSERT_EQ(Addr, (LLVMOrcJITTargetAddress)&TargetFn);
513 if (LLVMErrorRef Err = LLVMOrcLLJITLookup(Jit, &Addr, "dependency")) {
514 FAIL() << "dependency was not materialized " << toString(Err);
516 ASSERT_TRUE(!!Addr);
517 ASSERT_EQ(Addr, (LLVMOrcJITTargetAddress)&TargetFn);