[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