[llvm] r199338 - [LTO] Add a hook to map LLVM diagnostics into the clients of LTO.

Quentin Colombet qcolombet at apple.com
Wed Jan 15 14:04:35 PST 2014


Author: qcolombet
Date: Wed Jan 15 16:04:35 2014
New Revision: 199338

URL: http://llvm.org/viewvc/llvm-project?rev=199338&view=rev
Log:
[LTO] Add a hook to map LLVM diagnostics into the clients of LTO.

Add a hook in the C API of LTO so that clients of the code generator can set
their own handler for the LLVM diagnostics.
The handler is defined like this:
typedef void (*lto_diagnostic_handler_t)(lto_codegen_diagnostic_severity_t
severity, const char *diag, void *ctxt)
- severity says how bad this is.
- diag is a string that contains the diagnostic message.
- ctxt is the registered context for this handler.

This hook is more general than the lto_get_error_message, since this function
keeps only the latest message and can only be queried when something went wrong
(no warning for instance).

<rdar://problem/15517596>

Modified:
    llvm/trunk/include/llvm-c/lto.h
    llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
    llvm/trunk/tools/lto/lto.cpp
    llvm/trunk/tools/lto/lto.exports

Modified: llvm/trunk/include/llvm-c/lto.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=199338&r1=199337&r2=199338&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/lto.h (original)
+++ llvm/trunk/include/llvm-c/lto.h Wed Jan 15 16:04:35 2014
@@ -40,7 +40,7 @@ typedef bool lto_bool_t;
  * @{
  */
 
-#define LTO_API_VERSION 6
+#define LTO_API_VERSION 7
 
 typedef enum {
     LTO_SYMBOL_ALIGNMENT_MASK              = 0x0000001F, /* log2 of alignment */
@@ -204,6 +204,33 @@ lto_module_get_symbol_name(lto_module_t
 extern lto_symbol_attributes
 lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
 
+/**
+ * Diagnostic severity.
+ */
+typedef enum {
+  LTO_DS_ERROR,
+  LTO_DS_WARNING,
+  LTO_DS_NOTE
+} lto_codegen_diagnostic_severity_t;
+
+/**
+ * Diagnostic handler type.
+ * \p severity defines the severity.
+ * \p diag is the actual diagnostic.
+ * The diagnostic is not prefixed by any of severity keyword, e.g., 'error: '.
+ * \p ctxt is used to pass the context set with the diagnostic handler.
+ */
+typedef void (*lto_diagnostic_handler_t)(
+    lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt);
+
+/**
+ * Set a diagnostic handler and the related context (void *).
+ * This is more general than lto_get_error_message, as the diagnostic handler
+ * can be called at anytime within lto.
+ */
+extern void lto_codegen_set_diagnostic_handler(lto_code_gen_t,
+                                               lto_diagnostic_handler_t,
+                                               void *);
 
 /**
  * Instantiates a code generator.

Modified: llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h?rev=199338&r1=199337&r2=199338&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h (original)
+++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h Wed Jan 15 16:04:35 2014
@@ -46,6 +46,7 @@
 
 namespace llvm {
   class LLVMContext;
+  class DiagnosticInfo;
   class GlobalValue;
   class Mangler;
   class MemoryBuffer;
@@ -115,6 +116,8 @@ struct LTOCodeGenerator {
                       bool disableGVNLoadPRE,
                       std::string &errMsg);
 
+  void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
+
   bool shouldInternalize() const {
     return InternalizeStrategy != LTO_INTERNALIZE_NONE;
   }
@@ -139,6 +142,10 @@ private:
                         llvm::Mangler &Mangler);
   bool determineTarget(std::string &errMsg);
 
+  static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context);
+
+  void DiagnosticHandler2(const llvm::DiagnosticInfo &DI);
+
   typedef llvm::StringMap<uint8_t> StringSet;
 
   llvm::LLVMContext &Context;
@@ -155,6 +162,8 @@ private:
   std::string MCpu;
   std::string NativeObjectPath;
   llvm::TargetOptions Options;
+  lto_diagnostic_handler_t DiagHandler;
+  void *DiagContext;
 };
 
 #endif // LTO_CODE_GENERATOR_H

Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=199338&r1=199337&r2=199338&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Wed Jan 15 16:04:35 2014
@@ -21,6 +21,8 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Mangler.h"
 #include "llvm/IR/Module.h"
@@ -37,6 +39,7 @@
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
@@ -63,7 +66,8 @@ LTOCodeGenerator::LTOCodeGenerator()
     : Context(getGlobalContext()), Linker(new Module("ld-temp.o", Context)),
       TargetMach(NULL), EmitDwarfDebugInfo(false), ScopeRestrictionsDone(false),
       CodeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
-      InternalizeStrategy(LTO_INTERNALIZE_FULL), NativeObjectFile(NULL) {
+      InternalizeStrategy(LTO_INTERNALIZE_FULL), NativeObjectFile(NULL),
+      DiagHandler(NULL), DiagContext(NULL) {
   initializeLTOPasses();
 }
 
@@ -536,3 +540,47 @@ void LTOCodeGenerator::parseCodeGenDebug
     cl::ParseCommandLineOptions(CodegenOptions.size(),
                                 const_cast<char **>(&CodegenOptions[0]));
 }
+
+void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI,
+                                         void *Context) {
+  ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI);
+}
+
+void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) {
+  // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
+  lto_codegen_diagnostic_severity_t Severity;
+  switch (DI.getSeverity()) {
+  case DS_Error:
+    Severity = LTO_DS_ERROR;
+    break;
+  case DS_Warning:
+    Severity = LTO_DS_WARNING;
+    break;
+  case DS_Note:
+    Severity = LTO_DS_NOTE;
+    break;
+  }
+  // Create the string that will be reported to the external diagnostic handler.
+  std::string MsgStorage;
+  raw_string_ostream Stream(MsgStorage);
+  DiagnosticPrinterRawOStream DP(Stream);
+  DI.print(DP);
+  Stream.flush();
+
+  // If this method has been called it means someone has set up an external
+  // diagnostic handler. Assert on that.
+  assert(DiagHandler && "Invalid diagnostic handler");
+  (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
+}
+
+void
+LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
+                                       void *Ctxt) {
+  this->DiagHandler = DiagHandler;
+  this->DiagContext = Ctxt;
+  if (!DiagHandler)
+    return Context.setDiagnosticHandler(NULL, NULL);
+  // Register the LTOCodeGenerator stub in the LLVMContext to forward the
+  // diagnostic to the external DiagHandler.
+  Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this);
+}

Modified: llvm/trunk/tools/lto/lto.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=199338&r1=199337&r2=199338&view=diff
==============================================================================
--- llvm/trunk/tools/lto/lto.cpp (original)
+++ llvm/trunk/tools/lto/lto.cpp Wed Jan 15 16:04:35 2014
@@ -193,6 +193,13 @@ lto_symbol_attributes lto_module_get_sym
   return mod->getSymbolAttributes(index);
 }
 
+/// Set a diagnostic handler.
+void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
+                                        lto_diagnostic_handler_t diag_handler,
+                                        void *ctxt) {
+  cg->setDiagnosticHandler(diag_handler, ctxt);
+}
+
 /// lto_codegen_create - Instantiates a code generator. Returns NULL if there
 /// is an error.
 lto_code_gen_t lto_codegen_create(void) {

Modified: llvm/trunk/tools/lto/lto.exports
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.exports?rev=199338&r1=199337&r2=199338&view=diff
==============================================================================
--- llvm/trunk/tools/lto/lto.exports (original)
+++ llvm/trunk/tools/lto/lto.exports Wed Jan 15 16:04:35 2014
@@ -15,6 +15,7 @@ lto_module_is_object_file_for_target
 lto_module_is_object_file_in_memory
 lto_module_is_object_file_in_memory_for_target
 lto_module_dispose
+lto_codegen_set_diagnostic_handler
 lto_codegen_add_module
 lto_codegen_add_must_preserve_symbol
 lto_codegen_compile





More information about the llvm-commits mailing list