[llvm] r339802 - [Support] Add a basic C API for llvm::Error.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 16 11:31:06 PDT 2018
Hi Adrian,
That seems odd. Do you know why this would be happening for llvm-c/Error.h
and not other llvm-c headers?
Cheers,
Lang.
On Wed, Aug 15, 2018 at 1:53 PM Adrian Prantl <aprantl at apple.com> wrote:
> It looks like you may also need to update the module.modulemap for
> building with -DLLVM_ENABLE_MODULES=On:
>
> While building module 'LLVM_Utils' imported from
> ../lib/Support/APSInt.cpp:15:
> In file included from <module-includes>:77:
> In file included from ../include/llvm/Support/BinaryStreamError.h:14:
> *../include/llvm/Support/Error.h:17:2: **warning: **missing submodule
> 'LLVM_C.Error' [-Wincomplete-umbrella]*
> #include "llvm-c/Error.h"
> * ^ ~~~~~~~~~~~~~~~~*
> 1 warning generated.
>
> thanks,
> adrian
>
> On Aug 15, 2018, at 11:42 AM, Lang Hames via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
> Author: lhames
> Date: Wed Aug 15 11:42:11 2018
> New Revision: 339802
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339802&view=rev
> Log:
> [Support] Add a basic C API for llvm::Error.
>
> Summary:
> The C-API supports consuming errors, converting an error to a string error
> message, and querying an error's type. Other LLVM C APIs that wish to use
> llvm::Error can supply error-type-id checkers and custom
> error-to-structured-type converters for any custom errors they provide.
>
> Reviewers: bogner, zturner, labath, dblaikie
>
> Subscribers: llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D50716
>
> Added:
> llvm/trunk/include/llvm-c/Error.h
> Modified:
> llvm/trunk/include/llvm/Support/Error.h
> llvm/trunk/lib/Support/Error.cpp
> llvm/trunk/unittests/Support/ErrorTest.cpp
>
> Added: llvm/trunk/include/llvm-c/Error.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Error.h?rev=339802&view=auto
>
> ==============================================================================
> --- llvm/trunk/include/llvm-c/Error.h (added)
> +++ llvm/trunk/include/llvm-c/Error.h Wed Aug 15 11:42:11 2018
> @@ -0,0 +1,65 @@
> +/*===------- llvm-c/Error.h - llvm::Error class C Interface -------*- C
> -*-===*\
> +|*
> *|
> +|* The LLVM Compiler Infrastructure
> *|
> +|*
> *|
> +|* This file is distributed under the University of Illinois Open Source
> *|
> +|* License. See LICENSE.TXT for details.
> *|
> +|*
> *|
>
> +|*===----------------------------------------------------------------------===*|
> +|*
> *|
> +|* This file defines the C interface to LLVM's Error class.
> *|
> +|*
> *|
>
> +\*===----------------------------------------------------------------------===*/
> +
> +#ifndef LLVM_C_ERROR_H
> +#define LLVM_C_ERROR_H
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * Opaque reference to an error instance. Null serves as the 'success'
> value.
> + */
> +typedef struct LLVMOpaqueError *LLVMErrorRef;
> +
> +/**
> + * Error type identifier.
> + */
> +typedef const void *LLVMErrorTypeId;
> +
> +/**
> + * Returns the type id for the given error instance, which must be a
> failure
> + * value (i.e. non-null).
> + */
> +LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err);
> +
> +/**
> + * Dispose of the given error without handling it. This operation
> consumes the
> + * error, and the given LLVMErrorRef value is not usable once this call
> returns.
> + * Note: This method *only* needs to be called if the error is not being
> passed
> + * to some other consuming operation, e.g. LLVMGetErrorMessage.
> + */
> +void LLVMConsumeError(LLVMErrorRef Err);
> +
> +/**
> + * Returns the given string's error message. This operation consumes the
> error,
> + * and the given LLVMErrorRef value is not usable once this call returns.
> + */
> +char *LLVMGetErrorMessage(LLVMErrorRef Err);
> +
> +/**
> + * Dispose of the given error message.
> + */
> +void LLVMDisposeErrorMessage(char *ErrMsg);
> +
> +/**
> + * Returns the type id for llvm StringError.
> + */
> +LLVMErrorTypeId LLVMGetStringErrorTypeId();
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
>
> Modified: llvm/trunk/include/llvm/Support/Error.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Error.h?rev=339802&r1=339801&r2=339802&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/Error.h (original)
> +++ llvm/trunk/include/llvm/Support/Error.h Wed Aug 15 11:42:11 2018
> @@ -14,8 +14,9 @@
> #ifndef LLVM_SUPPORT_ERROR_H
> #define LLVM_SUPPORT_ERROR_H
>
> -#include "llvm/ADT/SmallVector.h"
> +#include "llvm-c/Error.h"
> #include "llvm/ADT/STLExtras.h"
> +#include "llvm/ADT/SmallVector.h"
> #include "llvm/ADT/StringExtras.h"
> #include "llvm/ADT/Twine.h"
> #include "llvm/Config/abi-breaking.h"
> @@ -167,6 +168,9 @@ class LLVM_NODISCARD Error {
> // error.
> template <typename T> friend class Expected;
>
> + // wrap needs to be able to steal the payload.
> + friend LLVMErrorRef wrap(Error);
> +
> protected:
> /// Create a success value. Prefer using 'Error::success()' for
> readability
> Error() {
> @@ -1183,6 +1187,17 @@ private:
> std::function<int(const Error &)> GetExitCode;
> };
>
> +/// Conversion from Error to LLVMErrorRef for C error bindings.
> +inline LLVMErrorRef wrap(Error Err) {
> + return reinterpret_cast<LLVMErrorRef>(Err.takePayload().release());
> +}
> +
> +/// Conversion from LLVMErrorRef to Error for C error bindings.
> +inline Error unwrap(LLVMErrorRef ErrRef) {
> + return Error(std::unique_ptr<ErrorInfoBase>(
> + reinterpret_cast<ErrorInfoBase *>(ErrRef)));
> +}
> +
> } // end namespace llvm
>
> #endif // LLVM_SUPPORT_ERROR_H
>
> Modified: llvm/trunk/lib/Support/Error.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Error.cpp?rev=339802&r1=339801&r2=339802&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Support/Error.cpp (original)
> +++ llvm/trunk/lib/Support/Error.cpp Wed Aug 15 11:42:11 2018
> @@ -126,6 +126,26 @@ void report_fatal_error(Error Err, bool
> report_fatal_error(ErrMsg);
> }
>
> +} // end namespace llvm
> +
> +LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err) {
> + return reinterpret_cast<ErrorInfoBase *>(Err)->dynamicClassID();
> +}
> +
> +void LLVMConsumeError(LLVMErrorRef Err) { consumeError(unwrap(Err)); }
> +
> +char *LLVMGetErrorMessage(LLVMErrorRef Err) {
> + std::string Tmp = toString(unwrap(Err));
> + char *ErrMsg = new char[Tmp.size() + 1];
> + memcpy(ErrMsg, Tmp.data(), Tmp.size());
> + ErrMsg[Tmp.size()] = '\0';
> + return ErrMsg;
> +}
> +
> +void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; }
> +
> +LLVMErrorTypeId LLVMGetStringErrorTypeId() {
> + return reinterpret_cast<void *>(&StringError::ID);
> }
>
> #ifndef _MSC_VER
>
> Modified: llvm/trunk/unittests/Support/ErrorTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorTest.cpp?rev=339802&r1=339801&r2=339802&view=diff
>
> ==============================================================================
> --- llvm/trunk/unittests/Support/ErrorTest.cpp (original)
> +++ llvm/trunk/unittests/Support/ErrorTest.cpp Wed Aug 15 11:42:11 2018
> @@ -8,6 +8,7 @@
>
> //===----------------------------------------------------------------------===//
>
> #include "llvm/Support/Error.h"
> +#include "llvm-c/Error.h"
>
> #include "llvm/ADT/Twine.h"
> #include "llvm/Support/Errc.h"
> @@ -832,4 +833,35 @@ TEST(Error, ErrorMatchers) {
> " Actual: failed (CustomError {0})");
> }
>
> +TEST(Error, C_API) {
> + EXPECT_THAT_ERROR(unwrap(wrap(Error::success())), Succeeded())
> + << "Failed to round-trip Error success value via C API";
> + EXPECT_THAT_ERROR(unwrap(wrap(make_error<CustomError>(0))),
> + Failed<CustomError>())
> + << "Failed to round-trip Error failure value via C API";
> +
> + auto Err =
> + wrap(make_error<StringError>("test message",
> inconvertibleErrorCode()));
> + EXPECT_EQ(LLVMGetErrorTypeId(Err), LLVMGetStringErrorTypeId())
> + << "Failed to match error type ids via C API";
> + char *ErrMsg = LLVMGetErrorMessage(Err);
> + EXPECT_STREQ(ErrMsg, "test message")
> + << "Failed to roundtrip StringError error message via C API";
> + LLVMDisposeErrorMessage(ErrMsg);
> +
> + bool GotCSE = false;
> + bool GotCE = false;
> + handleAllErrors(
> + unwrap(wrap(joinErrors(make_error<CustomSubError>(42, 7),
> + make_error<CustomError>(42)))),
> + [&](CustomSubError &CSE) {
> + GotCSE = true;
> + },
> + [&](CustomError &CE) {
> + GotCE = true;
> + });
> + EXPECT_TRUE(GotCSE) << "Failed to round-trip ErrorList via C API";
> + EXPECT_TRUE(GotCE) << "Failed to round-trip ErrorList via C API";
> +}
> +
> } // end anon namespace
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180816/a6caf301/attachment.html>
More information about the llvm-commits
mailing list