File: linker.cpp

package info (click to toggle)
llvmlite 0.44.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,736 kB
  • sloc: python: 12,771; cpp: 3,146; sh: 185; makefile: 183
file content (60 lines) | stat: -rw-r--r-- 1,683 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#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();

    // This exists at the change to LLVM 6.x
    // Link error diagnostics end up with a call to abort()
    // install this handler to instead extract the reason for failure
    // and report it.
    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;
    };

    // save current handler as "old"
    auto OldDiagnosticHandler = Ctx.getDiagnosticHandler();

    Ctx.setDiagnosticHandler(
        std::make_unique<ReportNotAbortDiagnosticHandler>(errstream));

    // link
    bool failed = LLVMLinkModules2(Dest, Src);

    // put old handler back
    Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));

    // if linking failed extract the reason for the failure
    if (failed) {
        errstream.flush();
        *Err = LLVMPY_CreateString(errorstring.c_str());
    }

    return failed;
}

} // end extern "C"