[llvm] [orc-rt] Consolidate symbol export macros (PR #220495)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 1 23:46:49 PDT 2026
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/220495
Replace the overlapping visibility macros with a single pair, one per public API surface:
ORC_RT_C_EXPORT (orc-rt-c/support/Compiler.h) - the C API
ORC_RT_EXPORT (orc-rt/support/Compiler.h) - the C++ API
ORC_RT_C_ABI is renamed to ORC_RT_C_EXPORT. ORC_RT_INTERFACE, ORC_RT_HIDDEN and ORC_RT_IMPORT are removed.
ORC_RT_EXPORT is currently defined as ORC_RT_C_EXPORT so that the platform logic lives in one place. It becomes separately switchable once there is an option to hide the C++ API.
No change to generated code: every macro expands to exactly what it did before. The Windows dllexport/dllimport and static-build cases are left as a TODO for the commit that adds the shared-library build.
>From dbd081bb5ce99909002a55f02c884d5acc8eee7e Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 2 Sep 2026 16:39:49 +1000
Subject: [PATCH] [orc-rt] Consolidate symbol export macros
Replace the overlapping visibility macros with a single pair, one per
public API surface:
ORC_RT_C_EXPORT (orc-rt-c/support/Compiler.h) - the C API
ORC_RT_EXPORT (orc-rt/support/Compiler.h) - the C++ API
ORC_RT_C_ABI is renamed to ORC_RT_C_EXPORT. ORC_RT_INTERFACE,
ORC_RT_HIDDEN and ORC_RT_IMPORT are removed.
ORC_RT_EXPORT is currently defined as ORC_RT_C_EXPORT so that the
platform logic lives in one place. It becomes separately switchable once
there is an option to hide the C++ API.
No change to generated code: every macro expands to exactly what it did
before. The Windows dllexport/dllimport and static-build cases are left
as a TODO for the commit that adds the shared-library build.
---
orc-rt/include/orc-rt-c/support/Compiler.h | 14 +++++++++-----
orc-rt/include/orc-rt-c/support/Error.h | 17 ++++++++++-------
orc-rt/include/orc-rt/support/Compiler.h | 20 +++++++++++---------
orc-rt/lib/bedrock/GDBJITRegistrar.cpp | 11 ++++++++---
4 files changed, 38 insertions(+), 24 deletions(-)
diff --git a/orc-rt/include/orc-rt-c/support/Compiler.h b/orc-rt/include/orc-rt-c/support/Compiler.h
index c740b549481f3..89b1b1d874c66 100644
--- a/orc-rt/include/orc-rt-c/support/Compiler.h
+++ b/orc-rt/include/orc-rt-c/support/Compiler.h
@@ -38,14 +38,18 @@
#define ORC_RT_C_EXTERN_C_END ORC_RT_C_STRICT_PROTOTYPES_END
#endif
-/* ORC_RT_C_ABI is the export/visibility macro used to mark symbols declared
- in orc-rt-c as exported when built as a shared library. */
+/* ORC_RT_C_EXPORT marks a symbol declared in orc-rt-c as part of the ORC
+ runtime's binary interface: exported from the runtime when it is built as a
+ shared library, and imported by consumers of that library.
+
+ TODO: Add the Windows __declspec(dllexport) / __declspec(dllimport) and
+ static-build cases once there is a shared-library build to exercise them. */
#if defined(__has_attribute) && __has_attribute(visibility)
-#define ORC_RT_C_ABI __attribute__((visibility("default")))
+#define ORC_RT_C_EXPORT __attribute__((visibility("default")))
#endif
-#if !defined(ORC_RT_C_ABI)
-#define ORC_RT_C_ABI
+#if !defined(ORC_RT_C_EXPORT)
+#define ORC_RT_C_EXPORT
#endif
/* ORC_RT_C_NOTHROW indicates that a function won't throw a C++ exception. */
diff --git a/orc-rt/include/orc-rt-c/support/Error.h b/orc-rt/include/orc-rt-c/support/Error.h
index 7afa373c7d75e..91b038f494cef 100644
--- a/orc-rt/include/orc-rt-c/support/Error.h
+++ b/orc-rt/include/orc-rt-c/support/Error.h
@@ -32,7 +32,7 @@ typedef const void *orc_rt_Error_TypeId;
* Returns the type id for the given error instance, which must be a failure
* value (i.e. non-null).
*/
-ORC_RT_C_ABI orc_rt_Error_TypeId orc_rt_Error_getTypeId(orc_rt_ErrorRef Err)
+ORC_RT_C_EXPORT orc_rt_Error_TypeId orc_rt_Error_getTypeId(orc_rt_ErrorRef Err)
ORC_RT_C_NOTHROW;
/**
@@ -42,7 +42,7 @@ ORC_RT_C_ABI orc_rt_Error_TypeId orc_rt_Error_getTypeId(orc_rt_ErrorRef Err)
* Note: This method *only* needs to be called if the error is not being passed
* to some other consuming operation, e.g. LLVMGetErrorMessage.
*/
-ORC_RT_C_ABI void orc_rt_Error_consume(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
+ORC_RT_C_EXPORT void orc_rt_Error_consume(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
/**
* Report a fatal error if Err is a failure value.
@@ -50,7 +50,8 @@ ORC_RT_C_ABI void orc_rt_Error_consume(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
* This function can be used to wrap calls to fallible functions ONLY when it is
* known that the Error will always be a success value.
*/
-ORC_RT_C_ABI void orc_rt_Error_cantFail(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
+ORC_RT_C_EXPORT void
+orc_rt_Error_cantFail(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
/**
* Returns the given string's error message. This operation consumes the error,
@@ -58,23 +59,25 @@ ORC_RT_C_ABI void orc_rt_Error_cantFail(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
* The caller is responsible for disposing of the string by calling
* LLVMDisposeErrorMessage.
*/
-ORC_RT_C_ABI char *orc_rt_Error_toString(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
+ORC_RT_C_EXPORT char *
+orc_rt_Error_toString(orc_rt_ErrorRef Err) ORC_RT_C_NOTHROW;
/**
* Dispose of the given error message.
*/
-ORC_RT_C_ABI void orc_rt_Error_freeErrorMessage(char *ErrMsg) ORC_RT_C_NOTHROW;
+ORC_RT_C_EXPORT void
+orc_rt_Error_freeErrorMessage(char *ErrMsg) ORC_RT_C_NOTHROW;
/**
* Returns the type id for llvm StringError.
*/
-ORC_RT_C_ABI orc_rt_Error_TypeId orc_rt_StringError_getTypeId(void)
+ORC_RT_C_EXPORT orc_rt_Error_TypeId orc_rt_StringError_getTypeId(void)
ORC_RT_C_NOTHROW;
/**
* Create a StringError.
*/
-ORC_RT_C_ABI orc_rt_ErrorRef orc_rt_StringError_create(const char *ErrMsg)
+ORC_RT_C_EXPORT orc_rt_ErrorRef orc_rt_StringError_create(const char *ErrMsg)
ORC_RT_C_NOTHROW;
ORC_RT_C_EXTERN_C_END
diff --git a/orc-rt/include/orc-rt/support/Compiler.h b/orc-rt/include/orc-rt/support/Compiler.h
index c568707a61d2b..e2c4e7c6fe14d 100644
--- a/orc-rt/include/orc-rt/support/Compiler.h
+++ b/orc-rt/include/orc-rt/support/Compiler.h
@@ -15,17 +15,19 @@
#ifndef ORC_RT_SUPPORT_COMPILER_H
#define ORC_RT_SUPPORT_COMPILER_H
+#include "orc-rt-c/support/Compiler.h"
+
#include <cassert>
-#if defined(_WIN32)
-#define ORC_RT_INTERFACE extern "C"
-#define ORC_RT_HIDDEN
-#define ORC_RT_IMPORT extern "C" __declspec(dllimport)
-#else
-#define ORC_RT_INTERFACE extern "C" __attribute__((visibility("default")))
-#define ORC_RT_HIDDEN __attribute__((visibility("hidden")))
-#define ORC_RT_IMPORT extern "C"
-#endif
+// ORC_RT_EXPORT marks a symbol declared in orc-rt as part of the ORC runtime's
+// binary interface: exported from the runtime when it is built as a shared
+// library, and imported by consumers of that library.
+//
+// Symbols belonging to the C API use ORC_RT_C_EXPORT instead. The two are
+// equivalent today, but the C++ API is expected to change far more often than
+// the C API, so ORC_RT_EXPORT may become separately switchable to allow the C++
+// API to be hidden.
+#define ORC_RT_EXPORT ORC_RT_C_EXPORT
#ifndef __has_builtin
#define __has_builtin(x) 0
diff --git a/orc-rt/lib/bedrock/GDBJITRegistrar.cpp b/orc-rt/lib/bedrock/GDBJITRegistrar.cpp
index 586f557eab4e2..9cfa01fdb5b72 100644
--- a/orc-rt/lib/bedrock/GDBJITRegistrar.cpp
+++ b/orc-rt/lib/bedrock/GDBJITRegistrar.cpp
@@ -45,15 +45,20 @@ static constexpr uint32_t JitDescriptorVersion = 1;
// We put information about the JIT'd object in this global, which the
// debugger reads. Make sure to specify the version statically, because the
// debugger checks the version before we can set it during runtime.
-ORC_RT_INTERFACE struct jit_descriptor __jit_debug_descriptor = {
+//
+// The symbols below are part of the debugger's contract with the runtime, so
+// they use ORC_RT_C_EXPORT rather than ORC_RT_EXPORT: they must stay exported
+// even in builds that hide the C++ API. (They are already within the extern "C"
+// block opened above, so no linkage specifier is needed here.)
+ORC_RT_C_EXPORT struct jit_descriptor __jit_debug_descriptor = {
JitDescriptorVersion, JIT_NOACTION, nullptr, nullptr};
// Debuggers that implement the GDB JIT interface put a special breakpoint in
// this function.
#if defined(_MSC_VER)
-ORC_RT_INTERFACE void __jit_debug_register_code() {}
+ORC_RT_C_EXPORT void __jit_debug_register_code() {}
#else
-ORC_RT_INTERFACE __attribute__((noinline)) void __jit_debug_register_code() {
+ORC_RT_C_EXPORT __attribute__((noinline)) void __jit_debug_register_code() {
// The noinline attribute above and the asm volatile below prevent calls to
// this function from being optimized out.
asm volatile("" ::: "memory");
More information about the llvm-commits
mailing list