Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/ffi/linker.cpp
1154 views
1
#include "core.h"
2
3
#include "llvm/IR/DiagnosticInfo.h"
4
#include "llvm/IR/DiagnosticPrinter.h"
5
#include "llvm/IR/Module.h"
6
#include "llvm/Support/raw_ostream.h"
7
8
#include "llvm-c/Linker.h"
9
10
extern "C" {
11
12
API_EXPORT(int)
13
LLVMPY_LinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, const char **Err) {
14
using namespace llvm;
15
std::string errorstring;
16
llvm::raw_string_ostream errstream(errorstring);
17
Module *D = unwrap(Dest);
18
LLVMContext &Ctx = D->getContext();
19
20
// This exists at the change to LLVM 6.x
21
// Link error diagnostics end up with a call to abort()
22
// install this handler to instead extract the reason for failure
23
// and report it.
24
class ReportNotAbortDiagnosticHandler : public DiagnosticHandler {
25
public:
26
ReportNotAbortDiagnosticHandler(llvm::raw_string_ostream &s)
27
: raw_stream(s) {}
28
29
bool handleDiagnostics(const DiagnosticInfo &DI) override {
30
llvm::DiagnosticPrinterRawOStream DP(raw_stream);
31
DI.print(DP);
32
return true;
33
}
34
35
private:
36
llvm::raw_string_ostream &raw_stream;
37
};
38
39
// save current handler as "old"
40
auto OldDiagnosticHandler = Ctx.getDiagnosticHandler();
41
42
Ctx.setDiagnosticHandler(
43
std::make_unique<ReportNotAbortDiagnosticHandler>(errstream));
44
45
// link
46
bool failed = LLVMLinkModules2(Dest, Src);
47
48
// put old handler back
49
Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
50
51
// if linking failed extract the reason for the failure
52
if (failed) {
53
errstream.flush();
54
*Err = LLVMPY_CreateString(errorstring.c_str());
55
}
56
57
return failed;
58
}
59
60
} // end extern "C"
61
62