Skip to content

Commit

Permalink
[Clang] Add explicit visibility symbol macros (#108276)
Browse files Browse the repository at this point in the history
This is part of the effort to support for enabling plugins on windows by
adding better support for building llvm and clang as a DLL. These macros
are similar to the ones i added in #96630, but are for clang.
Added explicit symbol visibility macros definitions that are defined in
a new header and will be used to for shared library builds of clang to
export
symbols. 
Updated clang cmake to define a macro to enable the symbol visibility
macros and explicitly disable them for clang tools that always use
static linking.

---------

Co-authored-by: Aaron Ballman <[email protected]>
  • Loading branch information
fsfod and AaronBallman authored Oct 14, 2024
1 parent eb83e4a commit 09fa2f0
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
11 changes: 11 additions & 0 deletions clang/cmake/modules/AddClang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ macro(add_clang_library name)
endif()
llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs})

if(MSVC AND NOT CLANG_LINK_CLANG_DYLIB)
# Make sure all consumers also turn off visibility macros so there not trying to dllimport symbols.
target_compile_definitions(${name} PUBLIC CLANG_BUILD_STATIC)
if(TARGET "obj.${name}")
target_compile_definitions("obj.${name}" PUBLIC CLANG_BUILD_STATIC)
endif()
elseif(NOT ARG_SHARED AND NOT ARG_STATIC)
# Clang component libraries linked in to clang-cpp are declared without SHARED or STATIC
target_compile_definitions("obj.${name}" PUBLIC CLANG_EXPORTS)
endif()

set(libs ${name})
if(ARG_SHARED AND ARG_STATIC)
list(APPEND libs ${name}_static)
Expand Down
63 changes: 63 additions & 0 deletions clang/include/clang/Support/Compiler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===-- clang/Support/Compiler.h - Compiler abstraction support -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines explicit visibility macros used to export symbols from
// clang-cpp
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_SUPPORT_COMPILER_H
#define CLANG_SUPPORT_COMPILER_H

#include "llvm/Support/Compiler.h"

/// CLANG_ABI is the main export/visibility macro to mark something as
/// explicitly exported when clang is built as a shared library with everything
/// else that is unannotated having hidden visibility.
///
/// CLANG_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.
///
/// CLANG_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.
#ifndef CLANG_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 CLANG_ABI_NOT_EXPORTED
// 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(CLANG_BUILD_STATIC)
#define CLANG_ABI
#define CLANG_TEMPLATE_ABI
#define CLANG_EXPORT_TEMPLATE
#elif defined(_WIN32) && !defined(__MINGW32__)
#if defined(CLANG_EXPORTS)
#define CLANG_ABI __declspec(dllexport)
#define CLANG_TEMPLATE_ABI
#define CLANG_EXPORT_TEMPLATE __declspec(dllexport)
#else
#define CLANG_ABI __declspec(dllimport)
#define CLANG_TEMPLATE_ABI __declspec(dllimport)
#define CLANG_EXPORT_TEMPLATE
#endif
#elif defined(__ELF__) || defined(__MINGW32__) || defined(_AIX)
#define CLANG_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define CLANG_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define CLANG_EXPORT_TEMPLATE
#elif defined(__MACH__) || defined(__WASM__)
#define CLANG_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define CLANG_TEMPLATE_ABI
#define CLANG_EXPORT_TEMPLATE
#endif
#endif

#endif
4 changes: 4 additions & 0 deletions clang/tools/libclang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ if(ENABLE_SHARED)
PROPERTIES
VERSION ${LIBCLANG_LIBRARY_VERSION}
DEFINE_SYMBOL _CINDEX_LIB_)
# Avoid declaring clang c++ symbols that are statically linked into libclang as dllimport'ed.
# If llvm/libclang-cpp dll is also being built for windows clang c++ symbols will still be
# implicitly be exported from libclang.
target_compile_definitions(libclang PRIVATE CLANG_BUILD_STATIC)
elseif(APPLE)
set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
set(LIBCLANG_LINK_FLAGS "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
Expand Down

0 comments on commit 09fa2f0

Please sign in to comment.