[PATCH] Added new functionality to LLVM C API to use DiagnosticInfo to handle errors

Quentin Colombet qcolombet at apple.com
Fri Apr 4 12:55:39 PDT 2014


On Apr 4, 2014, at 11:18 AM, Tom Stellard <tom at stellard.net> wrote:

> On Fri, Apr 04, 2014 at 10:59:11AM -0700, Eric Christopher wrote:
>> I'd very much prefer not to expose the severity for now. This is a
>> fairly well thought out, but very new interface and we guarantee
>> stability of the C interface so we'd be locking the current severity
>> interface down.
>> 
>> I'm not, honestly, a huge fan of opening this up to the C API in
>> general - is there a good reason to do so?
>> 
> 
> We would like to use this in Mesa so we can report backend compiler
> errors to the graphics drivers.  The most important use case is reporting
> when the verifier detects an illegal instruction, because executing
> illegal instructions has a good chance of locking up the system.
> 
> We'd also like to query the severity level, but we really only care about Errors
> and not the others.  In fact we probably could just use the severity and not
> worry about the error message.  What if we limited the C API to just:
> 
> LLVMContextSetDiagnosticHandler(LLVMContextRef C, LLVMDiagnosticHandler Handler,
>                                void *DiagnosticContext);
> /// @returns true if DiagnosticSeverity is DS_Error and false otherwise.
> bool LLVMDiagInfoHasError(LLVMDiagnosticInfoRef DI);
> 
> Would this work?

FWIW, the C API of lto has the severity thing.

The diagnostic handler is slightly different too and deal with string and severity:
/**
 * Diagnostic severity.
 *
 * \since LTO_API_VERSION=7
 */
typedef enum {
  LTO_DS_ERROR = 0,
  LTO_DS_WARNING = 1,
  LTO_DS_REMARK = 3, // Added in LTO_API_VERSION=10.
  LTO_DS_NOTE = 2
} 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.
 *
 * \since LTO_API_VERSION=7
 */
typedef void (*lto_diagnostic_handler_t)(
    lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt);

-Quentin

> 
> -Tom
> 
>> 
>> On Fri, Apr 4, 2014 at 10:39 AM, Quentin Colombet <qcolombet at apple.com> wrote:
>>> Hi Darren,
>>> 
>>> This LGTM with two comments:
>>> - LLVMPrintDiagInfoToString should state that the string has to be freed
>>> (see inline comment).
>>> - Should we provide an API to expose the severity as well? What would do the
>>> users of LLVMPrintDiagInfoToString if we do not?
>>> 
>>> Note that I'm not super familiar with the C API, so you may want to wait for
>>> another review.
>>> 
>>> Thanks,
>>> -Quentin
>>> 
>>> On Apr 2, 2014, at 8:32 PM, Tom Stellard <tom at stellard.net> wrote:
>>> 
>>> From: Darren Powell <darren.powell at amd.com>
>>> 
>>> ---
>>> include/llvm-c/Core.h            | 20 ++++++++++++++++++++
>>> include/llvm/IR/DiagnosticInfo.h |  3 +++
>>> lib/IR/Core.cpp                  | 20 ++++++++++++++++++++
>>> 3 files changed, 43 insertions(+)
>>> 
>>> diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
>>> index 50c5e3a..17367ff 100644
>>> --- a/include/llvm-c/Core.h
>>> +++ b/include/llvm-c/Core.h
>>> @@ -124,6 +124,12 @@ typedef struct LLVMOpaquePassRegistry
>>> *LLVMPassRegistryRef;
>>> * @see llvm::Use */
>>> typedef struct LLVMOpaqueUse *LLVMUseRef;
>>> 
>>> +
>>> +/**
>>> + * @see llvm::DiagnosticInfo
>>> + */
>>> +typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;
>>> +
>>> typedef enum {
>>>    LLVMZExtAttribute       = 1<<0,
>>>    LLVMSExtAttribute       = 1<<1,
>>> @@ -453,6 +459,8 @@ void LLVMEnablePrettyStackTrace(void);
>>> * @{
>>> */
>>> 
>>> +typedef void (*LLVMDiagnosticHandler)(LLVMDiagnosticInfoRef, void *);
>>> +
>>> /**
>>> * Create a new context.
>>> *
>>> @@ -467,6 +475,13 @@ LLVMContextRef LLVMContextCreate(void);
>>> LLVMContextRef LLVMGetGlobalContext(void);
>>> 
>>> /**
>>> + * Set the diagnostic handler for this context.
>>> + */
>>> +void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
>>> +                                     LLVMDiagnosticHandler Handler,
>>> +                                     void *DiagnosticContext);
>>> +
>>> +/**
>>> * Destroy a context instance.
>>> *
>>> * This should be called for every call to LLVMContextCreate() or memory
>>> @@ -474,6 +489,11 @@ LLVMContextRef LLVMGetGlobalContext(void);
>>> */
>>> void LLVMContextDispose(LLVMContextRef C);
>>> 
>>> +/**
>>> + * Extract string description from DiagnosticInfo.
>>> 
>>> 
>>> Add a comment here saying that the string should be freed using
>>> LLVMDisposeMessage.
>>> 
>>> + */
>>> +char *LLVMPrintDiagInfoToString(LLVMDiagnosticInfoRef DI);
>>> +
>>> unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name,
>>>                                  unsigned SLen);
>>> unsigned LLVMGetMDKindID(const char* Name, unsigned SLen);
>>> diff --git a/include/llvm/IR/DiagnosticInfo.h
>>> b/include/llvm/IR/DiagnosticInfo.h
>>> index de2a9d8..5fd6636 100644
>>> --- a/include/llvm/IR/DiagnosticInfo.h
>>> +++ b/include/llvm/IR/DiagnosticInfo.h
>>> @@ -193,6 +193,9 @@ public:
>>>  }
>>> };
>>> 
>>> +// Create wrappers for C Binding types (see CBindingWrapping.h).
>>> +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
>>> +
>>> } // End namespace llvm
>>> 
>>> #endif
>>> diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp
>>> index 4f3d8b1..e3b70c7 100644
>>> --- a/lib/IR/Core.cpp
>>> +++ b/lib/IR/Core.cpp
>>> @@ -17,6 +17,8 @@
>>> #include "llvm/IR/Attributes.h"
>>> #include "llvm/IR/CallSite.h"
>>> #include "llvm/IR/Constants.h"
>>> +#include "llvm/IR/DiagnosticInfo.h"
>>> +#include "llvm/IR/DiagnosticPrinter.h"
>>> #include "llvm/IR/DerivedTypes.h"
>>> #include "llvm/IR/GlobalAlias.h"
>>> #include "llvm/IR/GlobalVariable.h"
>>> @@ -76,6 +78,14 @@ LLVMContextRef LLVMGetGlobalContext() {
>>>  return wrap(&getGlobalContext());
>>> }
>>> 
>>> +void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
>>> +                                     LLVMDiagnosticHandler Handler,
>>> +                                     void *DiagnosticContext) {
>>> +  unwrap(C)->setDiagnosticHandler(
>>> +      LLVM_EXTENSION
>>> reinterpret_cast<LLVMContext::DiagnosticHandlerTy>(Handler),
>>> +      DiagnosticContext);
>>> +}
>>> +
>>> void LLVMContextDispose(LLVMContextRef C) {
>>>  delete unwrap(C);
>>> }
>>> @@ -89,6 +99,16 @@ unsigned LLVMGetMDKindID(const char* Name, unsigned SLen)
>>> {
>>>  return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen);
>>> }
>>> 
>>> +char *LLVMPrintDiagInfoToString(LLVMDiagnosticInfoRef DI) {
>>> +  std::string MsgStorage;
>>> +  raw_string_ostream Stream(MsgStorage);
>>> +  DiagnosticPrinterRawOStream DP(Stream);
>>> +
>>> +  unwrap(DI)->print(DP);
>>> +  Stream.flush();
>>> +
>>> +  return strdup(MsgStorage.c_str());
>>> +}
>>> 
>>> /*===-- Operations on modules
>>> ---------------------------------------------===*/
>>> 
>>> --
>>> 1.8.3.2
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140404/027a1977/attachment.html>


More information about the llvm-commits mailing list