[libunwind] Refactor CMake flag checks to match libc++ and libc++abi

libunwind was using its own set of macros/functions for flag checking
which was similar but different from libc++ and libc++abi. This made
it difficult to replicate the same checks across projects, in fact
there were some checks that appear to have been copy & pasted from
another project and that were broken in the standalone libunwind build.
This change refactors flag checks to match libc++ and libc++abi using
a copy of HandleLibunwindFlags.cmake which is derived from the versions
used by the other projects. This also paves a road to deduplicating and
unifying HandleLibunwindFlags.cmake, HandleLibcxxabiFlags.cmake and
HandleLibcxxFlags.cmake post monorepo switch.

Differential Revision: https://reviews.llvm.org/D68855

git-svn-id: https://llvm.org/svn/llvm-project/libunwind/trunk@374606 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 440141c..736c533 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -213,28 +213,14 @@
 set(LIBUNWIND_COMPILE_FLAGS "")
 set(LIBUNWIND_LINK_FLAGS "")
 
+# Include macros for adding and removing libunwind flags.
+include(HandleLibunwindFlags)
+
+#===============================================================================
+# Setup Compiler Flags
+#===============================================================================
+
 # Get required flags.
-macro(unwind_append_if list condition var)
-  if (${condition})
-    list(APPEND ${list} ${var})
-  endif()
-endmacro()
-
-macro(add_target_flags)
-  foreach(value ${ARGN})
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}")
-    list(APPEND LIBUNWIND_COMPILE_FLAGS ${value})
-    list(APPEND LIBUNWIND_LINK_FLAGS ${value})
-  endforeach()
-endmacro()
-
-macro(add_target_flags_if condition)
-  if (${condition})
-    add_target_flags(${ARGN})
-  endif()
-endmacro()
-
 add_target_flags_if(LIBUNWIND_BUILD_32_BITS "-m32")
 
 if(LIBUNWIND_TARGET_TRIPLE)
@@ -264,83 +250,86 @@
   list(APPEND LIBUNWIND_LINK_FLAGS "-rtlib=compiler-rt")
 endif()
 
-#===============================================================================
-# Setup Compiler Flags
-#===============================================================================
-
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WERROR_FLAG -Werror=return-type)
+add_compile_flags_if_supported(-Werror=return-type)
 
 # Get warning flags
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_W_FLAG -W)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WALL_FLAG -Wall)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WCHAR_SUBSCRIPTS_FLAG -Wchar-subscripts)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WCONVERSION_FLAG -Wconversion)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WMISMATCHED_TAGS_FLAG -Wmismatched-tags)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WMISSING_BRACES_FLAG -Wmissing-braces)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WNEWLINE_EOF_FLAG -Wnewline-eof)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WNO_UNUSED_FUNCTION_FLAG -Wno-unused-function)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSHADOW_FLAG -Wshadow)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSHORTEN_64_TO_32_FLAG -Wshorten-64-to-32)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSIGN_COMPARE_FLAG -Wsign-compare)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSIGN_CONVERSION_FLAG -Wsign-conversion)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSTRICT_ALIASING_FLAG -Wstrict-aliasing=2)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSTRICT_OVERFLOW_FLAG -Wstrict-overflow=4)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WUNUSED_PARAMETER_FLAG -Wunused-parameter)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WUNUSED_VARIABLE_FLAG -Wunused-variable)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings)
-unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WUNDEF_FLAG -Wundef)
+add_compile_flags_if_supported(-W)
+add_compile_flags_if_supported(-Wall)
+add_compile_flags_if_supported(-Wchar-subscripts)
+add_compile_flags_if_supported(-Wconversion)
+add_compile_flags_if_supported(-Wmismatched-tags)
+add_compile_flags_if_supported(-Wmissing-braces)
+add_compile_flags_if_supported(-Wnewline-eof)
+add_compile_flags_if_supported(-Wno-unused-function)
+add_compile_flags_if_supported(-Wshadow)
+add_compile_flags_if_supported(-Wshorten-64-to-32)
+add_compile_flags_if_supported(-Wsign-compare)
+add_compile_flags_if_supported(-Wsign-conversion)
+add_compile_flags_if_supported(-Wstrict-aliasing=2)
+add_compile_flags_if_supported(-Wstrict-overflow=4)
+add_compile_flags_if_supported(-Wunused-parameter)
+add_compile_flags_if_supported(-Wunused-variable)
+add_compile_flags_if_supported(-Wwrite-strings)
+add_compile_flags_if_supported(-Wundef)
 
 if (LIBUNWIND_ENABLE_WERROR)
-  unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WERROR_FLAG -Werror)
-  unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WX_FLAG -WX)
+  add_compile_flags_if_supported(-Werror)
+  add_compile_flags_if_supported(-WX)
 else()
-  unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WNO_ERROR_FLAG -Wno-error)
-  unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_NO_WX_FLAG -WX-)
+  add_compile_flags_if_supported(-Wno-error)
+  add_compile_flags_if_supported(-WX-)
 endif()
 
 if (LIBUNWIND_ENABLE_PEDANTIC)
-  unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_PEDANTIC_FLAG -pedantic)
+  add_compile_flags_if_supported(-pedantic)
 endif()
 
 # Get feature flags.
 # Exceptions
 # Catches C++ exceptions only and tells the compiler to assume that extern C
 # functions never throw a C++ exception.
-unwind_append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_FSTRICT_ALIASING_FLAG -fstrict-aliasing)
-unwind_append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_EHSC_FLAG -EHsc)
+add_cxx_compile_flags_if_supported(-fstrict-aliasing)
+add_cxx_compile_flags_if_supported(-EHsc)
 
-unwind_append_if(LIBUNWIND_C_FLAGS LIBUNWIND_HAS_FUNWIND_TABLES -funwind-tables)
+add_c_compile_flags_if_supported(-funwind-tables)
+add_cxx_compile_flags_if_supported(-fno-exceptions)
+add_cxx_compile_flags_if_supported(-fno-rtti)
 
 # Ensure that we don't depend on C++ standard library.
-unwind_append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_NOSTDINCXX_FLAG -nostdinc++)
+if (LIBCXXABI_HAS_NOSTDINCXX_FLAG)
+  list(APPEND LIBUNWIND_COMPILE_FLAGS -nostdinc++)
+  # Remove -stdlib flags to prevent them from causing an unused flag warning.
+  string(REPLACE "-stdlib=libc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  string(REPLACE "-stdlib=libstdc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endif()
 
 # Assert
 string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
 if (LIBUNWIND_ENABLE_ASSERTIONS)
   # MSVC doesn't like _DEBUG on release builds. See PR 4379.
   if (NOT MSVC)
-    list(APPEND LIBUNWIND_COMPILE_FLAGS -D_DEBUG)
+    add_compile_flags(-D_DEBUG)
   endif()
 
   # On Release builds cmake automatically defines NDEBUG, so we
   # explicitly undefine it:
   if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
-    list(APPEND LIBUNWIND_COMPILE_FLAGS -UNDEBUG)
+    add_compile_flags(-UNDEBUG)
   endif()
 else()
   if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
-    list(APPEND LIBUNWIND_COMPILE_FLAGS -DNDEBUG)
+    add_compile_flags(-DNDEBUG)
   endif()
 endif()
 
 # Cross-unwinding
 if (NOT LIBUNWIND_ENABLE_CROSS_UNWINDING)
-  list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_IS_NATIVE_ONLY)
+  add_compile_flags(-D_LIBUNWIND_IS_NATIVE_ONLY)
 endif()
 
 # Threading-support
 if (NOT LIBUNWIND_ENABLE_THREADS)
-  list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_HAS_NO_THREADS)
+  add_compile_flags(-D_LIBUNWIND_HAS_NO_THREADS)
 endif()
 
 # ARM WMMX register support
@@ -349,7 +338,7 @@
   # define this macro for any supported target at present. Therefore, here we
   # provide the option to explicitly enable support for WMMX registers in the
   # unwinder.
-  list(APPEND LIBUNWIND_COMPILE_FLAGS -D__ARM_WMMX)
+  add_compile_flags(-D__ARM_WMMX)
 endif()
 
 # This is the _ONLY_ place where add_definitions is called.
diff --git a/cmake/Modules/HandleLibunwindFlags.cmake b/cmake/Modules/HandleLibunwindFlags.cmake
new file mode 100644
index 0000000..57ba0b8
--- /dev/null
+++ b/cmake/Modules/HandleLibunwindFlags.cmake
@@ -0,0 +1,272 @@
+# HandleLibcxxFlags - A set of macros used to setup the flags used to compile
+# and link libc++abi. These macros add flags to the following CMake variables.
+# - LIBUNWIND_COMPILE_FLAGS: flags used to compile libunwind
+# - LIBUNWIND_LINK_FLAGS: flags used to link libunwind
+# - LIBUNWIND_LIBRARIES: libraries to link libunwind to.
+
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+
+unset(add_flag_if_supported)
+
+# Mangle the name of a compiler flag into a valid CMake identifier.
+# Ex: --std=c++11 -> STD_EQ_CXX11
+macro(mangle_name str output)
+  string(STRIP "${str}" strippedStr)
+  string(REGEX REPLACE "^/" "" strippedStr "${strippedStr}")
+  string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}")
+  string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}")
+  string(REPLACE "-" "_" strippedStr "${strippedStr}")
+  string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}")
+  string(REPLACE "+" "X" strippedStr "${strippedStr}")
+  string(TOUPPER "${strippedStr}" ${output})
+endmacro()
+
+# Remove a list of flags from all CMake variables that affect compile flags.
+# This can be used to remove unwanted flags specified on the command line
+# or added in other parts of LLVM's cmake configuration.
+macro(remove_flags)
+  foreach(var ${ARGN})
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_SHARED_MODULE_FLAGS "${CMAKE_SHARED_MODULE_FLAGS}")
+    remove_definitions(${var})
+  endforeach()
+endmacro(remove_flags)
+
+macro(check_flag_supported flag)
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+endmacro()
+
+macro(append_flags DEST)
+  foreach(value ${ARGN})
+    list(APPEND ${DEST} ${value})
+    list(APPEND ${DEST} ${value})
+  endforeach()
+endmacro()
+
+# If the specified 'condition' is true then append the specified list of flags to DEST
+macro(append_flags_if condition DEST)
+  if (${condition})
+    list(APPEND ${DEST} ${ARGN})
+  endif()
+endmacro()
+
+# Add each flag in the list specified by DEST if that flag is supported by the current compiler.
+macro(append_flags_if_supported DEST)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+    append_flags_if(LIBUNWIND_SUPPORTS_${flagname}_FLAG ${DEST} ${flag})
+  endforeach()
+endmacro()
+
+# Add a macro definition if condition is true.
+macro(define_if condition def)
+  if (${condition})
+    add_definitions(${def})
+  endif()
+endmacro()
+
+# Add a macro definition if condition is not true.
+macro(define_if_not condition def)
+  if (NOT ${condition})
+    add_definitions(${def})
+  endif()
+endmacro()
+
+# Add a macro definition to the __config_site file if the specified condition
+# is 'true'. Note that '-D${def}' is not added. Instead it is expected that
+# the build include the '__config_site' header.
+macro(config_define_if condition def)
+  if (${condition})
+    set(${def} ON)
+    set(LIBUNWIND_NEEDS_SITE_CONFIG ON)
+  endif()
+endmacro()
+
+macro(config_define_if_not condition def)
+  if (NOT ${condition})
+    set(${def} ON)
+    set(LIBUNWIND_NEEDS_SITE_CONFIG ON)
+  endif()
+endmacro()
+
+macro(config_define value def)
+  set(${def} ${value})
+  set(LIBUNWIND_NEEDS_SITE_CONFIG ON)
+endmacro()
+
+# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS',
+# 'LIBUNWIND_COMPILE_FLAGS' and 'LIBUNWIND_LINK_FLAGS'.
+macro(add_target_flags)
+  foreach(value ${ARGN})
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}")
+    list(APPEND LIBUNWIND_COMPILE_FLAGS ${value})
+    list(APPEND LIBUNWIND_LINK_FLAGS ${value})
+  endforeach()
+endmacro()
+
+# If the specified 'condition' is true then add a list of flags to
+# all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBUNWIND_COMPILE_FLAGS'
+# and 'LIBUNWIND_LINK_FLAGS'.
+macro(add_target_flags_if condition)
+  if (${condition})
+    add_target_flags(${ARGN})
+  endif()
+endmacro()
+
+# Add a specified list of flags to both 'LIBUNWIND_COMPILE_FLAGS' and
+# 'LIBUNWIND_LINK_FLAGS'.
+macro(add_flags)
+  foreach(value ${ARGN})
+    list(APPEND LIBUNWIND_COMPILE_FLAGS ${value})
+    list(APPEND LIBUNWIND_LINK_FLAGS ${value})
+  endforeach()
+endmacro()
+
+# If the specified 'condition' is true then add a list of flags to both
+# 'LIBUNWIND_COMPILE_FLAGS' and 'LIBUNWIND_LINK_FLAGS'.
+macro(add_flags_if condition)
+  if (${condition})
+    add_flags(${ARGN})
+  endif()
+endmacro()
+
+# Add each flag in the list to LIBUNWIND_COMPILE_FLAGS and LIBUNWIND_LINK_FLAGS
+# if that flag is supported by the current compiler.
+macro(add_flags_if_supported)
+  foreach(flag ${ARGN})
+      mangle_name("${flag}" flagname)
+      check_cxx_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+      add_flags_if(LIBUNWIND_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBUNWIND_COMPILE_FLAGS'.
+macro(add_compile_flags)
+  foreach(f ${ARGN})
+    list(APPEND LIBUNWIND_COMPILE_FLAGS ${f})
+  endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBUNWIND_COMPILE_FLAGS'
+macro(add_compile_flags_if condition)
+  if (${condition})
+    add_compile_flags(${ARGN})
+  endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBUNWIND_COMPILE_FLAGS' if the
+# flag is supported by the C++ compiler.
+macro(add_compile_flags_if_supported)
+  foreach(flag ${ARGN})
+      mangle_name("${flag}" flagname)
+      check_cxx_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+      add_compile_flags_if(LIBUNWIND_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBUNWIND_C_FLAGS'.
+macro(add_c_flags)
+  foreach(f ${ARGN})
+    list(APPEND LIBUNWIND_C_FLAGS ${f})
+  endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBUNWIND_C_FLAGS'
+macro(add_c_flags_if condition)
+  if (${condition})
+    add_c_flags(${ARGN})
+  endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBUNWIND_C_FLAGS' if the
+# flag is supported by the C compiler.
+macro(add_c_compile_flags_if_supported)
+  foreach(flag ${ARGN})
+      mangle_name("${flag}" flagname)
+      check_c_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+      add_c_flags_if(LIBUNWIND_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBUNWIND_CXX_FLAGS'.
+macro(add_cxx_flags)
+  foreach(f ${ARGN})
+    list(APPEND LIBUNWIND_CXX_FLAGS ${f})
+  endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBUNWIND_CXX_FLAGS'
+macro(add_cxx_flags_if condition)
+  if (${condition})
+    add_cxx_flags(${ARGN})
+  endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBUNWIND_CXX_FLAGS' if the
+# flag is supported by the C compiler.
+macro(add_cxx_compile_flags_if_supported)
+  foreach(flag ${ARGN})
+      mangle_name("${flag}" flagname)
+      check_cxx_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+      add_cxx_flags_if(LIBUNWIND_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBUNWIND_LINK_FLAGS'.
+macro(add_link_flags)
+  foreach(f ${ARGN})
+    list(APPEND LIBUNWIND_LINK_FLAGS ${f})
+  endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBUNWIND_LINK_FLAGS'
+macro(add_link_flags_if condition)
+  if (${condition})
+    add_link_flags(${ARGN})
+  endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBUNWIND_LINK_FLAGS' if the
+# flag is supported by the C++ compiler.
+macro(add_link_flags_if_supported)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBUNWIND_SUPPORTS_${flagname}_FLAG")
+    add_link_flags_if(LIBUNWIND_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of libraries or link flags to 'LIBUNWIND_LIBRARIES'.
+macro(add_library_flags)
+  foreach(lib ${ARGN})
+    list(APPEND LIBUNWIND_LIBRARIES ${lib})
+  endforeach()
+endmacro()
+
+# if 'condition' is true then add the specified list of libraries and flags
+# to 'LIBUNWIND_LIBRARIES'.
+macro(add_library_flags_if condition)
+  if(${condition})
+    add_library_flags(${ARGN})
+  endif()
+endmacro()
+
+# Turn a comma separated CMake list into a space separated string.
+macro(split_list listname)
+  string(REPLACE ";" " " ${listname} "${${listname}}")
+endmacro()
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 07a95ce..02d2f13 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -68,43 +68,8 @@
 endif()
 
 # Check compiler flags
-check_c_compiler_flag(-funwind-tables         LIBUNWIND_HAS_FUNWIND_TABLES)
-check_cxx_compiler_flag(-fno-exceptions       LIBUNWIND_HAS_NO_EXCEPTIONS_FLAG)
-check_cxx_compiler_flag(-fno-rtti             LIBUNWIND_HAS_NO_RTTI_FLAG)
-check_cxx_compiler_flag(-fstrict-aliasing     LIBUNWIND_HAS_FSTRICT_ALIASING_FLAG)
-check_cxx_compiler_flag(-nostdinc++           LIBUNWIND_HAS_NOSTDINCXX_FLAG)
-check_cxx_compiler_flag(-Wall                 LIBUNWIND_HAS_WALL_FLAG)
-check_cxx_compiler_flag(-W                    LIBUNWIND_HAS_W_FLAG)
-check_cxx_compiler_flag(-Wno-unused-function  LIBUNWIND_HAS_WNO_UNUSED_FUNCTION_FLAG)
-check_cxx_compiler_flag(-Wunused-variable     LIBUNWIND_HAS_WUNUSED_VARIABLE_FLAG)
-check_cxx_compiler_flag(-Wunused-parameter    LIBUNWIND_HAS_WUNUSED_PARAMETER_FLAG)
-check_cxx_compiler_flag(-Wstrict-aliasing     LIBUNWIND_HAS_WSTRICT_ALIASING_FLAG)
-check_cxx_compiler_flag(-Wstrict-overflow     LIBUNWIND_HAS_WSTRICT_OVERFLOW_FLAG)
-check_cxx_compiler_flag(-Wwrite-strings       LIBUNWIND_HAS_WWRITE_STRINGS_FLAG)
-check_cxx_compiler_flag(-Wchar-subscripts     LIBUNWIND_HAS_WCHAR_SUBSCRIPTS_FLAG)
-check_cxx_compiler_flag(-Wmismatched-tags     LIBUNWIND_HAS_WMISMATCHED_TAGS_FLAG)
-check_cxx_compiler_flag(-Wmissing-braces      LIBUNWIND_HAS_WMISSING_BRACES_FLAG)
-check_cxx_compiler_flag(-Wshorten-64-to-32    LIBUNWIND_HAS_WSHORTEN_64_TO_32_FLAG)
-check_cxx_compiler_flag(-Wsign-conversion     LIBUNWIND_HAS_WSIGN_CONVERSION_FLAG)
-check_cxx_compiler_flag(-Wsign-compare        LIBUNWIND_HAS_WSIGN_COMPARE_FLAG)
-check_cxx_compiler_flag(-Wshadow              LIBUNWIND_HAS_WSHADOW_FLAG)
-check_cxx_compiler_flag(-Wconversion          LIBUNWIND_HAS_WCONVERSION_FLAG)
-check_cxx_compiler_flag(-Wnewline-eof         LIBUNWIND_HAS_WNEWLINE_EOF_FLAG)
-check_cxx_compiler_flag(-Wundef               LIBUNWIND_HAS_WUNDEF_FLAG)
-check_cxx_compiler_flag(-pedantic             LIBUNWIND_HAS_PEDANTIC_FLAG)
-check_cxx_compiler_flag(-Werror               LIBUNWIND_HAS_WERROR_FLAG)
-check_cxx_compiler_flag(-Wno-error            LIBUNWIND_HAS_WNO_ERROR_FLAG)
-check_cxx_compiler_flag(/WX                   LIBUNWIND_HAS_WX_FLAG)
-check_cxx_compiler_flag(/WX-                  LIBUNWIND_HAS_NO_WX_FLAG)
-check_cxx_compiler_flag(/EHsc                 LIBUNWIND_HAS_EHSC_FLAG)
-check_cxx_compiler_flag(/EHs-                 LIBUNWIND_HAS_NO_EHS_FLAG)
-check_cxx_compiler_flag(/EHa-                 LIBUNWIND_HAS_NO_EHA_FLAG)
-check_cxx_compiler_flag(/GR-                  LIBUNWIND_HAS_NO_GR_FLAG)
-check_cxx_compiler_flag(-std=c++11            LIBUNWIND_HAS_STD_CXX11)
+check_cxx_compiler_flag(-nostdinc++ LIBUNWIND_HAS_NOSTDINCXX_FLAG)
 
-if(LIBUNWIND_HAS_STD_CXX11)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-endif()
-
+# Check libraries
 check_library_exists(dl dladdr "" LIBUNWIND_HAS_DL_LIB)
 check_library_exists(pthread pthread_once "" LIBUNWIND_HAS_PTHREAD_LIB)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 572c823..0b2a830 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,7 +5,11 @@
     Unwind-EHABI.cpp
     Unwind-seh.cpp
     )
-unwind_append_if(LIBUNWIND_CXX_SOURCES APPLE Unwind_AppleExtras.cpp)
+if(APPLE)
+  list(APPEND LIBUNWIND_CXX_SOURCES
+    Unwind_AppleExtras.cpp
+    )
+endif()
 
 set(LIBUNWIND_C_SOURCES
     UnwindLevel1.c
@@ -39,10 +43,11 @@
     ../include/libunwind.h
     ../include/unwind.h
     )
-
-unwind_append_if(LIBUNWIND_HEADERS APPLE
+if(APPLE)
+  list(APPEND LIBUNWIND_HEADERS
     ../include/mach-o/compact_unwind_encoding.h
     )
+endif()
 
 if (MSVC_IDE)
   # Force them all into the headers dir on MSVC, otherwise they end up at
@@ -56,32 +61,28 @@
     ${LIBUNWIND_ASM_SOURCES})
 
 # Generate library list.
-set(libraries)
-unwind_append_if(libraries LIBUNWIND_HAS_C_LIB c)
+add_library_flags_if(LIBUNWIND_HAS_C_LIB c)
 if (LIBUNWIND_USE_COMPILER_RT)
-  list(APPEND libraries "${LIBUNWIND_BUILTINS_LIBRARY}")
+  add_library_flags("${LIBUNWIND_BUILTINS_LIBRARY}")
 else()
-  unwind_append_if(libraries LIBUNWIND_HAS_GCC_S_LIB gcc_s)
-  unwind_append_if(libraries LIBUNWIND_HAS_GCC_LIB gcc)
+  add_library_flags_if(LIBUNWIND_HAS_GCC_S_LIB gcc_s)
+  add_library_flags_if(LIBUNWIND_HAS_GCC_LIB gcc)
 endif()
-unwind_append_if(libraries LIBUNWIND_HAS_DL_LIB dl)
+add_library_flags_if(LIBUNWIND_HAS_DL_LIB dl)
 if (LIBUNWIND_ENABLE_THREADS)
-  unwind_append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread)
-  unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_WEAK_PTHREAD_LIB -DLIBUNWIND_USE_WEAK_PTHREAD=1)
+  add_library_flags_if(LIBUNWIND_HAS_PTHREAD_LIB pthread)
+  add_compile_flags_if(LIBUNWIND_WEAK_PTHREAD_LIB -DLIBUNWIND_USE_WEAK_PTHREAD=1)
 endif()
 
 # Setup flags.
-unwind_append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_NO_RTTI_FLAG -fno-rtti)
-
-unwind_append_if(LIBUNWIND_LINK_FLAGS LIBUNWIND_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
+add_link_flags_if_supported(-nodefaultlibs)
 
 # MINGW_LIBRARIES is defined in config-ix.cmake
-unwind_append_if(libraries MINGW "${MINGW_LIBRARIES}")
+add_library_flags_if(MINGW "${MINGW_LIBRARIES}")
 
-if (LIBUNWIND_HAS_NO_EXCEPTIONS_FLAG AND LIBUNWIND_HAS_FUNWIND_TABLES)
-  list(APPEND LIBUNWIND_COMPILE_FLAGS -fno-exceptions)
-  list(APPEND LIBUNWIND_COMPILE_FLAGS -funwind-tables)
-elseif (LIBUNWIND_ENABLE_SHARED)
+if (LIBUNWIND_ENABLE_SHARED AND
+    NOT (LIBUNWIND_SUPPORTS_FNO_EXCEPTIONS_FLAG AND
+         LIBUNWIND_SUPPORTS_FUNWIND_TABLES_FLAG))
   message(FATAL_ERROR
           "Compiler doesn't support generation of unwind tables if exception "
           "support is disabled.  Building libunwind DSO with runtime dependency "
@@ -89,15 +90,11 @@
 endif()
 
 if (APPLE)
-  list(APPEND LIBUNWIND_COMPILE_FLAGS "-U__STRICT_ANSI__")
-  list(APPEND LIBUNWIND_LINK_FLAGS
-       "-compatibility_version 1"
-       "-install_name /usr/lib/libunwind.1.dylib")
+  add_compile_flags("-U__STRICT_ANSI__")
+  add_link_flags("-compatibility_version 1" "-install_name /usr/lib/libunwind.1.dylib")
 
   if (CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6")
-    list(APPEND LIBUNWIND_LINK_FLAGS
-         "-current_version ${LIBUNWIND_VERSION}"
-         "/usr/lib/libSystem.B.dylib")
+    add_link_flags("-current_version ${LIBUNWIND_VERSION}" "/usr/lib/libSystem.B.dylib")
   endif ()
 endif ()
 
@@ -117,14 +114,23 @@
   if(COMMAND llvm_setup_rpath)
     llvm_setup_rpath(unwind_shared)
   endif()
-  target_link_libraries(unwind_shared PRIVATE ${libraries})
+  target_link_libraries(unwind_shared PRIVATE ${LIBUNWIND_LIBRARIES})
   set_target_properties(unwind_shared
                         PROPERTIES
-                          COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
-                          LINK_FLAGS    "${LIBUNWIND_LINK_FLAGS}"
-                          OUTPUT_NAME   "unwind"
-                          VERSION       "1.0"
-                          SOVERSION     "1")
+                          CXX_STANDARD
+                            11
+                          CXX_STANDARD_REQUIRED
+                            ON
+                          COMPILE_FLAGS
+                            "${LIBUNWIND_COMPILE_FLAGS}"
+                          LINK_FLAGS
+                            "${LIBUNWIND_LINK_FLAGS}"
+                          OUTPUT_NAME
+                            "unwind"
+                          VERSION
+                            "1.0"
+                          SOVERSION
+                            "1")
   list(APPEND LIBUNWIND_BUILD_TARGETS "unwind_shared")
   if (LIBUNWIND_INSTALL_SHARED_LIBRARY)
     list(APPEND LIBUNWIND_INSTALL_TARGETS "unwind_shared")
@@ -134,12 +140,19 @@
 # Build the static library.
 if (LIBUNWIND_ENABLE_STATIC)
   add_library(unwind_static STATIC ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
-  target_link_libraries(unwind_static PRIVATE ${libraries})
+  target_link_libraries(unwind_static PRIVATE ${LIBUNWIND_LIBRARIES})
   set_target_properties(unwind_static
                         PROPERTIES
-                          COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
-                          LINK_FLAGS    "${LIBUNWIND_LINK_FLAGS}"
-                          OUTPUT_NAME   "unwind")
+                          CXX_STANDARD
+                            11
+                          CXX_STANDARD_REQUIRED
+                            ON
+                          COMPILE_FLAGS
+                            "${LIBUNWIND_COMPILE_FLAGS}"
+                          LINK_FLAGS
+                            "${LIBUNWIND_LINK_FLAGS}"
+                          OUTPUT_NAME
+                            "unwind")
 
   if(LIBUNWIND_HERMETIC_STATIC_LIBRARY)
     append_flags_if_supported(UNWIND_STATIC_LIBRARY_FLAGS -fvisibility=hidden)