llvm.org GIT mirror llvm / 0660f17
Make it easier to pass a custom diagnostic handler to the IR linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220732 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
3 changed file(s) with 46 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
1111
1212 #include "llvm/ADT/SmallPtrSet.h"
1313
14 #include
15
1416 namespace llvm {
15
17 class DiagnosticInfo;
1618 class Module;
1719 class StructType;
1820
2729 PreserveSource = 1 // Preserve the source module.
2830 };
2931
32 typedef std::function
33 DiagnosticHandlerFunction;
34
35 Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
3036 Linker(Module *M);
3137 ~Linker();
3238
4349 return linkInModule(Src, Linker::DestroySource);
4450 }
4551
46 static bool LinkModules(Module *Dest, Module *Src, unsigned Mode);
52 static bool
53 LinkModules(Module *Dest, Module *Src, unsigned Mode,
54 DiagnosticHandlerFunction DiagnosticHandler);
55
56 static bool
57 LinkModules(Module *Dest, Module *Src, unsigned Mode);
58
4759
4860 private:
4961 Module *Composite;
5062 SmallPtrSet IdentifiedStructTypes;
63 DiagnosticHandlerFunction DiagnosticHandler;
5164 };
5265
5366 } // End llvm namespace
417417 // Vector of functions to lazily link in.
418418 std::vector LazilyLinkFunctions;
419419
420 Linker::DiagnosticHandlerFunction DiagnosticHandler;
421
420422 public:
421 ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, unsigned mode)
423 ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, unsigned mode,
424 Linker::DiagnosticHandlerFunction DiagnosticHandler)
422425 : DstM(dstM), SrcM(srcM), TypeMap(Set),
423 ValMaterializer(TypeMap, DstM, LazilyLinkFunctions), Mode(mode) {}
426 ValMaterializer(TypeMap, DstM, LazilyLinkFunctions), Mode(mode),
427 DiagnosticHandler(DiagnosticHandler) {}
424428
425429 bool run();
426430
430434
431435 /// Helper method for setting a message and returning an error code.
432436 bool emitError(const Twine &Message) {
433 DstM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));
437 DiagnosticHandler(LinkDiagnosticInfo(DS_Error, Message));
434438 return true;
435439 }
436440
437441 void emitWarning(const Twine &Message) {
438 DstM->getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message));
442 DiagnosticHandler(LinkDiagnosticInfo(DS_Warning, Message));
439443 }
440444
441445 bool getComdatLeader(Module *M, StringRef ComdatName,
17201724 return false;
17211725 }
17221726
1723 Linker::Linker(Module *M) : Composite(M) {
1727 Linker::Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler)
1728 : Composite(M), DiagnosticHandler(DiagnosticHandler) {}
1729
1730 Linker::Linker(Module *M)
1731 : Composite(M), DiagnosticHandler([this](const DiagnosticInfo &DI) {
1732 Composite->getContext().diagnose(DI);
1733 }) {
17241734 TypeFinder StructTypes;
17251735 StructTypes.run(*M, true);
17261736 IdentifiedStructTypes.insert(StructTypes.begin(), StructTypes.end());
17351745 }
17361746
17371747 bool Linker::linkInModule(Module *Src, unsigned Mode) {
1738 ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, Mode);
1748 ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, Mode, DiagnosticHandler);
17391749 return TheLinker.run();
17401750 }
17411751
17481758 /// true is returned and ErrorMsg (if not null) is set to indicate the problem.
17491759 /// Upon failure, the Dest module could be in a modified state, and shouldn't be
17501760 /// relied on to be consistent.
1761 bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode,
1762 DiagnosticHandlerFunction DiagnosticHandler) {
1763 Linker L(Dest, DiagnosticHandler);
1764 return L.linkInModule(Src, Mode);
1765 }
1766
17511767 bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode) {
17521768 Linker L(Dest);
17531769 return L.linkInModule(Src, Mode);
17571773 // C API.
17581774 //===----------------------------------------------------------------------===//
17591775
1760 static void bindingDiagnosticHandler(const llvm::DiagnosticInfo &DI,
1761 void *Context) {
1762 if (DI.getSeverity() != DS_Error)
1763 return;
1764
1765 std::string *Message = (std::string *)Context;
1766 {
1767 raw_string_ostream Stream(*Message);
1768 DiagnosticPrinterRawOStream DP(Stream);
1769 DI.print(DP);
1770 }
1771 }
1772
1773
17741776 LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
17751777 LLVMLinkerMode Mode, char **OutMessages) {
17761778 Module *D = unwrap(Dest);
1777 LLVMContext &Ctx = D->getContext();
1778
1779 LLVMContext::DiagnosticHandlerTy OldHandler = Ctx.getDiagnosticHandler();
1780 void *OldDiagnosticContext = Ctx.getDiagnosticContext();
17811779 std::string Message;
1782 Ctx.setDiagnosticHandler(bindingDiagnosticHandler, &Message);
1783 LLVMBool Result = Linker::LinkModules(D, unwrap(Src), Mode);
1784 Ctx.setDiagnosticHandler(OldHandler, OldDiagnosticContext);
1780 raw_string_ostream Stream(Message);
1781 DiagnosticPrinterRawOStream DP(Stream);
1782
1783 LLVMBool Result = Linker::LinkModules(
1784 D, unwrap(Src), Mode, [&](const DiagnosticInfo &DI) { DI.print(DP); });
17851785
17861786 if (OutMessages && Result)
17871787 *OutMessages = strdup(Message.c_str());
7070 return Result;
7171 }
7272
73 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
73 static void diagnosticHandler(const DiagnosticInfo &DI) {
7474 unsigned Severity = DI.getSeverity();
7575 switch (Severity) {
7676 case DS_Error:
7777 errs() << "ERROR: ";
78 break;
7879 case DS_Warning:
7980 if (SuppressWarnings)
8081 return;
8788
8889 DiagnosticPrinterRawOStream DP(errs());
8990 DI.print(DP);
91 errs() << '\n';
9092 }
9193
9294 int main(int argc, char **argv) {
99101 cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
100102
101103 auto Composite = make_unique("llvm-link", Context);
102 Linker L(Composite.get());
104 Linker L(Composite.get(), diagnosticHandler);
103105
104 Context.setDiagnosticHandler(diagnosticHandler);
105106 for (unsigned i = 0; i < InputFilenames.size(); ++i) {
106107 std::unique_ptr M = loadFile(argv[0], InputFilenames[i], Context);
107108 if (!M.get()) {