Skip to content

Conversation

andrurogerz
Copy link
Contributor

@andrurogerz andrurogerz commented May 28, 2025

Purpose

This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the llvm-c interface with a new LLVM_C_ABI annotation, which behaves like the LLVM_ABI. This annotation currently has no meaningful impact on the LLVM build; however, it is a prerequisite to support an LLVM Windows DLL (shared library) build.

Overview

  1. Add a new llvm-c/Visibility.h header file that defines a new LLVM_C_ABI macro. The macro resolves to the proper DLL export/import annotation on Windows and a "default" visibility annotation elsewhere.
  2. Add a new LLVM_ENABLE_LLVM_C_EXPORT_ANNOTATIONS #cmakedefine that is used to gate the definition of LLVM_C_ABI.
  3. Remove the existing LLVM_C_ABI definition from llvm/Support/Compiler.h. Update the small number of LLVM_C_ABI references to get it from the new llvm-c/Visibility.h header.
  4. Code-mod annotate the public llvm-c interface using the Interface Definition Scanner (IDS) tool.
  5. Format the changes with clang-format.

Background

This effort is tracked in #109483. Additional context is provided in this discourse, and documentation for LLVM_ABI and related annotations is found in the LLVM repo here.

Validation

Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations:

  • Windows with MSVC
  • Windows with Clang
  • Linux with GCC
  • Linux with Clang
  • Darwin with Clang

@andrurogerz andrurogerz force-pushed the llvmdll-lib-llvm-c branch 2 times, most recently from 4c219aa to 29dbd9e Compare May 28, 2025 15:33
@andrurogerz andrurogerz force-pushed the llvmdll-lib-llvm-c branch 2 times, most recently from d478b2b to 1cf4a9d Compare June 4, 2025 14:07
@andrurogerz andrurogerz force-pushed the llvmdll-lib-llvm-c branch 3 times, most recently from a2e900b to cbf727c Compare June 24, 2025 19:12
@andrurogerz andrurogerz marked this pull request as ready for review June 24, 2025 21:15
@andrurogerz andrurogerz requested a review from compnerd June 24, 2025 21:16
@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

@llvm/pr-subscribers-llvm-support
@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-debuginfo

Author: Andrew Rogers (andrurogerz)

Changes

Purpose

This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the llvm-c interface with a new LLVM_C_ABI annotation, which behaves like the LLVM_ABI. This annotation currently has no meaningful impact on the LLVM build; however, it is a prerequisite to support an LLVM Windows DLL (shared library) build.

Overview

  1. Add a new llvm-c/Visibility.h header file that defines a new LLVM_C_ABI macro. The macro resolves to the proper DLL export/import annotation on Windows and a "default" visibility annotation elsewhere.
  2. Add a new LLVM_ENABLE_LLVM_C_EXPORT_ANNOTATIONS #cmakedefine that is used to gate the definition of LLVM_C_ABI.
  3. Remove the existing LLVM_C_ABI definition from llvm/Support/Compiler.h. Update the small number of LLVM_C_ABI references to get it from the new llvm-c/Visibility.h header.
  4. Code-mod annotate the public llvm-c interface using the Interface Definition Scanner (IDS) tool.
  5. Format the changes with clang-format.

Background

This effort is tracked in #109483. Additional context is provided in this discourse, and documentation for LLVM_ABI and related annotations is found in the LLVM repo here.

Validation

Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations:

  • Windows with MSVC
  • Windows with Clang
  • Linux with GCC
  • Linux with Clang
  • Darwin with Clang

Patch is 370.12 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/141701.diff

34 Files Affected:

  • (modified) llvm/CMakeLists.txt (+4)
  • (modified) llvm/include/llvm-c/Analysis.h (+8-5)
  • (modified) llvm/include/llvm-c/BitReader.h (+25-19)
  • (modified) llvm/include/llvm-c/BitWriter.h (+6-5)
  • (modified) llvm/include/llvm-c/Comdat.h (+8-5)
  • (modified) llvm/include/llvm-c/Core.h (+1152-973)
  • (modified) llvm/include/llvm-c/DebugInfo.h (+194-234)
  • (modified) llvm/include/llvm-c/Disassembler.h (+16-17)
  • (modified) llvm/include/llvm-c/Error.h (+8-7)
  • (modified) llvm/include/llvm-c/ErrorHandling.h (+4-3)
  • (modified) llvm/include/llvm-c/ExecutionEngine.h (+72-66)
  • (modified) llvm/include/llvm-c/IRReader.h (+5-3)
  • (modified) llvm/include/llvm-c/LLJIT.h (+33-30)
  • (modified) llvm/include/llvm-c/LLJITUtils.h (+2-1)
  • (modified) llvm/include/llvm-c/Linker.h (+2-1)
  • (modified) llvm/include/llvm-c/Object.h (+53-50)
  • (modified) llvm/include/llvm-c/Orc.h (+108-97)
  • (modified) llvm/include/llvm-c/OrcEE.h (+4-3)
  • (modified) llvm/include/llvm-c/Remarks.h (+37-27)
  • (modified) llvm/include/llvm-c/Support.h (+6-5)
  • (modified) llvm/include/llvm-c/Target.h (+50-38)
  • (modified) llvm/include/llvm-c/TargetMachine.h (+69-55)
  • (modified) llvm/include/llvm-c/Transforms/PassBuilder.h (+45-32)
  • (added) llvm/include/llvm-c/Visibility.h (+44)
  • (modified) llvm/include/llvm-c/blake3.h (+19-17)
  • (modified) llvm/include/llvm/Config/llvm-config.h.cmake (+3)
  • (modified) llvm/include/llvm/Support/Compiler.h (-5)
  • (modified) llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp (+1)
  • (modified) llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp (+1)
  • (modified) llvm/lib/Target/X86/MCA/X86CustomBehaviour.cpp (+1)
  • (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp (+1)
  • (modified) llvm/lib/Target/X86/TargetInfo/X86TargetInfo.cpp (+1)
  • (modified) llvm/lib/Target/X86/X86AsmPrinter.cpp (+1)
  • (modified) llvm/lib/Target/X86/X86TargetMachine.cpp (+1)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index ec8db6f0733f2..5aa4b9efccb7e 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -949,6 +949,10 @@ if (LLVM_BUILD_LLVM_DYLIB OR LLVM_BUILD_SHARED_LIBS OR LLVM_ENABLE_PLUGINS)
   set(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS ON)
 endif()
 
+# Because LLVM-C is built into the LLVM library, for now export its symbols
+# whenever LLVM symbols are exported.
+set(LLVM_ENABLE_LLVM_C_EXPORT_ANNOTATIONS ${LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS})
+
 option(LLVM_OPTIMIZED_TABLEGEN "Force TableGen to be built with optimization" OFF)
 if(CMAKE_CROSSCOMPILING OR (LLVM_OPTIMIZED_TABLEGEN AND (LLVM_ENABLE_ASSERTIONS OR CMAKE_CONFIGURATION_TYPES)))
   set(LLVM_USE_HOST_TOOLS ON)
diff --git a/llvm/include/llvm-c/Analysis.h b/llvm/include/llvm-c/Analysis.h
index 270b145a4d27e..01e1667b5232b 100644
--- a/llvm/include/llvm-c/Analysis.h
+++ b/llvm/include/llvm-c/Analysis.h
@@ -21,6 +21,7 @@
 
 #include "llvm-c/ExternC.h"
 #include "llvm-c/Types.h"
+#include "llvm-c/Visibility.h"
 
 LLVM_C_EXTERN_C_BEGIN
 
@@ -41,17 +42,19 @@ typedef enum {
 /* Verifies that a module is valid, taking the specified action if not.
    Optionally returns a human-readable description of any invalid constructs.
    OutMessage must be disposed with LLVMDisposeMessage. */
-LLVMBool LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
-                          char **OutMessage);
+LLVM_C_ABI LLVMBool LLVMVerifyModule(LLVMModuleRef M,
+                                     LLVMVerifierFailureAction Action,
+                                     char **OutMessage);
 
 /* Verifies that a single function is valid, taking the specified action. Useful
    for debugging. */
-LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
+LLVM_C_ABI LLVMBool LLVMVerifyFunction(LLVMValueRef Fn,
+                                       LLVMVerifierFailureAction Action);
 
 /* Open up a ghostview window that displays the CFG of the current function.
    Useful for debugging. */
-void LLVMViewFunctionCFG(LLVMValueRef Fn);
-void LLVMViewFunctionCFGOnly(LLVMValueRef Fn);
+LLVM_C_ABI void LLVMViewFunctionCFG(LLVMValueRef Fn);
+LLVM_C_ABI void LLVMViewFunctionCFGOnly(LLVMValueRef Fn);
 
 /**
  * @}
diff --git a/llvm/include/llvm-c/BitReader.h b/llvm/include/llvm-c/BitReader.h
index 088107468d4fb..9dcdbf436454f 100644
--- a/llvm/include/llvm-c/BitReader.h
+++ b/llvm/include/llvm-c/BitReader.h
@@ -21,6 +21,7 @@
 
 #include "llvm-c/ExternC.h"
 #include "llvm-c/Types.h"
+#include "llvm-c/Visibility.h"
 
 LLVM_C_EXTERN_C_BEGIN
 
@@ -36,30 +37,33 @@ LLVM_C_EXTERN_C_BEGIN
    Optionally returns a human-readable error message via OutMessage.
 
    This is deprecated. Use LLVMParseBitcode2. */
-LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
-                          char **OutMessage);
+LLVM_C_ABI LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
+                                     LLVMModuleRef *OutModule,
+                                     char **OutMessage);
 
 /* Builds a module from the bitcode in the specified memory buffer, returning a
    reference to the module via the OutModule parameter. Returns 0 on success. */
-LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
-                           LLVMModuleRef *OutModule);
+LLVM_C_ABI LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
+                                      LLVMModuleRef *OutModule);
 
 /* This is deprecated. Use LLVMParseBitcodeInContext2. */
-LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
-                                   LLVMMemoryBufferRef MemBuf,
-                                   LLVMModuleRef *OutModule, char **OutMessage);
+LLVM_C_ABI LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
+                                              LLVMMemoryBufferRef MemBuf,
+                                              LLVMModuleRef *OutModule,
+                                              char **OutMessage);
 
-LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
-                                    LLVMMemoryBufferRef MemBuf,
-                                    LLVMModuleRef *OutModule);
+LLVM_C_ABI LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
+                                               LLVMMemoryBufferRef MemBuf,
+                                               LLVMModuleRef *OutModule);
 
 /** Reads a module from the specified path, returning via the OutMP parameter
     a module provider which performs lazy deserialization. Returns 0 on success.
     Optionally returns a human-readable error message via OutMessage.
     This is deprecated. Use LLVMGetBitcodeModuleInContext2. */
-LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
-                                       LLVMMemoryBufferRef MemBuf,
-                                       LLVMModuleRef *OutM, char **OutMessage);
+LLVM_C_ABI LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+                                                  LLVMMemoryBufferRef MemBuf,
+                                                  LLVMModuleRef *OutM,
+                                                  char **OutMessage);
 
 /** Reads a module from the given memory buffer, returning via the OutMP
  * parameter a module provider which performs lazy deserialization.
@@ -68,15 +72,17 @@ LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
  *
  * Takes ownership of \p MemBuf if (and only if) the module was read
  * successfully. */
-LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
-                                        LLVMMemoryBufferRef MemBuf,
-                                        LLVMModuleRef *OutM);
+LLVM_C_ABI LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
+                                                   LLVMMemoryBufferRef MemBuf,
+                                                   LLVMModuleRef *OutM);
 
 /* This is deprecated. Use LLVMGetBitcodeModule2. */
-LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
-                              char **OutMessage);
+LLVM_C_ABI LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,
+                                         LLVMModuleRef *OutM,
+                                         char **OutMessage);
 
-LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM);
+LLVM_C_ABI LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
+                                          LLVMModuleRef *OutM);
 
 /**
  * @}
diff --git a/llvm/include/llvm-c/BitWriter.h b/llvm/include/llvm-c/BitWriter.h
index ea84b6593d126..71d482b6be070 100644
--- a/llvm/include/llvm-c/BitWriter.h
+++ b/llvm/include/llvm-c/BitWriter.h
@@ -21,6 +21,7 @@
 
 #include "llvm-c/ExternC.h"
 #include "llvm-c/Types.h"
+#include "llvm-c/Visibility.h"
 
 LLVM_C_EXTERN_C_BEGIN
 
@@ -34,18 +35,18 @@ LLVM_C_EXTERN_C_BEGIN
 /*===-- Operations on modules ---------------------------------------------===*/
 
 /** Writes a module to the specified path. Returns 0 on success. */
-int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path);
+LLVM_C_ABI int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path);
 
 /** Writes a module to an open file descriptor. Returns 0 on success. */
-int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
-                         int Unbuffered);
+LLVM_C_ABI int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
+                                    int Unbuffered);
 
 /** Deprecated for LLVMWriteBitcodeToFD. Writes a module to an open file
     descriptor. Returns 0 on success. Closes the Handle. */
-int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
+LLVM_C_ABI int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
 
 /** Writes a module to a new memory buffer and returns it. */
-LLVMMemoryBufferRef LLVMWriteBitcodeToMemoryBuffer(LLVMModuleRef M);
+LLVM_C_ABI LLVMMemoryBufferRef LLVMWriteBitcodeToMemoryBuffer(LLVMModuleRef M);
 
 /**
  * @}
diff --git a/llvm/include/llvm-c/Comdat.h b/llvm/include/llvm-c/Comdat.h
index 8002bc0581af7..cf13f8507440e 100644
--- a/llvm/include/llvm-c/Comdat.h
+++ b/llvm/include/llvm-c/Comdat.h
@@ -16,6 +16,7 @@
 
 #include "llvm-c/ExternC.h"
 #include "llvm-c/Types.h"
+#include "llvm-c/Visibility.h"
 
 LLVM_C_EXTERN_C_BEGIN
 
@@ -43,35 +44,37 @@ typedef enum {
  *
  * @see llvm::Module::getOrInsertComdat()
  */
-LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M, const char *Name);
+LLVM_C_ABI LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M,
+                                               const char *Name);
 
 /**
  * Get the Comdat assigned to the given global object.
  *
  * @see llvm::GlobalObject::getComdat()
  */
-LLVMComdatRef LLVMGetComdat(LLVMValueRef V);
+LLVM_C_ABI LLVMComdatRef LLVMGetComdat(LLVMValueRef V);
 
 /**
  * Assign the Comdat to the given global object.
  *
  * @see llvm::GlobalObject::setComdat()
  */
-void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C);
+LLVM_C_ABI void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C);
 
 /*
  * Get the conflict resolution selection kind for the Comdat.
  *
  * @see llvm::Comdat::getSelectionKind()
  */
-LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C);
+LLVM_C_ABI LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C);
 
 /*
  * Set the conflict resolution selection kind for the Comdat.
  *
  * @see llvm::Comdat::setSelectionKind()
  */
-void LLVMSetComdatSelectionKind(LLVMComdatRef C, LLVMComdatSelectionKind Kind);
+LLVM_C_ABI void LLVMSetComdatSelectionKind(LLVMComdatRef C,
+                                           LLVMComdatSelectionKind Kind);
 
 /**
  * @}
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 3f30ed92997b4..d645646289025 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -18,6 +18,7 @@
 #include "llvm-c/Deprecated.h"
 #include "llvm-c/ErrorHandling.h"
 #include "llvm-c/ExternC.h"
+#include "llvm-c/Visibility.h"
 
 #include "llvm-c/Types.h"
 
@@ -536,7 +537,7 @@ typedef unsigned LLVMGEPNoWrapFlags;
 /** Deallocate and destroy all ManagedStatic variables.
     @see llvm::llvm_shutdown
     @see ManagedStatic */
-void LLVMShutdown(void);
+LLVM_C_ABI void LLVMShutdown(void);
 
 /*===-- Version query -----------------------------------------------------===*/
 
@@ -546,12 +547,13 @@ void LLVMShutdown(void);
  * The version components are returned via the function's three output
  * parameters or skipped if a NULL pointer was supplied.
  */
-void LLVMGetVersion(unsigned *Major, unsigned *Minor, unsigned *Patch);
+LLVM_C_ABI void LLVMGetVersion(unsigned *Major, unsigned *Minor,
+                               unsigned *Patch);
 
 /*===-- Error handling ----------------------------------------------------===*/
 
-char *LLVMCreateMessage(const char *Message);
-void LLVMDisposeMessage(char *Message);
+LLVM_C_ABI char *LLVMCreateMessage(const char *Message);
+LLVM_C_ABI void LLVMDisposeMessage(char *Message);
 
 /**
  * @defgroup LLVMCCoreContext Contexts
@@ -574,44 +576,46 @@ typedef void (*LLVMYieldCallback)(LLVMContextRef, void *);
  * Every call to this function should be paired with a call to
  * LLVMContextDispose() or the context will leak memory.
  */
-LLVMContextRef LLVMContextCreate(void);
+LLVM_C_ABI LLVMContextRef LLVMContextCreate(void);
 
 /**
  * Obtain the global context instance.
  */
-LLVMContextRef LLVMGetGlobalContext(void);
+LLVM_C_ABI LLVMContextRef LLVMGetGlobalContext(void);
 
 /**
  * Set the diagnostic handler for this context.
  */
-void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
-                                     LLVMDiagnosticHandler Handler,
-                                     void *DiagnosticContext);
+LLVM_C_ABI void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
+                                                LLVMDiagnosticHandler Handler,
+                                                void *DiagnosticContext);
 
 /**
  * Get the diagnostic handler of this context.
  */
-LLVMDiagnosticHandler LLVMContextGetDiagnosticHandler(LLVMContextRef C);
+LLVM_C_ABI LLVMDiagnosticHandler
+LLVMContextGetDiagnosticHandler(LLVMContextRef C);
 
 /**
  * Get the diagnostic context of this context.
  */
-void *LLVMContextGetDiagnosticContext(LLVMContextRef C);
+LLVM_C_ABI void *LLVMContextGetDiagnosticContext(LLVMContextRef C);
 
 /**
  * Set the yield callback function for this context.
  *
  * @see LLVMContext::setYieldCallback()
  */
-void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback,
-                                 void *OpaqueHandle);
+LLVM_C_ABI void LLVMContextSetYieldCallback(LLVMContextRef C,
+                                            LLVMYieldCallback Callback,
+                                            void *OpaqueHandle);
 
 /**
  * Retrieve whether the given context is set to discard all value names.
  *
  * @see LLVMContext::shouldDiscardValueNames()
  */
-LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C);
+LLVM_C_ABI LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C);
 
 /**
  * Set whether the given context discards all value names.
@@ -621,7 +625,8 @@ LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C);
  *
  * @see LLVMContext::setDiscardValueNames()
  */
-void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard);
+LLVM_C_ABI void LLVMContextSetDiscardValueNames(LLVMContextRef C,
+                                                LLVMBool Discard);
 
 /**
  * Destroy a context instance.
@@ -629,7 +634,7 @@ void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard);
  * This should be called for every call to LLVMContextCreate() or memory
  * will be leaked.
  */
-void LLVMContextDispose(LLVMContextRef C);
+LLVM_C_ABI void LLVMContextDispose(LLVMContextRef C);
 
 /**
  * Return a string representation of the DiagnosticInfo. Use
@@ -637,23 +642,25 @@ void LLVMContextDispose(LLVMContextRef C);
  *
  * @see DiagnosticInfo::print()
  */
-char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI);
+LLVM_C_ABI char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI);
 
 /**
  * Return an enum LLVMDiagnosticSeverity.
  *
  * @see DiagnosticInfo::getSeverity()
  */
-LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI);
+LLVM_C_ABI LLVMDiagnosticSeverity
+LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI);
 
-unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name,
-                                  unsigned SLen);
-unsigned LLVMGetMDKindID(const char *Name, unsigned SLen);
+LLVM_C_ABI unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name,
+                                             unsigned SLen);
+LLVM_C_ABI unsigned LLVMGetMDKindID(const char *Name, unsigned SLen);
 
 /**
  * Maps a synchronization scope name to a ID unique within this context.
  */
-unsigned LLVMGetSyncScopeID(LLVMContextRef C, const char *Name, size_t SLen);
+LLVM_C_ABI unsigned LLVMGetSyncScopeID(LLVMContextRef C, const char *Name,
+                                       size_t SLen);
 
 /**
  * Return an unique id given the name of a enum attribute,
@@ -666,36 +673,39 @@ unsigned LLVMGetSyncScopeID(LLVMContextRef C, const char *Name, size_t SLen);
  * NB: Attribute names and/or id are subject to change without
  * going through the C API deprecation cycle.
  */
-unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen);
-unsigned LLVMGetLastEnumAttributeKind(void);
+LLVM_C_ABI unsigned LLVMGetEnumAttributeKindForName(const char *Name,
+                                                    size_t SLen);
+LLVM_C_ABI unsigned LLVMGetLastEnumAttributeKind(void);
 
 /**
  * Create an enum attribute.
  */
-LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID,
-                                         uint64_t Val);
+LLVM_C_ABI LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C,
+                                                    unsigned KindID,
+                                                    uint64_t Val);
 
 /**
  * Get the unique id corresponding to the enum attribute
  * passed as argument.
  */
-unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A);
+LLVM_C_ABI unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A);
 
 /**
  * Get the enum attribute's value. 0 is returned if none exists.
  */
-uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A);
+LLVM_C_ABI uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A);
 
 /**
  * Create a type attribute
  */
-LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
-                                         LLVMTypeRef type_ref);
+LLVM_C_ABI LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C,
+                                                    unsigned KindID,
+                                                    LLVMTypeRef type_ref);
 
 /**
  * Get the type attribute's value.
  */
-LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A);
+LLVM_C_ABI LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A);
 
 /**
  * Create a ConstantRange attribute.
@@ -703,40 +713,42 @@ LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A);
  * LowerWords and UpperWords need to be NumBits divided by 64 rounded up
  * elements long.
  */
-LLVMAttributeRef LLVMCreateConstantRangeAttribute(LLVMContextRef C,
-                                                  unsigned KindID,
-                                                  unsigned NumBits,
-                                                  const uint64_t LowerWords[],
-                                                  const uint64_t UpperWords[]);
+LLVM_C_ABI LLVMAttributeRef LLVMCreateConstantRangeAttribute(
+    LLVMContextRef C, unsigned KindID, unsigned NumBits,
+    const uint64_t LowerWords[], const uint64_t UpperWords[]);
 
 /**
  * Create a string attribute.
  */
-LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
-                                           const char *K, unsigned KLength,
-                                           const char *V, unsigned VLength);
+LLVM_C_ABI LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
+                                                      const char *K,
+                                                      unsigned KLength,
+                                                      const char *V,
+                                                      unsigned VLength);
 
 /**
  * Get the string attribute's kind.
  */
-const char *LLVMGetStringAttributeKind(LLVMAttributeRef A, unsigned *Length);
+LLVM_C_ABI const char *LLVMGetStringAttributeKind(LLVMAttributeRef A,
+                                                  unsigned *Length);
 
 /**
  * Get the string attribute's value.
  */
-const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length);
+LLVM_C_ABI const char *LLVMGetStringAttributeValue(LLVMAttributeRef A,
+                                                   unsigned *Length);
 
 /**
  * Check for the different types of attributes.
  */
-LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A);
-LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A);
-LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A);
+LLVM_C_ABI LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A);
+LLVM_C_ABI LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A);
+LLVM_C_ABI LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A);
 
 /**
  * Obtain a Type from a context by its registered name.
  */
-LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name);
+LLVM_C_ABI LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name);
 
 /**
  * @}
@@ -761,7 +773,7 @@ LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name);
  * Every invocation should be paired with LLVMDisposeModule() or memory
  * will be leaked.
  */
-LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
+LLVM_C_ABI LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
 
 /**
  * Create a new, empty module in a specific context.
@@ -769,12 +781,12 @@ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
  * Every invocation should be paired with LLVMDisposeModule() or memory
  * will be leaked.
  */
-LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID,
-                       ...
[truncated]

@andrurogerz andrurogerz force-pushed the llvmdll-lib-llvm-c branch from cbf727c to e10f4f8 Compare July 7, 2025 18:13
@andrurogerz andrurogerz requested a review from compnerd July 7, 2025 18:19
@andrurogerz
Copy link
Contributor Author

@compnerd I would like to revisit the LLVMRemarkVersion annotation in a follow-up if you're OK with that.

@compnerd compnerd merged commit 0580563 into llvm:main Jul 8, 2025
9 checks passed
@andrurogerz andrurogerz deleted the llvmdll-lib-llvm-c branch July 23, 2025 19:41
nikic pushed a commit that referenced this pull request Jul 24, 2025
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `Demangle` interface with
a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This
annotation currently has no meaningful impact on the LLVM build;
however, it is a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Overview

1. Add a new `Demangle/Visibility.h` header file that defines a new
`DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import
annotation on Windows and a "default" visibility annotation elsewhere.
2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine`
that is used to gate the definition of `DEMANGLE_ABI`.
3. Code-mod annotate the public `Demangle` interface using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool.
4. Manually fix-up `#include` statements for consistency.
5. Format the changes with `clang-format`.
6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle`
that always defines `DEMANGLE_ABI` to nothing.
7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h`
instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm
copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying
`Visibillity.h` as is already the case for `DemangleConfig.h`.

## Background

This PR follows the pattern established with the `llvm-c` changes made
in #141701.

This effort is tracked in #109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---------

Co-authored-by: Louis Dionne <[email protected]>
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Jul 28, 2025
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `Demangle` interface with
a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This
annotation currently has no meaningful impact on the LLVM build;
however, it is a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Overview

1. Add a new `Demangle/Visibility.h` header file that defines a new
`DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import
annotation on Windows and a "default" visibility annotation elsewhere.
2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine`
that is used to gate the definition of `DEMANGLE_ABI`.
3. Code-mod annotate the public `Demangle` interface using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool.
4. Manually fix-up `#include` statements for consistency.
5. Format the changes with `clang-format`.
6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle`
that always defines `DEMANGLE_ABI` to nothing.
7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h`
instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm
copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying
`Visibillity.h` as is already the case for `DemangleConfig.h`.

## Background

This PR follows the pattern established with the `llvm-c` changes made
in llvm#141701.

This effort is tracked in llvm#109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---------

Co-authored-by: Louis Dionne <[email protected]>
andrurogerz added a commit to andrurogerz/llvm-project that referenced this pull request Aug 4, 2025
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `Demangle` interface with
a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This
annotation currently has no meaningful impact on the LLVM build;
however, it is a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Overview

1. Add a new `Demangle/Visibility.h` header file that defines a new
`DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import
annotation on Windows and a "default" visibility annotation elsewhere.
2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine`
that is used to gate the definition of `DEMANGLE_ABI`.
3. Code-mod annotate the public `Demangle` interface using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool.
4. Manually fix-up `#include` statements for consistency.
5. Format the changes with `clang-format`.
6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle`
that always defines `DEMANGLE_ABI` to nothing.
7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h`
instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm
copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying
`Visibillity.h` as is already the case for `DemangleConfig.h`.

## Background

This PR follows the pattern established with the `llvm-c` changes made
in llvm#141701.

This effort is tracked in llvm#109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---------

Co-authored-by: Louis Dionne <[email protected]>
andrurogerz added a commit to andrurogerz/llvm-project that referenced this pull request Aug 5, 2025
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `Demangle` interface with
a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This
annotation currently has no meaningful impact on the LLVM build;
however, it is a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Overview

1. Add a new `Demangle/Visibility.h` header file that defines a new
`DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import
annotation on Windows and a "default" visibility annotation elsewhere.
2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine`
that is used to gate the definition of `DEMANGLE_ABI`.
3. Code-mod annotate the public `Demangle` interface using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool.
4. Manually fix-up `#include` statements for consistency.
5. Format the changes with `clang-format`.
6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle`
that always defines `DEMANGLE_ABI` to nothing.
7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h`
instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm
copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying
`Visibillity.h` as is already the case for `DemangleConfig.h`.

## Background

This PR follows the pattern established with the `llvm-c` changes made
in llvm#141701.

This effort is tracked in llvm#109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---------

Co-authored-by: Louis Dionne <[email protected]>
SquallATF pushed a commit to SquallATF/llvm-project that referenced this pull request Aug 28, 2025
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `Demangle` interface with
a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This
annotation currently has no meaningful impact on the LLVM build;
however, it is a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Overview

1. Add a new `Demangle/Visibility.h` header file that defines a new
`DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import
annotation on Windows and a "default" visibility annotation elsewhere.
2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine`
that is used to gate the definition of `DEMANGLE_ABI`.
3. Code-mod annotate the public `Demangle` interface using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool.
4. Manually fix-up `#include` statements for consistency.
5. Format the changes with `clang-format`.
6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle`
that always defines `DEMANGLE_ABI` to nothing.
7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h`
instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm
copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying
`Visibillity.h` as is already the case for `DemangleConfig.h`.

## Background

This PR follows the pattern established with the `llvm-c` changes made
in llvm#141701.

This effort is tracked in llvm#109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---------

Co-authored-by: Louis Dionne <[email protected]>
SquallATF pushed a commit to SquallATF/llvm-project that referenced this pull request Sep 10, 2025
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `Demangle` interface with
a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This
annotation currently has no meaningful impact on the LLVM build;
however, it is a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Overview

1. Add a new `Demangle/Visibility.h` header file that defines a new
`DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import
annotation on Windows and a "default" visibility annotation elsewhere.
2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine`
that is used to gate the definition of `DEMANGLE_ABI`.
3. Code-mod annotate the public `Demangle` interface using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool.
4. Manually fix-up `#include` statements for consistency.
5. Format the changes with `clang-format`.
6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle`
that always defines `DEMANGLE_ABI` to nothing.
7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h`
instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm
copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying
`Visibillity.h` as is already the case for `DemangleConfig.h`.

## Background

This PR follows the pattern established with the `llvm-c` changes made
in llvm#141701.

This effort is tracked in llvm#109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---------

Co-authored-by: Louis Dionne <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants