[llvm] Initial changes for llvm shared library build using explicit visibility annotations (PR #96630)

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 31 13:20:08 PDT 2024


================
@@ -125,18 +126,89 @@
 #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
 #endif
 
-
-#if (!(defined(_WIN32) || defined(__CYGWIN__)) ||                              \
-     (defined(__MINGW32__) && defined(__clang__)))
-#define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
 #if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
 #define LLVM_EXTERNAL_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
 #else
 #define LLVM_EXTERNAL_VISIBILITY
 #endif
+
+#if (!(defined(_WIN32) || defined(__CYGWIN__)) ||                              \
+     (defined(__MINGW32__) && defined(__clang__)))
+#define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
+#define LLVM_ALWAYS_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
+#elif defined(_WIN32)
+#define LLVM_ALWAYS_EXPORT __declspec(dllexport)
+#define LLVM_LIBRARY_VISIBILITY
 #else
 #define LLVM_LIBRARY_VISIBILITY
-#define LLVM_EXTERNAL_VISIBILITY
+#define LLVM_ALWAYS_EXPORT
+#endif
+
+/// LLVM_ABI is the main export/visibility macro to mark something as explicitly
+/// exported when llvm is built as a shared library with everything else that is
+/// unannotated will have internal visibility.
+///
+/// LLVM_EXPORT_TEMPLATE is used on explicit template instantiations in source
+/// files that were declared extern in a header. This macro is only set as a
+/// compiler export attribute on windows, on other platforms it does nothing.
+///
+/// LLVM_TEMPLATE_ABI is for annotating extern template declarations in headers
+/// for both functions and classes. On windows its turned in to dllimport for
+/// library consumers, for other platforms its a default visibility attribute.
+///
+/// LLVM_C_ABI is used to annotated functions and data that need to be exported
+/// for the libllvm-c API. This used both for the llvm-c headers and for the
+/// functions declared in the different Target's c++ source files that don't
+/// include the header forward declaring them.
+#ifndef LLVM_ABI_GENERATING_ANNOTATIONS
+// Marker to add to classes or functions in public headers that should not have
+// export macros added to them by the clang tool
+#define LLVM_ABI_NOT_EXPORTED
+#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS) ||       \
+    defined(LLVM_ENABLE_PLUGINS)
+// Some libraries like those for tablegen are linked in to tools that used
+// in the build so can't depend on the llvm shared library. If export macros
+// were left enabled when building these we would get duplicate or
+// missing symbol linker errors on windows.
+#if defined(LLVM_BUILD_STATIC)
+#define LLVM_ABI
+#define LLVM_TEMPLATE_ABI
+#define LLVM_EXPORT_TEMPLATE
+#define LLVM_ABI_EXPORT
+#define LLVM_ABI_IMPORT
----------------
compnerd wrote:

Sorry, I'm not sure I understand. The `LLVM_ABI_IMPORT` doesn't really make sense, IMO. Consider the following:

```c
void ABI __fastcall function(void);
```

This function declaration should be annotated as `__declspec(dllexport)` when being *defined*. However, when declared as an external symbol, the _only_ difference would be that it would be annotated `__declspec(dllimport)`. The rest of the signature should be untouched (including the calling convention). You do not want to have your own declaration as that allows for it to go out of sync. So the definition of `ABI` changes between the build and use.

https://github.com/llvm/llvm-project/pull/96630


More information about the llvm-commits mailing list