summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSterling Augustine <saugustine@google.com>2019-01-28 18:56:43 +0000
committerSterling Augustine <saugustine@google.com>2019-01-28 18:56:43 +0000
commit9490fcc1919e7e24bd411b1e72802c171881be55 (patch)
tree99aaa1c043ae6f05e00ef95b7d31d4a033c66e8f
parent586d949b9c554d5e5b7b445a49c122ce3d0e5c53 (diff)
downloadbcm5719-llvm-9490fcc1919e7e24bd411b1e72802c171881be55.tar.gz
bcm5719-llvm-9490fcc1919e7e24bd411b1e72802c171881be55.zip
Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib=
Summary: "clang++ hello.cc --rtlib=compiler-rt" now works without specifying additional unwind or exception handling libraries. Reviewers: rsmith Subscribers: srhines, dberris, aheejin, llvm-commits Differential Revision: https://reviews.llvm.org/D57128 llvm-svn: 352404
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/include/clang/Driver/ToolChain.h8
-rw-r--r--clang/lib/Driver/ToolChain.cpp27
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.cpp86
-rw-r--r--clang/test/Driver/compiler-rt-unwind.c50
6 files changed, 149 insertions, 28 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 189e0565a83..6f2b11a89c8 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -51,6 +51,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 a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 92ea40596c1..1fefb9a9d87 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2568,6 +2568,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_eh,compiler-rt-unwind,platform">;
def sub__library : JoinedOrSeparate<["-"], "sub_library">;
def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
def system_header_prefix : Joined<["--"], "system-header-prefix=">,
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index eec49ec3dde..7c75f254d15 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -367,6 +367,10 @@ public:
return ToolChain::CST_Libstdcxx;
}
+ virtual RuntimeLibType GetDefaultUnwindLibType() const {
+ return ToolChain::RLT_Libgcc;
+ }
+
virtual std::string getCompilerRTPath() const;
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
@@ -511,6 +515,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 RuntimeLibType 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 a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index fcf373e9f7f..42d9d91960a 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -679,6 +679,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
return GetDefaultRuntimeLibType();
}
+ToolChain::RuntimeLibType ToolChain
+::GetUnwindLibType(
+ const ArgList &Args) const {
+ const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
+ // If nothing has been specified, follow the runtime lib type.
+ if (!A)
+ return GetRuntimeLibType(Args);
+
+ StringRef LibName = A->getValue();
+ if (LibName == "compiler-rt") {
+ if (GetRuntimeLibType(Args) == RLT_Libgcc)
+ getDriver().Diag(diag::err_drv_incompatible_unwindlib);
+ return ToolChain::RLT_CompilerRT;
+ }
+ else if (LibName == "libgcc")
+ return ToolChain::RLT_Libgcc;
+ else if (LibName == "platform") {
+ return GetRuntimeLibType(Args);
+ }
+
+ 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 a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 1161e8158d5..909dc101059 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1131,41 +1131,70 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) {
return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
}
-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
- ArgStringList &CmdArgs, const ArgList &Args) {
- bool isAndroid = Triple.isAndroid();
- bool isCygMing = Triple.isOSCygMing();
- bool IsIAMCU = Triple.isOSIAMCU();
- bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
- Args.hasArg(options::OPT_static);
+enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
+
+static LibGccType getLibGccType(const ArgList &Args) {
+ bool Static = Args.hasArg(options::OPT_static_libgcc) ||
+ Args.hasArg(options::OPT_static);
+
+ bool Shared = Args.hasArg(options::OPT_shared_libgcc);
+ if (Shared)
+ return LibGccType::SharedLibGcc;
+ if (Static)
+ return LibGccType::StaticLibGcc;
+ return LibGccType::UnspecifiedLibGcc;
+}
- bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
- bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
+static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
+ ArgStringList &CmdArgs, const ArgList &Args) {
+ // Targets that don't use unwind libraries.
+ if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
+ TC.getTriple().isOSBinFormatWasm())
+ return;
- // Gcc adds libgcc arguments in various ways:
- //
- // gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
- // g++ <none>: -lgcc_s -lgcc
- // gcc shared: -lgcc_s -lgcc
- // g++ shared: -lgcc_s -lgcc
- // gcc static: -lgcc -lgcc_eh
- // g++ static: -lgcc -lgcc_eh
- //
- // Also, certain targets need additional adjustments.
+ ToolChain::RuntimeLibType UNW = TC.GetUnwindLibType(Args);
+ switch (UNW) {
+ case ToolChain::RLT_Libgcc: {
+ LibGccType LGT = getLibGccType(Args);
+ if (LGT == LibGccType::UnspecifiedLibGcc || LGT == LibGccType::SharedLibGcc)
+ CmdArgs.push_back("-lgcc_s");
+ else if (LGT == LibGccType::StaticLibGcc)
+ CmdArgs.push_back("-lgcc_eh");
+ break;
+ }
+ case ToolChain::RLT_CompilerRT:
+ CmdArgs.push_back("-lunwind");
+ break;
+ }
+}
+
+// Gcc adds libgcc arguments in various ways:
+//
+// gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
+// g++ <none>: -lgcc_s -lgcc
+// gcc shared: -lgcc_s -lgcc
+// g++ shared: -lgcc_s -lgcc
+// gcc static: -lgcc -lgcc_eh
+// g++ static: -lgcc -lgcc_eh
+//
+// Also, certain targets need additional adjustments.
+
+static void AddLibgcc(const ToolChain &TC, const Driver &D,
+ ArgStringList &CmdArgs, const ArgList &Args) {
+ bool isAndroid = TC.getTriple().isAndroid();
+ LibGccType LGT = getLibGccType(Args);
- bool LibGccFirst = (D.CCCIsCC() && UnspecifiedLibgcc) || StaticLibgcc;
+ bool LibGccFirst = (D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc) ||
+ LGT == LibGccType::StaticLibGcc;
if (LibGccFirst)
CmdArgs.push_back("-lgcc");
- bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
+ bool AsNeeded = D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc &&
+ !isAndroid && !TC.getTriple().isOSCygMing();
if (AsNeeded)
CmdArgs.push_back("--as-needed");
- if ((UnspecifiedLibgcc || SharedLibgcc) && !isAndroid)
- CmdArgs.push_back("-lgcc_s");
-
- else if (StaticLibgcc && !isAndroid && !IsIAMCU)
- CmdArgs.push_back("-lgcc_eh");
+ AddUnwindLibrary(TC, D, CmdArgs, Args);
if (AsNeeded)
CmdArgs.push_back("--no-as-needed");
@@ -1178,7 +1207,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
//
// NOTE: This fixes a link error on Android MIPS as well. The non-static
// libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
- if (isAndroid && !StaticLibgcc)
+ if (isAndroid && LGT != LibGccType::StaticLibGcc)
CmdArgs.push_back("-ldl");
}
@@ -1190,6 +1219,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
switch (RLT) {
case ToolChain::RLT_CompilerRT:
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
+ AddUnwindLibrary(TC, D, CmdArgs, Args);
break;
case ToolChain::RLT_Libgcc:
// Make sure libgcc is not used under MSVC environment by default
@@ -1201,7 +1231,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
<< Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
}
} else
- AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
+ AddLibgcc(TC, D, CmdArgs, Args);
break;
}
}
diff --git a/clang/test/Driver/compiler-rt-unwind.c b/clang/test/Driver/compiler-rt-unwind.c
new file mode 100644
index 00000000000..9d881ea0e0a
--- /dev/null
+++ b/clang/test/Driver/compiler-rt-unwind.c
@@ -0,0 +1,50 @@
+// 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=gcc \
+// 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=gcc --unwindlib=compiler-rt \
+// 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"
+// RTLIB-COMPILER-RT: "{{.*}}-lunwind"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=gcc \
+// 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=gcc \
+// 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=compiler-rt \
+// 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"
OpenPOWER on IntegriCloud