#include "core.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm-c/Linker.h"
extern "C" {
API_EXPORT(int)
LLVMPY_LinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, const char **Err) {
using namespace llvm;
std::string errorstring;
llvm::raw_string_ostream errstream(errorstring);
Module *D = unwrap(Dest);
LLVMContext &Ctx = D->getContext();
class ReportNotAbortDiagnosticHandler : public DiagnosticHandler {
public:
ReportNotAbortDiagnosticHandler(llvm::raw_string_ostream &s)
: raw_stream(s) {}
bool handleDiagnostics(const DiagnosticInfo &DI) override {
llvm::DiagnosticPrinterRawOStream DP(raw_stream);
DI.print(DP);
return true;
}
private:
llvm::raw_string_ostream &raw_stream;
};
auto OldDiagnosticHandler = Ctx.getDiagnosticHandler();
Ctx.setDiagnosticHandler(
std::make_unique<ReportNotAbortDiagnosticHandler>(errstream));
bool failed = LLVMLinkModules2(Dest, Src);
Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
if (failed) {
errstream.flush();
*Err = LLVMPY_CreateString(errorstring.c_str());
}
return failed;
}
}