[Orc] Re-add C bindings for the Orc APIs, with a fix to remove the union that
[oota-llvm.git] / unittests / ExecutionEngine / Orc / OrcCAPITest.cpp
1 //===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "OrcTestCommon.h"
11 #include "gtest/gtest.h"
12 #include "llvm-c/OrcBindings.h"
13 #include "llvm-c/Target.h"
14 #include "llvm-c/TargetMachine.h"
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 namespace llvm {
21
22 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef);
23
24 class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
25 protected:
26
27   std::unique_ptr<Module> createTestModule(const Triple &TT) {
28     ModuleBuilder MB(getGlobalContext(), TT.str(), "");
29     Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
30     Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
31
32     Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext()));
33     IRBuilder<> B(&Main->back());
34     Value* Result = B.CreateCall(TestFunc);
35     B.CreateRet(Result);
36
37     return MB.takeModule();
38   }
39
40   typedef int (*MainFnTy)(void);
41
42   static int myTestFuncImpl(void) {
43     return 42;
44   }
45
46   static char *testFuncName;
47
48   static uint64_t myResolver(const char *Name, void *Ctx) {
49     if (!strncmp(Name, testFuncName, 8))
50       return (uint64_t)&myTestFuncImpl;
51     return 0;
52   }
53
54 };
55
56 char *OrcCAPIExecutionTest::testFuncName = 0;
57
58 TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
59   auto TM = getHostTargetMachineIfSupported();
60
61   if (!TM)
62     return;
63
64   std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
65
66   LLVMOrcJITStackRef JIT =
67     LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
68
69   LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
70
71   LLVMOrcModuleHandle H =
72     LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
73   MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
74   int Result = MainFn();
75   EXPECT_EQ(Result, 42)
76     << "Eagerly JIT'd code did not return expected result";
77
78   LLVMOrcRemoveModule(JIT, H);
79
80   LLVMOrcDisposeMangledSymbol(testFuncName);
81   LLVMOrcDisposeInstance(JIT);
82 }
83
84 TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
85   auto TM = getHostTargetMachineIfSupported();
86
87   if (!TM)
88     return;
89
90   std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
91
92   LLVMOrcJITStackRef JIT =
93     LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
94
95   LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
96   LLVMOrcModuleHandle H =
97     LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
98   MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
99   int Result = MainFn();
100   EXPECT_EQ(Result, 42)
101     << "Lazily JIT'd code did not return expected result";
102
103   LLVMOrcRemoveModule(JIT, H);
104
105   LLVMOrcDisposeMangledSymbol(testFuncName);
106   LLVMOrcDisposeInstance(JIT);
107 }
108
109 }