diff options
Diffstat (limited to 'cmake/modules/HandleLLVMOptions.cmake')
-rw-r--r-- | cmake/modules/HandleLLVMOptions.cmake | 426 |
1 files changed, 259 insertions, 167 deletions
diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake index 1825b55ed54b..099d2ebcc437 100644 --- a/cmake/modules/HandleLLVMOptions.cmake +++ b/cmake/modules/HandleLLVMOptions.cmake @@ -8,12 +8,41 @@ string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) include(CheckCompilerVersion) include(HandleLLVMStdlib) -include(AddLLVMDefinitions) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) +if(CMAKE_LINKER MATCHES "lld-link.exe" OR (WIN32 AND LLVM_USE_LINKER STREQUAL "lld")) + set(LINKER_IS_LLD_LINK TRUE) +else() + set(LINKER_IS_LLD_LINK FALSE) +endif() -if (CMAKE_LINKER MATCHES "lld-link.exe") +# Ninja Job Pool support +# The following only works with the Ninja generator in CMake >= 3.0. +set(LLVM_PARALLEL_COMPILE_JOBS "" CACHE STRING + "Define the maximum number of concurrent compilation jobs.") +if(LLVM_PARALLEL_COMPILE_JOBS) + if(NOT CMAKE_MAKE_PROGRAM MATCHES "ninja") + message(WARNING "Job pooling is only available with Ninja generators.") + else() + set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${LLVM_PARALLEL_COMPILE_JOBS}) + set(CMAKE_JOB_POOL_COMPILE compile_job_pool) + endif() +endif() + +set(LLVM_PARALLEL_LINK_JOBS "" CACHE STRING + "Define the maximum number of concurrent link jobs.") +if(LLVM_PARALLEL_LINK_JOBS) + if(NOT CMAKE_MAKE_PROGRAM MATCHES "ninja") + message(WARNING "Job pooling is only available with Ninja generators.") + else() + set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS}) + set(CMAKE_JOB_POOL_LINK link_job_pool) + endif() +endif() + + +if (LINKER_IS_LLD_LINK) # Pass /MANIFEST:NO so that CMake doesn't run mt.exe on our binaries. Adding # manifests with mt.exe breaks LLD's symbol tables and takes as much time as # the link. See PR24476. @@ -147,9 +176,19 @@ function(add_flag_or_print_warning flag name) endif() endfunction() -if(LLVM_ENABLE_LLD) - check_cxx_compiler_flag("-fuse-ld=lld" CXX_SUPPORTS_LLD) - append_if(CXX_SUPPORTS_LLD "-fuse-ld=lld" +if( LLVM_ENABLE_LLD ) + if ( LLVM_USE_LINKER ) + message(FATAL_ERROR "LLVM_ENABLE_LLD and LLVM_USE_LINKER can't be set at the same time") + endif() + set(LLVM_USE_LINKER "lld") +endif() + +if( LLVM_USE_LINKER ) + check_cxx_compiler_flag("-fuse-ld=${LLVM_USE_LINKER}" CXX_SUPPORTS_CUSTOM_LINKER) + if ( NOT CXX_SUPPORTS_CUSTOM_LINKER ) + message(FATAL_ERROR "Host compiler does not support '-fuse-ld=${LLVM_USE_LINKER}'") + endif() + append("-fuse-ld=${LLVM_USE_LINKER}" CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) endif() @@ -213,10 +252,10 @@ if( MSVC_IDE ) "Number of parallel compiler jobs. 0 means use all processors. Default is 0.") if( NOT LLVM_COMPILER_JOBS STREQUAL "1" ) if( LLVM_COMPILER_JOBS STREQUAL "0" ) - add_llvm_definitions( /MP ) + add_definitions( /MP ) else() message(STATUS "Number of parallel compiler jobs set to " ${LLVM_COMPILER_JOBS}) - add_llvm_definitions( /MP${LLVM_COMPILER_JOBS} ) + add_definitions( /MP${LLVM_COMPILER_JOBS} ) endif() else() message(STATUS "Parallel compilation disabled") @@ -245,17 +284,17 @@ if( MSVC ) if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0 ) # For MSVC 2013, disable iterator null pointer checking in debug mode, # especially so std::equal(nullptr, nullptr, nullptr) will not assert. - add_llvm_definitions("-D_DEBUG_POINTER_IMPL=") + add_definitions("-D_DEBUG_POINTER_IMPL=") endif() include(ChooseMSVCCRT) if( MSVC11 ) - add_llvm_definitions(-D_VARIADIC_MAX=10) + add_definitions(-D_VARIADIC_MAX=10) endif() # Add definitions that make MSVC much less annoying. - add_llvm_definitions( + add_definitions( # For some reason MS wants to deprecate a bunch of standard functions... -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS @@ -266,94 +305,15 @@ if( MSVC ) ) # Tell MSVC to use the Unicode version of the Win32 APIs instead of ANSI. - add_llvm_definitions( + add_definitions( -DUNICODE -D_UNICODE ) - set(msvc_warning_flags - # Disabled warnings. - -wd4141 # Suppress ''modifier' : used more than once' (because of __forceinline combined with inline) - -wd4146 # Suppress 'unary minus operator applied to unsigned type, result still unsigned' - -wd4180 # Suppress 'qualifier applied to function type has no meaning; ignored' - -wd4244 # Suppress ''argument' : conversion from 'type1' to 'type2', possible loss of data' - -wd4258 # Suppress ''var' : definition from the for loop is ignored; the definition from the enclosing scope is used' - -wd4267 # Suppress ''var' : conversion from 'size_t' to 'type', possible loss of data' - -wd4291 # Suppress ''declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception' - -wd4345 # Suppress 'behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized' - -wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized' - -wd4355 # Suppress ''this' : used in base member initializer list' - -wd4456 # Suppress 'declaration of 'var' hides local variable' - -wd4457 # Suppress 'declaration of 'var' hides function parameter' - -wd4458 # Suppress 'declaration of 'var' hides class member' - -wd4459 # Suppress 'declaration of 'var' hides global declaration' - -wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated' - -wd4624 # Suppress ''derived class' : destructor could not be generated because a base class destructor is inaccessible' - -wd4722 # Suppress 'function' : destructor never returns, potential memory leak - -wd4800 # Suppress ''type' : forcing value to bool 'true' or 'false' (performance warning)' - -wd4100 # Suppress 'unreferenced formal parameter' - -wd4127 # Suppress 'conditional expression is constant' - -wd4512 # Suppress 'assignment operator could not be generated' - -wd4505 # Suppress 'unreferenced local function has been removed' - -wd4610 # Suppress '<class> can never be instantiated' - -wd4510 # Suppress 'default constructor could not be generated' - -wd4702 # Suppress 'unreachable code' - -wd4245 # Suppress 'signed/unsigned mismatch' - -wd4706 # Suppress 'assignment within conditional expression' - -wd4310 # Suppress 'cast truncates constant value' - -wd4701 # Suppress 'potentially uninitialized local variable' - -wd4703 # Suppress 'potentially uninitialized local pointer variable' - -wd4389 # Suppress 'signed/unsigned mismatch' - -wd4611 # Suppress 'interaction between '_setjmp' and C++ object destruction is non-portable' - -wd4805 # Suppress 'unsafe mix of type <type> and type <type> in operation' - -wd4204 # Suppress 'nonstandard extension used : non-constant aggregate initializer' - -wd4577 # Suppress 'noexcept used with no exception handling mode specified; termination on exception is not guaranteed' - -wd4091 # Suppress 'typedef: ignored on left of '' when no variable is declared' - # C4592 is disabled because of false positives in Visual Studio 2015 - # Update 1. Re-evaluate the usefulness of this diagnostic with Update 2. - -wd4592 # Suppress ''var': symbol will be dynamically initialized (implementation limitation) - -wd4319 # Suppress ''operator' : zero extending 'type' to 'type' of greater size' - - # Ideally, we'd like this warning to be enabled, but MSVC 2013 doesn't - # support the 'aligned' attribute in the way that clang sources requires (for - # any code that uses the LLVM_ALIGNAS macro), so this is must be disabled to - # avoid unwanted alignment warnings. - # When we switch to requiring a version of MSVC that supports the 'alignas' - # specifier (MSVC 2015?) this warning can be re-enabled. - -wd4324 # Suppress 'structure was padded due to __declspec(align())' - - # Promoted warnings. - -w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning. - - # Promoted warnings to errors. - -we4238 # Promote 'nonstandard extension used : class rvalue used as lvalue' to error. - ) - - # Enable warnings - if (LLVM_ENABLE_WARNINGS) - # Put /W4 in front of all the -we flags. cl.exe doesn't care, but for - # clang-cl having /W4 after the -we flags will re-enable the warnings - # disabled by -we. - set(msvc_warning_flags "/W4 ${msvc_warning_flags}") - # CMake appends /W3 by default, and having /W3 followed by /W4 will result in - # cl : Command line warning D9025 : overriding '/W3' with '/W4'. Since this is - # a command line warning and not a compiler warning, it cannot be suppressed except - # by fixing the command line. - string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - - if (LLVM_ENABLE_PEDANTIC) - # No MSVC equivalent available - endif (LLVM_ENABLE_PEDANTIC) - endif (LLVM_ENABLE_WARNINGS) if (LLVM_ENABLE_WERROR) - append("/WX" msvc_warning_flags) + append("/WX" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif (LLVM_ENABLE_WERROR) - foreach(flag ${msvc_warning_flags}) - append("${flag}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - endforeach(flag) - append("/Zc:inline" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) # /Zc:strictStrings is incompatible with VS12's (Visual Studio 2013's) @@ -373,11 +333,13 @@ if( MSVC ) # "Enforce type conversion rules". append("/Zc:rvalueCast" CMAKE_CXX_FLAGS) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT LLVM_ENABLE_LTO) # clang-cl and cl by default produce non-deterministic binaries because # link.exe /incremental requires a timestamp in the .obj file. clang-cl # has the flag /Brepro to force deterministic binaries. We want to pass that - # whenever you're building with clang unless you're passing /incremental. + # whenever you're building with clang unless you're passing /incremental + # or using LTO (/Brepro with LTO would result in a warning about the flag + # being unused, because we're not generating object files). # This checks CMAKE_CXX_COMPILER_ID in addition to check_cxx_compiler_flag() # because cl.exe does not emit an error on flags it doesn't understand, # letting check_cxx_compiler_flag() claim it understands all flags. @@ -401,63 +363,6 @@ if( MSVC ) endif() elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE ) - if (LLVM_ENABLE_WARNINGS) - append("-Wall -W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - append("-Wcast-qual" CMAKE_CXX_FLAGS) - - # Turn off missing field initializer warnings for gcc to avoid noise from - # false positives with empty {}. Turn them on otherwise (they're off by - # default for clang). - check_cxx_compiler_flag("-Wmissing-field-initializers" CXX_SUPPORTS_MISSING_FIELD_INITIALIZERS_FLAG) - if (CXX_SUPPORTS_MISSING_FIELD_INITIALIZERS_FLAG) - if (CMAKE_COMPILER_IS_GNUCXX) - append("-Wno-missing-field-initializers" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - else() - append("-Wmissing-field-initializers" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - endif() - endif() - - append_if(LLVM_ENABLE_PEDANTIC "-pedantic" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - append_if(LLVM_ENABLE_PEDANTIC "-Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - add_flag_if_supported("-Wcovered-switch-default" COVERED_SWITCH_DEFAULT_FLAG) - append_if(USE_NO_UNINITIALIZED "-Wno-uninitialized" CMAKE_CXX_FLAGS) - append_if(USE_NO_MAYBE_UNINITIALIZED "-Wno-maybe-uninitialized" CMAKE_CXX_FLAGS) - - # Check if -Wnon-virtual-dtor warns even though the class is marked final. - # If it does, don't add it. So it won't be added on clang 3.4 and older. - # This also catches cases when -Wnon-virtual-dtor isn't supported by - # the compiler at all. This flag is not activated for gcc since it will - # incorrectly identify a protected non-virtual base when there is a friend - # declaration. - if (NOT CMAKE_COMPILER_IS_GNUCXX) - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11 -Werror=non-virtual-dtor") - CHECK_CXX_SOURCE_COMPILES("class base {public: virtual void anchor();protected: ~base();}; - class derived final : public base { public: ~derived();}; - int main() { return 0; }" - CXX_WONT_WARN_ON_FINAL_NONVIRTUALDTOR) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) - append_if(CXX_WONT_WARN_ON_FINAL_NONVIRTUALDTOR - "-Wnon-virtual-dtor" CMAKE_CXX_FLAGS) - endif() - - # Enable -Wdelete-non-virtual-dtor if available. - add_flag_if_supported("-Wdelete-non-virtual-dtor" DELETE_NON_VIRTUAL_DTOR_FLAG) - - # Check if -Wcomment is OK with an // comment ending with '\' if the next - # line is also a // comment. - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror -Wcomment") - CHECK_C_SOURCE_COMPILES("// \\\\\\n//\\nint main() {return 0;}" - C_WCOMMENT_ALLOWS_LINE_WRAP) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) - if (NOT C_WCOMMENT_ALLOWS_LINE_WRAP) - append("-Wno-comment" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - endif() - - # Enable -Wstring-conversion to catch misuse of string literals. - add_flag_if_supported("-Wstring-conversion" STRING_CONVERSION_FLAG) - endif (LLVM_ENABLE_WARNINGS) append_if(LLVM_ENABLE_WERROR "-Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) add_flag_if_supported("-Werror=date-time" WERROR_DATE_TIME) if (LLVM_ENABLE_CXX1Y) @@ -511,6 +416,155 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE ) endif(LLVM_ENABLE_MODULES) endif( MSVC ) +if (MSVC AND NOT CLANG_CL) + set(msvc_warning_flags + # Disabled warnings. + -wd4141 # Suppress ''modifier' : used more than once' (because of __forceinline combined with inline) + -wd4146 # Suppress 'unary minus operator applied to unsigned type, result still unsigned' + -wd4180 # Suppress 'qualifier applied to function type has no meaning; ignored' + -wd4244 # Suppress ''argument' : conversion from 'type1' to 'type2', possible loss of data' + -wd4258 # Suppress ''var' : definition from the for loop is ignored; the definition from the enclosing scope is used' + -wd4267 # Suppress ''var' : conversion from 'size_t' to 'type', possible loss of data' + -wd4291 # Suppress ''declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception' + -wd4345 # Suppress 'behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized' + -wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized' + -wd4355 # Suppress ''this' : used in base member initializer list' + -wd4456 # Suppress 'declaration of 'var' hides local variable' + -wd4457 # Suppress 'declaration of 'var' hides function parameter' + -wd4458 # Suppress 'declaration of 'var' hides class member' + -wd4459 # Suppress 'declaration of 'var' hides global declaration' + -wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated' + -wd4624 # Suppress ''derived class' : destructor could not be generated because a base class destructor is inaccessible' + -wd4722 # Suppress 'function' : destructor never returns, potential memory leak + -wd4800 # Suppress ''type' : forcing value to bool 'true' or 'false' (performance warning)' + -wd4100 # Suppress 'unreferenced formal parameter' + -wd4127 # Suppress 'conditional expression is constant' + -wd4512 # Suppress 'assignment operator could not be generated' + -wd4505 # Suppress 'unreferenced local function has been removed' + -wd4610 # Suppress '<class> can never be instantiated' + -wd4510 # Suppress 'default constructor could not be generated' + -wd4702 # Suppress 'unreachable code' + -wd4245 # Suppress 'signed/unsigned mismatch' + -wd4706 # Suppress 'assignment within conditional expression' + -wd4310 # Suppress 'cast truncates constant value' + -wd4701 # Suppress 'potentially uninitialized local variable' + -wd4703 # Suppress 'potentially uninitialized local pointer variable' + -wd4389 # Suppress 'signed/unsigned mismatch' + -wd4611 # Suppress 'interaction between '_setjmp' and C++ object destruction is non-portable' + -wd4805 # Suppress 'unsafe mix of type <type> and type <type> in operation' + -wd4204 # Suppress 'nonstandard extension used : non-constant aggregate initializer' + -wd4577 # Suppress 'noexcept used with no exception handling mode specified; termination on exception is not guaranteed' + -wd4091 # Suppress 'typedef: ignored on left of '' when no variable is declared' + # C4592 is disabled because of false positives in Visual Studio 2015 + # Update 1. Re-evaluate the usefulness of this diagnostic with Update 2. + -wd4592 # Suppress ''var': symbol will be dynamically initialized (implementation limitation) + -wd4319 # Suppress ''operator' : zero extending 'type' to 'type' of greater size' + + # Ideally, we'd like this warning to be enabled, but MSVC 2013 doesn't + # support the 'aligned' attribute in the way that clang sources requires (for + # any code that uses the LLVM_ALIGNAS macro), so this is must be disabled to + # avoid unwanted alignment warnings. + # When we switch to requiring a version of MSVC that supports the 'alignas' + # specifier (MSVC 2015?) this warning can be re-enabled. + -wd4324 # Suppress 'structure was padded due to __declspec(align())' + + # Promoted warnings. + -w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning. + + # Promoted warnings to errors. + -we4238 # Promote 'nonstandard extension used : class rvalue used as lvalue' to error. + ) + + # Enable warnings + if (LLVM_ENABLE_WARNINGS) + # Put /W4 in front of all the -we flags. cl.exe doesn't care, but for + # clang-cl having /W4 after the -we flags will re-enable the warnings + # disabled by -we. + set(msvc_warning_flags "/W4 ${msvc_warning_flags}") + # CMake appends /W3 by default, and having /W3 followed by /W4 will result in + # cl : Command line warning D9025 : overriding '/W3' with '/W4'. Since this is + # a command line warning and not a compiler warning, it cannot be suppressed except + # by fixing the command line. + string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + + if (LLVM_ENABLE_PEDANTIC) + # No MSVC equivalent available + endif (LLVM_ENABLE_PEDANTIC) + endif (LLVM_ENABLE_WARNINGS) + + foreach(flag ${msvc_warning_flags}) + append("${flag}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endforeach(flag) +endif (MSVC AND NOT CLANG_CL) + +if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL)) + append("-Wall -W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append("-Wcast-qual" CMAKE_CXX_FLAGS) + + # Turn off missing field initializer warnings for gcc to avoid noise from + # false positives with empty {}. Turn them on otherwise (they're off by + # default for clang). + check_cxx_compiler_flag("-Wmissing-field-initializers" CXX_SUPPORTS_MISSING_FIELD_INITIALIZERS_FLAG) + if (CXX_SUPPORTS_MISSING_FIELD_INITIALIZERS_FLAG) + if (CMAKE_COMPILER_IS_GNUCXX) + append("-Wno-missing-field-initializers" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + else() + append("-Wmissing-field-initializers" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() + endif() + + if (LLVM_ENABLE_PEDANTIC AND LLVM_COMPILER_IS_GCC_COMPATIBLE) + append("-pedantic" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append("-Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() + + add_flag_if_supported("-Wcovered-switch-default" COVERED_SWITCH_DEFAULT_FLAG) + append_if(USE_NO_UNINITIALIZED "-Wno-uninitialized" CMAKE_CXX_FLAGS) + append_if(USE_NO_MAYBE_UNINITIALIZED "-Wno-maybe-uninitialized" CMAKE_CXX_FLAGS) + + # Check if -Wnon-virtual-dtor warns even though the class is marked final. + # If it does, don't add it. So it won't be added on clang 3.4 and older. + # This also catches cases when -Wnon-virtual-dtor isn't supported by + # the compiler at all. This flag is not activated for gcc since it will + # incorrectly identify a protected non-virtual base when there is a friend + # declaration. Don't activate this in general on Windows as this warning has + # too many false positives on COM-style classes, which are destroyed with + # Release() (PR32286). + if (NOT CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11 -Werror=non-virtual-dtor") + CHECK_CXX_SOURCE_COMPILES("class base {public: virtual void anchor();protected: ~base();}; + class derived final : public base { public: ~derived();}; + int main() { return 0; }" + CXX_WONT_WARN_ON_FINAL_NONVIRTUALDTOR) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) + append_if(CXX_WONT_WARN_ON_FINAL_NONVIRTUALDTOR + "-Wnon-virtual-dtor" CMAKE_CXX_FLAGS) + endif() + + # Enable -Wdelete-non-virtual-dtor if available. + add_flag_if_supported("-Wdelete-non-virtual-dtor" DELETE_NON_VIRTUAL_DTOR_FLAG) + + # Check if -Wcomment is OK with an // comment ending with '\' if the next + # line is also a // comment. + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror -Wcomment") + CHECK_C_SOURCE_COMPILES("// \\\\\\n//\\nint main() {return 0;}" + C_WCOMMENT_ALLOWS_LINE_WRAP) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) + if (NOT C_WCOMMENT_ALLOWS_LINE_WRAP) + append("-Wno-comment" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() + + # Enable -Wstring-conversion to catch misuse of string literals. + add_flag_if_supported("-Wstring-conversion" STRING_CONVERSION_FLAG) +endif (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL)) + +if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND NOT LLVM_ENABLE_WARNINGS) + append("-w" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) +endif() + macro(append_common_sanitizer_flags) if (NOT MSVC) # Append -fno-omit-frame-pointer and turn on debug info to get better @@ -527,7 +581,7 @@ macro(append_common_sanitizer_flags) elseif (CLANG_CL) # Keep frame pointers around. append("/Oy-" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - if (CMAKE_LINKER MATCHES "lld-link.exe") + if (LINKER_IS_LLD_LINK) # Use DWARF debug info with LLD. append("-gdwarf" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() @@ -555,8 +609,11 @@ if(LLVM_USE_SANITIZER) append_common_sanitizer_flags() append("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - append("-fsanitize-blacklist=${CMAKE_SOURCE_DIR}/utils/sanitizers/ubsan_blacklist.txt" - CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + set(BLACKLIST_FILE "${CMAKE_SOURCE_DIR}/utils/sanitizers/ubsan_blacklist.txt") + if (EXISTS "${BLACKLIST_FILE}") + append("-fsanitize-blacklist=${BLACKLIST_FILE}" + CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() elseif (LLVM_USE_SANITIZER STREQUAL "Thread") append_common_sanitizer_flags() append("-fsanitize=thread" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) @@ -578,6 +635,10 @@ if(LLVM_USE_SANITIZER) else() message(FATAL_ERROR "LLVM_USE_SANITIZER is not supported on this platform.") endif() + if (LLVM_USE_SANITIZER MATCHES "(Undefined;)?Address(;Undefined)?") + add_flag_if_supported("-fsanitize-address-use-after-scope" + FSANITIZE_USE_AFTER_SCOPE_FLAG) + endif() if (LLVM_USE_SANITIZE_COVERAGE) append("-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() @@ -588,9 +649,9 @@ if(LLVM_USE_SPLIT_DWARF) add_definitions("-gsplit-dwarf") endif() -add_llvm_definitions( -D__STDC_CONSTANT_MACROS ) -add_llvm_definitions( -D__STDC_FORMAT_MACROS ) -add_llvm_definitions( -D__STDC_LIMIT_MACROS ) +add_definitions( -D__STDC_CONSTANT_MACROS ) +add_definitions( -D__STDC_FORMAT_MACROS ) +add_definitions( -D__STDC_LIMIT_MACROS ) # clang doesn't print colored diagnostics when invoked from Ninja if (UNIX AND @@ -658,20 +719,38 @@ append_if(LLVM_BUILD_INSTRUMENTED_COVERAGE "-fprofile-instr-generate='${LLVM_PRO set(LLVM_ENABLE_LTO OFF CACHE STRING "Build LLVM with LTO. May be specified as Thin or Full to use a particular kind of LTO") string(TOUPPER "${LLVM_ENABLE_LTO}" uppercase_LLVM_ENABLE_LTO) +if(LLVM_ENABLE_LTO AND LLVM_ON_WIN32 AND NOT LINKER_IS_LLD_LINK) + message(FATAL_ERROR "When compiling for Windows, LLVM_ENABLE_LTO requires using lld as the linker (point CMAKE_LINKER at lld-link.exe)") +endif() if(uppercase_LLVM_ENABLE_LTO STREQUAL "THIN") - append("-flto=thin" CMAKE_CXX_FLAGS CMAKE_C_FLAGS - CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) - # On darwin, enable the lto cache. This improves initial build time a little - # since we re-link a lot of the same objects, and significantly improves - # incremental build time. - append_if(APPLE "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache" - CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + append("-flto=thin" CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + if(NOT LINKER_IS_LLD_LINK) + append("-flto=thin" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + endif() + # If the linker supports it, enable the lto cache. This improves initial build + # time a little since we re-link a lot of the same objects, and significantly + # improves incremental build time. + # FIXME: We should move all this logic into the clang driver. + if(APPLE) + append("-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache" + CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + elseif(UNIX AND LLVM_USE_LINKER STREQUAL "lld") + append("-Wl,--thinlto-cache-dir=${PROJECT_BINARY_DIR}/lto.cache" + CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + elseif(LLVM_USE_LINKER STREQUAL "gold") + append("-Wl,--plugin-opt,cache-dir=${PROJECT_BINARY_DIR}/lto.cache" + CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + endif() elseif(uppercase_LLVM_ENABLE_LTO STREQUAL "FULL") - append("-flto=full" CMAKE_CXX_FLAGS CMAKE_C_FLAGS - CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + append("-flto=full" CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + if(NOT LINKER_IS_LLD_LINK) + append("-flto=full" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + endif() elseif(LLVM_ENABLE_LTO) - append("-flto" CMAKE_CXX_FLAGS CMAKE_C_FLAGS - CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + append("-flto" CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + if(NOT LINKER_IS_LLD_LINK) + append("-flto" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) + endif() endif() # This option makes utils/extract_symbols.py be used to determine the list of @@ -698,3 +777,16 @@ if(WIN32 OR CYGWIN) else() set(LLVM_ENABLE_PLUGINS ON) endif() + +function(get_compile_definitions) + get_directory_property(top_dir_definitions DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS) + foreach(definition ${top_dir_definitions}) + if(DEFINED result) + string(APPEND result " -D${definition}") + else() + set(result "-D${definition}") + endif() + endforeach() + set(LLVM_DEFINITIONS "${result}" PARENT_SCOPE) +endfunction() +get_compile_definitions() |