summary refs log tree commit diff
path: root/pkgs/development/compilers/llvm/7/clang
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/compilers/llvm/7/clang')
-rw-r--r--pkgs/development/compilers/llvm/7/clang/default.nix24
-rw-r--r--pkgs/development/compilers/llvm/7/clang/gnu-install-dirs.patch281
-rw-r--r--pkgs/development/compilers/llvm/7/clang/unwindlib.patch227
3 files changed, 526 insertions, 6 deletions
diff --git a/pkgs/development/compilers/llvm/7/clang/default.nix b/pkgs/development/compilers/llvm/7/clang/default.nix
index 4ab13441e36..187602ef361 100644
--- a/pkgs/development/compilers/llvm/7/clang/default.nix
+++ b/pkgs/development/compilers/llvm/7/clang/default.nix
@@ -1,4 +1,5 @@
-{ lib, stdenv, fetch, cmake, libxml2, llvm, version, clang-tools-extra_src, python3, lld
+{ lib, stdenv, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3
+, buildLlvmTools
 , fixDarwinDylibNames
 , enableManpages ? false
 , enablePolly ? false # TODO: get this info from llvm (passthru?)
@@ -23,17 +24,21 @@ let
       ++ lib.optional enableManpages python3.pkgs.sphinx
       ++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames;
 
-    buildInputs = [ libxml2 llvm lld ];
+    buildInputs = [ libxml2 libllvm ];
 
     cmakeFlags = [
       "-DCMAKE_CXX_FLAGS=-std=c++11"
       "-DLLVM_ENABLE_RTTI=ON"
+      "-DLLVM_CONFIG_PATH=${libllvm.dev}/bin/llvm-config${lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) "-native"}"
     ] ++ lib.optionals enableManpages [
       "-DCLANG_INCLUDE_DOCS=ON"
       "-DLLVM_ENABLE_SPHINX=ON"
       "-DSPHINX_OUTPUT_MAN=ON"
       "-DSPHINX_OUTPUT_HTML=OFF"
       "-DSPHINX_WARNINGS_AS_ERRORS=OFF"
+    ] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
+      "-DLLVM_TABLEGEN_EXE=${buildLlvmTools.llvm}/bin/llvm-tblgen"
+      "-DCLANG_TABLEGEN=${buildLlvmTools.libclang.dev}/bin/clang-tblgen"
     ] ++ lib.optionals enablePolly [
       "-DWITH_POLLY=ON"
       "-DLINK_POLLY_INTO_TOOLS=ON"
@@ -43,6 +48,10 @@ let
       ./purity.patch
       # make clang -xhip use $PATH to find executables
       ./HIP-use-PATH-7.patch
+      # Backport for the `--unwindlib=[libgcc|compiler-rt]` flag, which is
+      # needed for our bootstrapping to not interfere with C.
+      ./unwindlib.patch
+      ./gnu-install-dirs.patch
     ];
 
     postPatch = ''
@@ -59,12 +68,12 @@ let
         --replace "NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB" FALSE
     '';
 
-    outputs = [ "out" "lib" "python" ];
+    outputs = [ "out" "lib" "dev" "python" ];
 
     # Clang expects to find LLVMgold in its own prefix
     postInstall = ''
-      if [ -e ${llvm}/lib/LLVMgold.so ]; then
-        ln -sv ${llvm}/lib/LLVMgold.so $out/lib
+      if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then
+        ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib
       fi
 
       ln -sv $out/bin/clang $out/bin/cpp
@@ -81,11 +90,14 @@ let
       fi
       mv $out/share/clang/*.py $python/share/clang
       rm $out/bin/c-index-test
+
+      mkdir -p $dev/bin
+      cp bin/clang-tblgen $dev/bin
     '';
 
     passthru = {
       isClang = true;
-      inherit llvm;
+      inherit libllvm;
     };
 
     meta = {
diff --git a/pkgs/development/compilers/llvm/7/clang/gnu-install-dirs.patch b/pkgs/development/compilers/llvm/7/clang/gnu-install-dirs.patch
new file mode 100644
index 00000000000..540c043a2db
--- /dev/null
+++ b/pkgs/development/compilers/llvm/7/clang/gnu-install-dirs.patch
@@ -0,0 +1,281 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 52b881939499..85662a2113e7 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -5,6 +5,8 @@ cmake_minimum_required(VERSION 3.4.3)
+ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
+   project(Clang)
+ 
++  include(GNUInstallDirs)
++
+   # Rely on llvm-config.
+   set(CONFIG_OUTPUT)
+   find_program(LLVM_CONFIG "llvm-config")
+@@ -374,7 +376,7 @@ include_directories(BEFORE
+ 
+ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+   install(DIRECTORY include/clang include/clang-c
+-    DESTINATION include
++    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+     FILES_MATCHING
+     PATTERN "*.def"
+     PATTERN "*.h"
+@@ -383,7 +385,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+     )
+ 
+   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/clang
+-    DESTINATION include
++    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+     FILES_MATCHING
+     PATTERN "CMakeFiles" EXCLUDE
+     PATTERN "*.inc"
+@@ -391,7 +393,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+     )
+ 
+   install(PROGRAMS utils/bash-autocomplete.sh
+-    DESTINATION share/clang
++    DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+     )
+ endif()
+ 
+diff --git a/cmake/modules/AddClang.cmake b/cmake/modules/AddClang.cmake
+index c09a8423f9f6..39f37e0097eb 100644
+--- a/cmake/modules/AddClang.cmake
++++ b/cmake/modules/AddClang.cmake
+@@ -99,9 +99,9 @@ macro(add_clang_library name)
+       install(TARGETS ${name}
+         COMPONENT ${name}
+         ${export_to_clangtargets}
+-        LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+-        ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+-        RUNTIME DESTINATION bin)
++        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}
++        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}
++        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+ 
+       if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES)
+         add_llvm_install_targets(install-${name}
+@@ -141,7 +141,7 @@ macro(add_clang_tool name)
+ 
+     install(TARGETS ${name}
+       ${export_to_clangtargets}
+-      RUNTIME DESTINATION bin
++      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+       COMPONENT ${name})
+ 
+     if(NOT CMAKE_CONFIGURATION_TYPES)
+@@ -156,5 +156,5 @@ endmacro()
+ macro(add_clang_symlink name dest)
+   add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE)
+   # Always generate install targets
+-  llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE)
++  llvm_install_symlink(${name} ${dest} ${CMAKE_INSTALL_FULL_BINDIR} ALWAYS_GENERATE)
+ endmacro()
+diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
+index 1930d8e225c7..bb9158093079 100644
+--- a/lib/Headers/CMakeLists.txt
++++ b/lib/Headers/CMakeLists.txt
+@@ -162,19 +162,19 @@ install(
+   FILES ${files} ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
+   COMPONENT clang-headers
+   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+-  DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
++  DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
+ 
+ install(
+   FILES ${files} ${CMAKE_CURRENT_BINARY_DIR}/arm_fp16.h
+   COMPONENT clang-headers
+   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+-  DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
++  DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
+ 
+ install(
+   FILES ${cuda_wrapper_files}
+   COMPONENT clang-headers
+   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+-  DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include/cuda_wrappers)
++  DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include/cuda_wrappers)
+ 
+ if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's.
+   add_llvm_install_targets(install-clang-headers
+diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
+index 53e3421f1b35..79ae5bb4c399 100644
+--- a/tools/c-index-test/CMakeLists.txt
++++ b/tools/c-index-test/CMakeLists.txt
+@@ -54,7 +54,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+     set_property(TARGET c-index-test APPEND PROPERTY INSTALL_RPATH
+        "@executable_path/../../lib")
+   else()
+-    set(INSTALL_DESTINATION bin)
++    set(INSTALL_DESTINATION ${CMAKE_INSTALL_BINDIR})
+   endif()
+ 
+   install(TARGETS c-index-test
+diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
+index c5ace26c2914..97bdfca7d896 100644
+--- a/tools/clang-check/CMakeLists.txt
++++ b/tools/clang-check/CMakeLists.txt
+@@ -20,4 +20,4 @@ target_link_libraries(clang-check
+   )
+ 
+ install(TARGETS clang-check
+-  RUNTIME DESTINATION bin)
++  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+diff --git a/tools/clang-format/CMakeLists.txt b/tools/clang-format/CMakeLists.txt
+index a295e8cd0b2a..1973ff82c7f6 100644
+--- a/tools/clang-format/CMakeLists.txt
++++ b/tools/clang-format/CMakeLists.txt
+@@ -21,20 +21,20 @@ if( LLVM_LIB_FUZZING_ENGINE OR LLVM_USE_SANITIZE_COVERAGE )
+ endif()
+ 
+ install(PROGRAMS clang-format-bbedit.applescript
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-format)
+ install(PROGRAMS clang-format-diff.py
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-format)
+ install(PROGRAMS clang-format-sublime.py
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-format)
+ install(PROGRAMS clang-format.el
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-format)
+ install(PROGRAMS clang-format.py
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-format)
+ install(PROGRAMS git-clang-format
+-  DESTINATION bin
++  DESTINATION ${CMAKE_INSTALL_BINDIR}
+   COMPONENT clang-format)
+diff --git a/tools/clang-func-mapping/CMakeLists.txt b/tools/clang-func-mapping/CMakeLists.txt
+index ae28e28d532d..8ecb2e37a8f7 100644
+--- a/tools/clang-func-mapping/CMakeLists.txt
++++ b/tools/clang-func-mapping/CMakeLists.txt
+@@ -20,4 +20,4 @@ target_link_libraries(clang-func-mapping
+   )
+ 
+ install(TARGETS clang-func-mapping
+-  RUNTIME DESTINATION bin)
++  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+diff --git a/tools/clang-offload-bundler/CMakeLists.txt b/tools/clang-offload-bundler/CMakeLists.txt
+index 8718015be76a..7a038f39622e 100644
+--- a/tools/clang-offload-bundler/CMakeLists.txt
++++ b/tools/clang-offload-bundler/CMakeLists.txt
+@@ -22,4 +22,4 @@ target_link_libraries(clang-offload-bundler
+   ${CLANG_OFFLOAD_BUNDLER_LIB_DEPS}
+   )
+ 
+-install(TARGETS clang-offload-bundler RUNTIME DESTINATION bin)
++install(TARGETS clang-offload-bundler RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+diff --git a/tools/clang-rename/CMakeLists.txt b/tools/clang-rename/CMakeLists.txt
+index 3b3ab1540a80..9aca9ba4a2cf 100644
+--- a/tools/clang-rename/CMakeLists.txt
++++ b/tools/clang-rename/CMakeLists.txt
+@@ -18,8 +18,8 @@ target_link_libraries(clang-rename
+   )
+ 
+ install(PROGRAMS clang-rename.py
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-rename)
+ install(PROGRAMS clang-rename.el
+-  DESTINATION share/clang
++  DESTINATION ${CMAKE_INSTALL_DATADIR}/clang
+   COMPONENT clang-rename)
+diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
+index 96d1c390249c..41c762b37b76 100644
+--- a/tools/diagtool/CMakeLists.txt
++++ b/tools/diagtool/CMakeLists.txt
+@@ -21,7 +21,7 @@ target_link_libraries(diagtool
+ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+   install(TARGETS diagtool
+     COMPONENT diagtool
+-    RUNTIME DESTINATION bin)
++    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+ 
+   if (NOT CMAKE_CONFIGURATION_TYPES)
+     add_llvm_install_targets(install-diagtool
+diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
+index e539c8308e75..4e1fbccea35d 100644
+--- a/tools/libclang/CMakeLists.txt
++++ b/tools/libclang/CMakeLists.txt
+@@ -130,7 +130,7 @@ endif()
+ if(INTERNAL_INSTALL_PREFIX)
+   set(LIBCLANG_HEADERS_INSTALL_DESTINATION "${INTERNAL_INSTALL_PREFIX}/include")
+ else()
+-  set(LIBCLANG_HEADERS_INSTALL_DESTINATION include)
++  set(LIBCLANG_HEADERS_INSTALL_DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+ endif()
+ 
+ install(DIRECTORY ../../include/clang-c
+diff --git a/tools/scan-build/CMakeLists.txt b/tools/scan-build/CMakeLists.txt
+index 380379300b09..adfd58ed5f7d 100644
+--- a/tools/scan-build/CMakeLists.txt
++++ b/tools/scan-build/CMakeLists.txt
+@@ -41,7 +41,7 @@ if(CLANG_INSTALL_SCANBUILD)
+                          ${CMAKE_BINARY_DIR}/bin/
+                        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin/${BinFile})
+     list(APPEND Depends ${CMAKE_BINARY_DIR}/bin/${BinFile})
+-    install(PROGRAMS bin/${BinFile} DESTINATION bin)
++    install(PROGRAMS bin/${BinFile} DESTINATION ${CMAKE_INSTALL_BINDIR})
+   endforeach()
+ 
+   foreach(LibexecFile ${LibexecFiles})
+@@ -53,7 +53,7 @@ if(CLANG_INSTALL_SCANBUILD)
+                          ${CMAKE_BINARY_DIR}/libexec/
+                        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libexec/${LibexecFile})
+     list(APPEND Depends ${CMAKE_BINARY_DIR}/libexec/${LibexecFile})
+-    install(PROGRAMS libexec/${LibexecFile} DESTINATION libexec)
++    install(PROGRAMS libexec/${LibexecFile} DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})
+   endforeach()
+ 
+   foreach(ManPage ${ManPages})
+@@ -77,7 +77,7 @@ if(CLANG_INSTALL_SCANBUILD)
+                          ${CMAKE_BINARY_DIR}/share/scan-build/
+                        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/share/scan-build/${ShareFile})
+     list(APPEND Depends ${CMAKE_BINARY_DIR}/share/scan-build/${ShareFile})
+-    install(FILES share/scan-build/${ShareFile} DESTINATION share/scan-build)
++    install(FILES share/scan-build/${ShareFile} DESTINATION ${CMAKE_INSTALL_DATADIR}/scan-build)
+   endforeach()
+ 
+   add_custom_target(scan-build ALL DEPENDS ${Depends})
+diff --git a/tools/scan-view/CMakeLists.txt b/tools/scan-view/CMakeLists.txt
+index b305ca562a72..554bcb379061 100644
+--- a/tools/scan-view/CMakeLists.txt
++++ b/tools/scan-view/CMakeLists.txt
+@@ -21,7 +21,7 @@ if(CLANG_INSTALL_SCANVIEW)
+                          ${CMAKE_BINARY_DIR}/bin/
+                        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin/${BinFile})
+     list(APPEND Depends ${CMAKE_BINARY_DIR}/bin/${BinFile})
+-    install(PROGRAMS bin/${BinFile} DESTINATION bin)
++    install(PROGRAMS bin/${BinFile} DESTINATION ${CMAKE_INSTALL_BINDIR})
+   endforeach()
+ 
+   foreach(ShareFile ${ShareFiles})
+@@ -33,7 +33,7 @@ if(CLANG_INSTALL_SCANVIEW)
+                          ${CMAKE_BINARY_DIR}/share/scan-view/
+                        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/share/${ShareFile})
+     list(APPEND Depends ${CMAKE_BINARY_DIR}/share/scan-view/${ShareFile})
+-    install(FILES share/${ShareFile} DESTINATION share/scan-view)
++    install(FILES share/${ShareFile} DESTINATION ${CMAKE_INSTALL_DATADIR}/scan-view)
+   endforeach()
+ 
+   add_custom_target(scan-view ALL DEPENDS ${Depends})
+diff --git a/utils/hmaptool/CMakeLists.txt b/utils/hmaptool/CMakeLists.txt
+index 5573009d343a..24b3a90f233f 100644
+--- a/utils/hmaptool/CMakeLists.txt
++++ b/utils/hmaptool/CMakeLists.txt
+@@ -9,7 +9,7 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/${CLANG_HM
+                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${CLANG_HMAPTOOL})
+ 
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/${CLANG_HMAPTOOL})
+-install(PROGRAMS ${CLANG_HMAPTOOL} DESTINATION bin)
++install(PROGRAMS ${CLANG_HMAPTOOL} DESTINATION ${CMAKE_INSTALL_BINDIR})
+ 
+ add_custom_target(hmaptool ALL DEPENDS ${Depends})
+ set_target_properties(hmaptool PROPERTIES FOLDER "Utils")
diff --git a/pkgs/development/compilers/llvm/7/clang/unwindlib.patch b/pkgs/development/compilers/llvm/7/clang/unwindlib.patch
new file mode 100644
index 00000000000..59a092d7c70
--- /dev/null
+++ b/pkgs/development/compilers/llvm/7/clang/unwindlib.patch
@@ -0,0 +1,227 @@
+commit a5cacb5ba7f1f18e7bb6f6709e42683eeb7e6470
+Author: Sterling Augustine <saugustine@google.com>
+Date:   Tue Mar 19 20:01:59 2019 +0000
+
+    Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib= [take 2]
+    
+    "clang++ hello.cc --rtlib=compiler-rt"
+    
+    now can works without specifying additional unwind or exception
+    handling libraries.
+    
+    This reworked version of the feature no longer modifies today's default
+    unwind library for compiler-rt: which is nothing. Rather, a user
+    can specify -DCLANG_DEFAULT_UNWINDLIB=libunwind when configuring
+    the compiler.
+    
+    This should address the issues from the previous version.
+    
+    Update tests for new --unwindlib semantics.
+    
+    Differential Revision: https://reviews.llvm.org/D59109
+    
+    llvm-svn: 356508
+
+diff --git clang/CMakeLists.txt clang/CMakeLists.txt
+index 52b881939499..2c3fb62f6e73 100644
+--- clang/CMakeLists.txt
++++ clang/CMakeLists.txt
+@@ -244,6 +244,24 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL "" OR
+     "Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE)
+ endif()
+ 
++set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
++  "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty to match runtime library.)")
++if (CLANG_DEFAULT_UNWINDLIB STREQUAL "")
++  if (CLANG_DEFAULT_RTLIB STREQUAL "libgcc")
++    set (CLANG_DEFAULT_UNWINDLIB "libgcc" CACHE STRING "" FORCE)
++  elseif (CLANG_DEFAULT_RTLIBS STREQUAL "libunwind")
++    set (CLANG_DEFAULT_UNWINDLIB "none" CACHE STRING "" FORCE)
++  endif()
++endif()
++
++if (NOT(CLANG_DEFAULT_UNWINDLIB STREQUAL "none" OR
++        CLANG_DEFAULT_UNWINDLIB STREQUAL "libgcc" OR
++        CLANG_DEFAULT_UNWINDLIB STREQUAL "libunwind"))
++  message(WARNING "Resetting default unwindlib to use platform default")
++  set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
++    "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty for none)" FORCE)
++endif()
++
+ set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING
+   "Default objcopy executable to use.")
+ 
+diff --git clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticDriverKinds.td
+index 7f75f45c6578..7e1bb33b5cef 100644
+--- clang/include/clang/Basic/DiagnosticDriverKinds.td
++++ clang/include/clang/Basic/DiagnosticDriverKinds.td
+@@ -52,6 +52,10 @@ def err_drv_invalid_rtlib_name : Error<
+   "invalid runtime library name in argument '%0'">;
+ def err_drv_unsupported_rtlib_for_platform : Error<
+   "unsupported runtime library '%0' for platform '%1'">;
++def err_drv_invalid_unwindlib_name : Error<
++  "invalid unwind library name in argument '%0'">;
++def err_drv_incompatible_unwindlib : Error<
++  "--rtlib=libgcc requires --unwindlib=libgcc">;
+ def err_drv_invalid_stdlib_name : Error<
+   "invalid library name in argument '%0'">;
+ def err_drv_invalid_output_with_multiple_archs : Error<
+diff --git clang/include/clang/Config/config.h.cmake clang/include/clang/Config/config.h.cmake
+index 1d624450b9d9..2d4cb747e87e 100644
+--- clang/include/clang/Config/config.h.cmake
++++ clang/include/clang/Config/config.h.cmake
+@@ -23,6 +23,9 @@
+ /* Default runtime library to use. */
+ #define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
+ 
++/* Default unwind library to use. */
++#define CLANG_DEFAULT_UNWINDLIB "${CLANG_DEFAULT_UNWINDLIB}"
++
+ /* Default objcopy to use */
+ #define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
+ 
+diff --git clang/include/clang/Driver/Options.td clang/include/clang/Driver/Options.td
+index 601aa8744967..0e74a2d36dea 100644
+--- clang/include/clang/Driver/Options.td
++++ clang/include/clang/Driver/Options.td
+@@ -2428,6 +2428,8 @@ def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
+   }]>;
+ def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
+   HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
++def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>,
++  HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">;
+ def sub__library : JoinedOrSeparate<["-"], "sub_library">;
+ def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
+ def system_header_prefix : Joined<["--"], "system-header-prefix=">,
+diff --git clang/include/clang/Driver/ToolChain.h clang/include/clang/Driver/ToolChain.h
+index 2f9c2c190e32..d5b131bcf112 100644
+--- clang/include/clang/Driver/ToolChain.h
++++ clang/include/clang/Driver/ToolChain.h
+@@ -99,6 +99,12 @@ public:
+     RLT_Libgcc
+   };
+ 
++  enum UnwindLibType {
++    UNW_None,
++    UNW_CompilerRT,
++    UNW_Libgcc
++  };
++
+   enum RTTIMode {
+     RM_Enabled,
+     RM_Disabled,
+@@ -352,6 +358,10 @@ public:
+     return ToolChain::CST_Libstdcxx;
+   }
+ 
++  virtual UnwindLibType GetDefaultUnwindLibType() const {
++    return ToolChain::UNW_None;
++  }
++
+   virtual std::string getCompilerRTPath() const;
+ 
+   virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
+@@ -484,6 +494,10 @@ public:
+   // given compilation arguments.
+   virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+ 
++  // GetUnwindLibType - Determine the unwind library type to use with the
++  // given compilation arguments.
++  virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
++
+   /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
+   /// the include paths to use for the given C++ standard library type.
+   virtual void
+diff --git clang/lib/Driver/ToolChain.cpp clang/lib/Driver/ToolChain.cpp
+index cf3db34688df..d980dd5d23fb 100644
+--- clang/lib/Driver/ToolChain.cpp
++++ clang/lib/Driver/ToolChain.cpp
+@@ -665,6 +665,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
+   return GetDefaultRuntimeLibType();
+ }
+ 
++ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
++    const ArgList &Args) const {
++  const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
++  StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
++
++  if (LibName == "none")
++    return ToolChain::UNW_None;
++  else if (LibName == "platform" || LibName == "") {
++    ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
++    if (RtLibType == ToolChain::RLT_CompilerRT)
++      return ToolChain::UNW_None;
++    else if (RtLibType == ToolChain::RLT_Libgcc)
++      return ToolChain::UNW_Libgcc;
++  } else if (LibName == "libunwind") {
++    if (GetRuntimeLibType(Args) == RLT_Libgcc)
++      getDriver().Diag(diag::err_drv_incompatible_unwindlib);
++    return ToolChain::UNW_CompilerRT;
++  } else if (LibName == "libgcc")
++    return ToolChain::UNW_Libgcc;
++
++  if (A)
++    getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
++        << A->getAsString(Args);
++
++  return GetDefaultUnwindLibType();
++}
++
+ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
+   const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
+   StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
+diff --git clang/test/Driver/compiler-rt-unwind.c clang/test/Driver/compiler-rt-unwind.c
+new file mode 100644
+index 000000000000..00024dfa7ed3
+--- /dev/null
++++ clang/test/Driver/compiler-rt-unwind.c
+@@ -0,0 +1,49 @@
++// General tests that the driver handles combinations of --rtlib=XXX and
++// --unwindlib=XXX properly.
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-EMPTY %s
++// RTLIB-EMPTY: "{{.*}}lgcc"
++// RTLIB-EMPTY: "{{.*}}-lgcc_s"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-GCC %s
++// RTLIB-GCC: "{{.*}}lgcc"
++// RTLIB-GCC: "{{.*}}lgcc_s"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
++// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
++// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
++// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT %s
++// RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
++// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins-x86_64.a"
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}lgcc_s"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1              \
++// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
++// RUN:     -static --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins-x86_64.a"
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}lgcc_eh"
++//
++// RUN: not %clang -no-canonical-prefixes %s -o %t.o 2> %t.err              \
++// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
++// RUN:     --gcc-toolchain="" \
++// RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s
++// RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc"