samsonov created this revision.
samsonov added reviewers: rafael, compnerd.
samsonov added a subscriber: cfe-commits.

After this change, AddCXXStdlibLibArgs will check the presence of
-static-libstdc++ flag and, if necessary, wrap -lc++/-lstdc++ in
-Bstatic/-Bdynamic to force static linking of C++ standard library.

It's no longer necessary to copy this code around across toolchains
(unless toolchain is overriding AddCXXStdlibLibArgs).

This change has an important consequnce: if the user provides "-lstdc++"
manually (i.e. it's not added automatically when we're linking C++ binary),
then "-static-libstdc++" *will* work as expected.

Other than that, the change attempts to preserve the existing behavior.

http://reviews.llvm.org/D15598

Files:
  lib/Driver/CrossWindowsToolChain.cpp
  lib/Driver/ToolChain.cpp
  lib/Driver/ToolChains.cpp
  lib/Driver/Tools.cpp
  test/Driver/static-libstdcxx.c

Index: test/Driver/static-libstdcxx.c
===================================================================
--- /dev/null
+++ test/Driver/static-libstdcxx.c
@@ -0,0 +1,11 @@
+// RUN: %clang -no-canonical-prefixes -target x86_64-unknown-linux -static-libstdc++ %s -### 2>&1 | FileCheck %s --check-prefix=C-ONLY-CODE
+// C-ONLY-CODE: warning: argument unused during compilation: '-static-libstdc++'
+
+// RUN: %clang --driver-mode=g++ -no-canonical-prefixes -target x86_64-unknown-linux -static-libstdc++ %s -### 2>&1 | FileCheck %s --check-prefix=CXX-CODE
+// CXX-CODE: "-Bstatic" "-lstdc++" "-Bdynamic"
+
+// RUN: %clang --driver-mode=g++ -no-canonical-prefixes -target x86_64-unknown-linux -static-libstdc++ -stdlib=libc++ %s -### 2>&1 | FileCheck %s --check-prefix=LIBCXX
+// LIBCXX: "-Bstatic" "-lc++" "-Bdynamic"
+
+// RUN: %clang -no-canonical-prefixes -target x86_64-unknown-linux -static-libstdc++ -lstdc++ %s -### 2>&1 | FileCheck %s --check-prefix=C-CODE-WITH-EXPLICIT-LSTDCXX
+// C-CODE-WITH-EXPLICIT-LSTDCXX: "-Bstatic" "-lstdc++" "-Bdynamic"
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -8754,13 +8754,7 @@
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                               !Args.hasArg(options::OPT_static);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
     ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
     CmdArgs.push_back("-lm");
   }
   // Silence warnings when linking C code with a C++ '-stdlib' argument.
@@ -8946,13 +8940,7 @@
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic =
-        Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
     ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
     CmdArgs.push_back("-lm");
   }
 
@@ -9704,13 +9692,7 @@
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                               !Args.hasArg(options::OPT_static);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
     TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
   }
 
   if (!Args.hasArg(options::OPT_nostdlib)) {
@@ -9978,13 +9960,7 @@
 
   if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nodefaultlibs)) {
-    bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
-                     !Args.hasArg(options::OPT_static);
-    if (StaticCXX)
-      CmdArgs.push_back("-Bstatic");
     TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (StaticCXX)
-      CmdArgs.push_back("-Bdynamic");
   }
 
   if (!Args.hasArg(options::OPT_nostdlib)) {
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -2849,7 +2849,15 @@
   // Check for -stdlib= flags. We only support libc++ but this consumes the arg
   // if the value is libc++, and emits an error for other values.
   GetCXXStdlibType(Args);
+  const bool IsStatic =
+      !Args.hasArg(options::OPT_dynamic) && !Args.hasArg(options::OPT_shared);
+  const bool OnlyCXXStdlibStatic =
+      Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
+  if (OnlyCXXStdlibStatic)
+    CmdArgs.push_back("-Bstatic");
   CmdArgs.push_back("-lc++");
+  if (OnlyCXXStdlibStatic)
+    CmdArgs.push_back("-Bdynamic");
 }
 
 void NaClToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -604,7 +604,11 @@
 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
                                     ArgStringList &CmdArgs) const {
   CXXStdlibType Type = GetCXXStdlibType(Args);
+  bool OnlyCXXStdlibStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                             !Args.hasArg(options::OPT_static);
 
+  if (OnlyCXXStdlibStatic)
+    CmdArgs.push_back("-Bstatic");
   switch (Type) {
   case ToolChain::CST_Libcxx:
     CmdArgs.push_back("-lc++");
@@ -614,6 +618,8 @@
     CmdArgs.push_back("-lstdc++");
     break;
   }
+  if (OnlyCXXStdlibStatic)
+    CmdArgs.push_back("-Bdynamic");
 }
 
 void ToolChain::AddFilePathLibArgs(const ArgList &Args,
Index: lib/Driver/CrossWindowsToolChain.cpp
===================================================================
--- lib/Driver/CrossWindowsToolChain.cpp
+++ lib/Driver/CrossWindowsToolChain.cpp
@@ -92,6 +92,10 @@
 void CrossWindowsToolChain::
 AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
                     llvm::opt::ArgStringList &CC1Args) const {
+  bool OnlyCXXStdlibStatic = DriverArgs.hasArg(options::OPT_static_libstdcxx) &&
+                             !DriverArgs.hasArg(options::OPT_static);
+  if (OnlyCXXStdlibStatic)
+    CC1Args.push_back("-Bstatic");
   switch (GetCXXStdlibType(DriverArgs)) {
   case ToolChain::CST_Libcxx:
     CC1Args.push_back("-lc++");
@@ -105,6 +109,8 @@
     CC1Args.push_back("-lmingw32");
     break;
   }
+  if (OnlyCXXStdlibStatic)
+    CC1Args.push_back("-Bdynamic");
 }
 
 clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to