diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index d681b1ccab6299..3669026d5325ca 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -839,15 +839,20 @@ endif() if(MSVC) option(LLVM_BUILD_LLVM_C_DYLIB "Build LLVM-C.dll (Windows only)" ON) - # Set this variable to OFF here so it can't be set with a command-line - # argument. - set (LLVM_LINK_LLVM_DYLIB OFF) + if(NOT LLVM_BUILD_LLVM_DYLIB_VIS) + # Set this variable to OFF here so it can't be set with a command-line + # argument. + set (LLVM_LINK_LLVM_DYLIB OFF) + endif() if (BUILD_SHARED_LIBS) message(FATAL_ERROR "BUILD_SHARED_LIBS options is not supported on Windows.") endif() -else() - option(LLVM_LINK_LLVM_DYLIB "Link tools against the libllvm dynamic library" OFF) + else() option(LLVM_BUILD_LLVM_C_DYLIB "Build libllvm-c re-export library (Darwin only)" OFF) +endif() + +if(NOT MSVC OR LLVM_BUILD_LLVM_DYLIB_VIS) + option(LLVM_LINK_LLVM_DYLIB "Link tools against the libllvm dynamic library" OFF) set(LLVM_BUILD_LLVM_DYLIB_default OFF) if(LLVM_LINK_LLVM_DYLIB OR LLVM_BUILD_LLVM_C_DYLIB) set(LLVM_BUILD_LLVM_DYLIB_default ON) @@ -855,6 +860,15 @@ else() option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" ${LLVM_BUILD_LLVM_DYLIB_default}) endif() +# Build llvm dynamic library with explicit symbol visibility on windows and default hidden symbol visibility on Linux +if(LLVM_BUILD_LLVM_DYLIB_VIS) + set(LLVM_BUILD_LLVM_DYLIB ON) + if(MSVC) + option(LLVM_DYLIB_EXPORT_INLINES "Force inline members of class to be dll exported when + building with clang-cl so the libllvm dll is compatible with MSVC" OFF) + endif() +endif() + if (LLVM_LINK_LLVM_DYLIB AND BUILD_SHARED_LIBS) message(FATAL_ERROR "Cannot enable BUILD_SHARED_LIBS with LLVM_LINK_LLVM_DYLIB. We recommend disabling BUILD_SHARED_LIBS.") endif() diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 99959ecfae9cba..c62b5649facae1 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -606,6 +606,10 @@ function(llvm_add_library name) endif() endforeach() endif() + + if(ARG_DISABLE_LLVM_LINK_LLVM_DYLIB) + target_compile_definitions(${obj_name} PRIVATE LLVM_BUILD_STATIC) + endif() endif() if(ARG_SHARED AND ARG_STATIC) @@ -641,8 +645,36 @@ function(llvm_add_library name) endif() set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Libraries") + ## If were compiling with clang-cl use /Zc:dllexportInlines- to exclude inline + ## class members from being dllexport'ed to reduce compile time. + ## This will also keep us below the 64k exported symbol limit + ## https://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html + if(LLVM_BUILD_LLVM_DYLIB AND NOT LLVM_DYLIB_EXPORT_INLINES AND + MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang) + target_compile_options(${name} PUBLIC /Zc:dllexportInlines-) + if(TARGET ${obj_name}) + target_compile_options(${obj_name} PUBLIC /Zc:dllexportInlines-) + endif() + endif() + if(ARG_COMPONENT_LIB) set_target_properties(${name} PROPERTIES LLVM_COMPONENT TRUE) + if(LLVM_BUILD_LLVM_DYLIB OR BUILD_SHARED_LIBS) + target_compile_definitions(${name} PRIVATE LLVM_EXPORTS) + endif() + + # When building shared objects for each target there are some internal APIs + # that are used across shared objects which we can't hide. + if (LLVM_BUILD_LLVM_DYLIB_VIS AND NOT BUILD_SHARED_LIBS AND NOT APPLE AND + (NOT (WIN32 OR CYGWIN) OR (MINGW AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND + NOT (${CMAKE_SYSTEM_NAME} MATCHES "AIX") AND + NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET) + + set_target_properties(${name} PROPERTIES + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN YES) + endif() set_property(GLOBAL APPEND PROPERTY LLVM_COMPONENT_LIBS ${name}) endif() @@ -741,6 +773,9 @@ function(llvm_add_library name) if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB) set(llvm_libs LLVM) else() + if(ARG_DISABLE_LLVM_LINK_LLVM_DYLIB) + target_compile_definitions(${name} PRIVATE LLVM_BUILD_STATIC) + endif() llvm_map_components_to_libnames(llvm_libs ${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS} @@ -1116,6 +1151,16 @@ macro(add_llvm_executable name) if (ARG_EXPORT_SYMBOLS) export_executable_symbols(${name}) endif() + + if(ARG_DISABLE_LLVM_LINK_LLVM_DYLIB OR NOT LLVM_LINK_LLVM_DYLIB) + target_compile_definitions(${name} PRIVATE LLVM_BUILD_STATIC) + endif() + + if(LLVM_BUILD_LLVM_DYLIB_VIS AND NOT LLVM_DYLIB_EXPORT_INLINES AND + MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang) + # This has to match how the libraries the executable is linked to are built or there be linker errors. + target_compile_options(${name} PRIVATE /Zc:dllexportInlines-) + endif() endmacro(add_llvm_executable name) # add_llvm_pass_plugin(name [NO_MODULE] ...) diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index bdbd36174fc7a9..ed13a82905b4e3 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -754,6 +754,12 @@ if (MSVC) # any code that uses the LLVM_ALIGNAS macro), so this is must be disabled to # avoid unwanted alignment warnings. -wd4324 # Suppress 'structure was padded due to __declspec(align())' + # This is triggered for every variable that is a template type of a class even + # if there private when the class is dllexport'ed + -wd4251 # Suppress 'needs to have dll-interface to be used by clients' + # We only putting dll export on classes with out of line members so this + # warning gets triggered a lot for bases we haven't exported' + -wd4275 # non dll-interface class used as base for dll-interface class # Promoted warnings. -w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning. diff --git a/llvm/include/llvm/ADT/Any.h b/llvm/include/llvm/ADT/Any.h index 89b4d9e5e4052b..88dbce96c2c3d8 100644 --- a/llvm/include/llvm/ADT/Any.h +++ b/llvm/include/llvm/ADT/Any.h @@ -25,7 +25,7 @@ namespace llvm { -class LLVM_EXTERNAL_VISIBILITY Any { +class LLVM_ABI Any { // The `Typeid::Id` static data member below is a globally unique // identifier for the type `T`. It is explicitly marked with default diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h index a8bbf2c578af9b..46b4413852d38a 100644 --- a/llvm/include/llvm/Analysis/LazyCallGraph.h +++ b/llvm/include/llvm/Analysis/LazyCallGraph.h @@ -416,7 +416,7 @@ class LazyCallGraph { /// outer structure. SCCs do not support mutation of the call graph, that /// must be done through the containing \c RefSCC in order to fully reason /// about the ordering and connections of the graph. - class LLVM_EXTERNAL_VISIBILITY SCC { + class LLVM_ABI SCC { friend class LazyCallGraph; friend class LazyCallGraph::Node; diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index 054206925483c5..dca437153b254b 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -41,7 +41,7 @@ extern template class LoopBase; /// Represents a single loop in the control flow graph. Note that not all SCCs /// in the CFG are necessarily loops. -class LLVM_EXTERNAL_VISIBILITY Loop : public LoopBase { +class LLVM_ABI Loop : public LoopBase { public: /// A range representing the start and end location of a loop. class LocRange { diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h index 3b33dd505ddeb2..22d5cb6ca15f50 100644 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopNestAnalysis.h @@ -25,7 +25,7 @@ using LoopVectorTy = SmallVector; class LPMUpdater; /// This class represents a loop nest and can be used to query its properties. -class LLVM_EXTERNAL_VISIBILITY LoopNest { +class LLVM_ABI LoopNest { public: using InstrVectorTy = SmallVector; diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 9845520d6db6b2..aeb72ca24d79b8 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -254,7 +254,7 @@ struct LandingPadInfo { : LandingPadBlock(MBB) {} }; -class LLVM_EXTERNAL_VISIBILITY MachineFunction { +class LLVM_ABI MachineFunction { Function &F; const LLVMTargetMachine &Target; const TargetSubtargetInfo *STI; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index 4abf978687d9d5..75b73e06878a96 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -60,8 +60,7 @@ class User; class BranchProbabilityInfo; class BlockFrequencyInfo; -class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject, - public ilist_node { +class LLVM_ABI Function : public GlobalObject, public ilist_node { public: using BasicBlockListType = SymbolTableList; diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index e8905f7ed393ca..528e19af5518df 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -62,7 +62,7 @@ class VersionTuple; /// constant references to global variables in the module. When a global /// variable is destroyed, it should have no entries in the GlobalList. /// The main container class for the LLVM Intermediate Representation. -class LLVM_EXTERNAL_VISIBILITY Module { +class LLVM_ABI Module { /// @name Types And Enumerations /// @{ public: diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h index d8e3794babc744..13d6982c5cb6cb 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h @@ -114,7 +114,8 @@ /// this attribute will be made public and visible outside of any shared library /// they are linked in to. -#if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility) +#if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility) && defined(__GNUC__) && \ + !defined(__clang__) #define LLVM_ATTRIBUTE_VISIBILITY_HIDDEN [[gnu::visibility("hidden")]] #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT [[gnu::visibility("default")]] #elif __has_attribute(visibility) @@ -125,18 +126,79 @@ #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 +#elif defined(_WIN32) +#if defined(LLVM_EXPORTS) +#define LLVM_ABI __declspec(dllexport) +#define LLVM_TEMPLATE_ABI +#define LLVM_EXPORT_TEMPLATE __declspec(dllexport) +#else +#define LLVM_ABI __declspec(dllimport) +#define LLVM_TEMPLATE_ABI __declspec(dllimport) +#define LLVM_EXPORT_TEMPLATE +#endif +#elif defined(__ELF__) +#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define LLVM_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define LLVM_EXPORT_TEMPLATE +#elif defined(__MACH__) || defined(__WASM__) +#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define LLVM_TEMPLATE_ABI +#define LLVM_EXPORT_TEMPLATE +#endif +#else +#define LLVM_ABI +#define LLVM_TEMPLATE_ABI +#define LLVM_EXPORT_TEMPLATE +#endif +#define LLVM_C_ABI LLVM_ABI #endif #if defined(__GNUC__) diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt index b20ac318e768db..ddf27a266ed674 100644 --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -11,7 +11,7 @@ if(LLVM_LINK_LLVM_DYLIB AND LLVM_DYLIB_EXPORTED_SYMBOL_FILE) endif() if(LLVM_BUILD_LLVM_DYLIB) - if(MSVC) + if(MSVC AND NOT LLVM_BUILD_LLVM_DYLIB_VIS) message(FATAL_ERROR "Generating libLLVM is not supported on MSVC") endif() if(ZOS) @@ -49,18 +49,27 @@ if(LLVM_BUILD_LLVM_DYLIB) ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in ${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map) - # GNU ld doesn't resolve symbols in the version script. - set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) - if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW) - # Solaris ld does not accept global: *; so there is no way to version *all* global symbols - set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES}) - endif() - if (NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS) - # Optimize function calls for default visibility definitions to avoid PLT and - # reduce dynamic relocations. - # Note: for -fno-pic default, the address of a function may be different from - # inside and outside libLLVM.so. - target_link_options(LLVM PRIVATE LINKER:-Bsymbolic-functions) + if(MSVC) + target_link_directories(LLVM PRIVATE ${LLVM_LIBRARY_DIR}) + foreach(library ${LIB_NAMES}) + # FIXME figure out how to use LINK_LIBRARY:WHOLE_ARCHIVE without cmake errors + # target_link_libraries(LLVM PRIVATE "$" ) + target_link_options(LLVM PRIVATE /WHOLEARCHIVE:${library}.lib) + endforeach() + else() + # GNU ld doesn't resolve symbols in the version script. + set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) + if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW) + # Solaris ld does not accept global: *; so there is no way to version *all* global symbols + set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES}) + endif() + if (NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS) + # Optimize function calls for default visibility definitions to avoid PLT and + # reduce dynamic relocations. + # Note: for -fno-pic default, the address of a function may be different from + # inside and outside libLLVM.so. + target_link_options(LLVM PRIVATE LINKER:-Bsymbolic-functions) + endif() endif() endif() diff --git a/llvm/utils/TableGen/Basic/CMakeLists.txt b/llvm/utils/TableGen/Basic/CMakeLists.txt index 09d79a01cae0a8..41d737e8d418e2 100644 --- a/llvm/utils/TableGen/Basic/CMakeLists.txt +++ b/llvm/utils/TableGen/Basic/CMakeLists.txt @@ -8,7 +8,7 @@ set(LLVM_LINK_COMPONENTS TableGen ) -add_llvm_library(LLVMTableGenBasic OBJECT EXCLUDE_FROM_ALL +add_llvm_library(LLVMTableGenBasic OBJECT EXCLUDE_FROM_ALL DISABLE_LLVM_LINK_LLVM_DYLIB CodeGenIntrinsics.cpp SDNodeProperties.cpp ) diff --git a/llvm/utils/TableGen/Common/CMakeLists.txt b/llvm/utils/TableGen/Common/CMakeLists.txt index ce5092b6962bae..7342156980f35f 100644 --- a/llvm/utils/TableGen/Common/CMakeLists.txt +++ b/llvm/utils/TableGen/Common/CMakeLists.txt @@ -10,7 +10,7 @@ set(LLVM_LINK_COMPONENTS TableGen ) -add_llvm_library(LLVMTableGenCommon STATIC OBJECT EXCLUDE_FROM_ALL +add_llvm_library(LLVMTableGenCommon STATIC OBJECT EXCLUDE_FROM_ALL DISABLE_LLVM_LINK_LLVM_DYLIB GlobalISel/CodeExpander.cpp GlobalISel/CombinerUtils.cpp GlobalISel/CXXPredicates.cpp