1283015SdimPull in r211785 from upstream clang trunk (by Logan Chien):
2283015Sdim
3283015Sdim  Implement the -fuse-ld= option.
4283015Sdim
5283015Sdim  This commit implements the -fuse-ld= option, so that the user
6283015Sdim  can specify -fuse-ld=bfd to use ld.bfd.
7283015Sdim
8283015Sdim  This commit re-applies r194328 with some test case changes.
9283015Sdim  It seems that r194328 was breaking macosx or mingw build
10283015Sdim  because clang can't find ld.bfd or ld.gold in the given sysroot.
11283015Sdim  We should use -B to specify the executable search path instead.
12283015Sdim
13283015Sdim  Patch originally by David Chisnall.
14283015Sdim
15283015SdimPull in r211786 from upstream clang trunk (by Logan Chien):
16283015Sdim
17283015Sdim  Propset the executables for GetProgramPath().
18283015Sdim
19283015SdimIntroduced here: http://svnweb.freebsd.org/changeset/base/279302
20283015Sdim
21283015SdimIndex: tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
22283015Sdim===================================================================
23283015Sdim--- tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
24283015Sdim+++ tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
25283015Sdim@@ -20,6 +20,8 @@ def err_drv_unknown_stdin_type : Error<
26283015Sdim def err_drv_unknown_language : Error<"language not recognized: '%0'">;
27283015Sdim def err_drv_invalid_arch_name : Error<
28283015Sdim   "invalid arch name '%0'">;
29283015Sdim+def err_drv_invalid_linker_name : Error<
30283015Sdim+  "invalid linker name in argument '%0'">;
31283015Sdim def err_drv_invalid_rtlib_name : Error<
32283015Sdim   "invalid runtime library name in argument '%0'">;
33283015Sdim def err_drv_unsupported_rtlib_for_platform : Error<
34283015SdimIndex: tools/clang/include/clang/Driver/Options.td
35283015Sdim===================================================================
36283015Sdim--- tools/clang/include/clang/Driver/Options.td
37283015Sdim+++ tools/clang/include/clang/Driver/Options.td
38283015Sdim@@ -1453,7 +1453,7 @@ def fprofile_dir : Joined<["-"], "fprofile-dir=">,
39283015Sdim 
40283015Sdim defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>;
41283015Sdim def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>;
42283015Sdim-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<clang_ignored_f_Group>;
43283015Sdim+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
44283015Sdim 
45283015Sdim defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>;
46283015Sdim def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>;
47283015SdimIndex: tools/clang/include/clang/Driver/ToolChain.h
48283015Sdim===================================================================
49283015Sdim--- tools/clang/include/clang/Driver/ToolChain.h
50283015Sdim+++ tools/clang/include/clang/Driver/ToolChain.h
51283015Sdim@@ -150,6 +150,10 @@ class ToolChain {
52283015Sdim   std::string GetFilePath(const char *Name) const;
53283015Sdim   std::string GetProgramPath(const char *Name) const;
54283015Sdim 
55283015Sdim+  /// Returns the linker path, respecting the -fuse-ld= argument to determine
56283015Sdim+  /// the linker suffix or name.
57283015Sdim+  std::string GetLinkerPath() const;
58283015Sdim+
59283015Sdim   /// \brief Dispatch to the specific toolchain for verbose printing.
60283015Sdim   ///
61283015Sdim   /// This is used when handling the verbose option to print detailed,
62283015SdimIndex: tools/clang/lib/Driver/ToolChain.cpp
63283015Sdim===================================================================
64283015Sdim--- tools/clang/lib/Driver/ToolChain.cpp
65283015Sdim+++ tools/clang/lib/Driver/ToolChain.cpp
66283015Sdim@@ -15,6 +15,7 @@
67283015Sdim #include "clang/Driver/Options.h"
68283015Sdim #include "clang/Driver/SanitizerArgs.h"
69283015Sdim #include "clang/Driver/ToolChain.h"
70283015Sdim+#include "llvm/ADT/SmallString.h"
71283015Sdim #include "llvm/ADT/StringSwitch.h"
72283015Sdim #include "llvm/Option/Arg.h"
73283015Sdim #include "llvm/Option/ArgList.h"
74283015Sdim@@ -146,6 +147,30 @@ std::string ToolChain::GetProgramPath(const char *
75283015Sdim   return D.GetProgramPath(Name, *this);
76283015Sdim }
77283015Sdim 
78283015Sdim+std::string ToolChain::GetLinkerPath() const {
79283015Sdim+  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
80283015Sdim+    StringRef Suffix = A->getValue();
81283015Sdim+
82283015Sdim+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
83283015Sdim+    // then use whatever the default system linker is.
84283015Sdim+    if (Suffix.empty() || Suffix == "ld")
85283015Sdim+      return GetProgramPath("ld");
86283015Sdim+
87283015Sdim+    llvm::SmallString<8> LinkerName("ld.");
88283015Sdim+    LinkerName.append(Suffix);
89283015Sdim+
90283015Sdim+    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
91283015Sdim+    if (llvm::sys::fs::exists(LinkerPath))
92283015Sdim+      return LinkerPath;
93283015Sdim+
94283015Sdim+    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
95283015Sdim+    return "";
96283015Sdim+  }
97283015Sdim+
98283015Sdim+  return GetProgramPath("ld");
99283015Sdim+}
100283015Sdim+
101283015Sdim+
102283015Sdim types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
103283015Sdim   return types::lookupTypeForExtension(Ext);
104283015Sdim }
105283015SdimIndex: tools/clang/lib/Driver/ToolChains.cpp
106283015Sdim===================================================================
107283015Sdim--- tools/clang/lib/Driver/ToolChains.cpp
108283015Sdim+++ tools/clang/lib/Driver/ToolChains.cpp
109283015Sdim@@ -2420,7 +2420,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &
110283015Sdim   PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
111283015Sdim                          GCCInstallation.getTriple().str() + "/bin").str());
112283015Sdim 
113283015Sdim-  Linker = GetProgramPath("ld");
114283015Sdim+  Linker = GetLinkerPath();
115283015Sdim 
116283015Sdim   Distro Distro = DetectDistro(Arch);
117283015Sdim 
118283015SdimIndex: tools/clang/lib/Driver/Tools.cpp
119283015Sdim===================================================================
120283015Sdim--- tools/clang/lib/Driver/Tools.cpp
121283015Sdim+++ tools/clang/lib/Driver/Tools.cpp
122283015Sdim@@ -5088,7 +5088,7 @@ void darwin::Link::ConstructJob(Compilation &C, co
123283015Sdim   Args.AddAllArgs(CmdArgs, options::OPT_F);
124283015Sdim 
125283015Sdim   const char *Exec =
126283015Sdim-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
127283015Sdim+    Args.MakeArgString(getToolChain().GetLinkerPath());
128283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
129283015Sdim }
130283015Sdim 
131283015Sdim@@ -5285,7 +5285,7 @@ void solaris::Link::ConstructJob(Compilation &C, c
132283015Sdim   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
133283015Sdim 
134283015Sdim   const char *Exec =
135283015Sdim-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
136283015Sdim+    Args.MakeArgString(getToolChain().GetLinkerPath());
137283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
138283015Sdim }
139283015Sdim 
140283015Sdim@@ -5397,7 +5397,7 @@ void auroraux::Link::ConstructJob(Compilation &C,
141283015Sdim   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
142283015Sdim 
143283015Sdim   const char *Exec =
144283015Sdim-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
145283015Sdim+    Args.MakeArgString(getToolChain().GetLinkerPath());
146283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
147283015Sdim }
148283015Sdim 
149283015Sdim@@ -5587,7 +5587,7 @@ void openbsd::Link::ConstructJob(Compilation &C, c
150283015Sdim   }
151283015Sdim 
152283015Sdim   const char *Exec =
153283015Sdim-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
154283015Sdim+    Args.MakeArgString(getToolChain().GetLinkerPath());
155283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
156283015Sdim }
157283015Sdim 
158283015Sdim@@ -5727,7 +5727,7 @@ void bitrig::Link::ConstructJob(Compilation &C, co
159283015Sdim   }
160283015Sdim 
161283015Sdim   const char *Exec =
162283015Sdim-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
163283015Sdim+    Args.MakeArgString(getToolChain().GetLinkerPath());
164283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
165283015Sdim }
166283015Sdim 
167283015Sdim@@ -6016,7 +6016,7 @@ void freebsd::Link::ConstructJob(Compilation &C, c
168283015Sdim   addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
169283015Sdim 
170283015Sdim   const char *Exec =
171283015Sdim-    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
172283015Sdim+    Args.MakeArgString(ToolChain.GetLinkerPath());
173283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
174283015Sdim }
175283015Sdim 
176283015Sdim@@ -6204,7 +6204,7 @@ void netbsd::Link::ConstructJob(Compilation &C, co
177283015Sdim 
178283015Sdim   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
179283015Sdim 
180283015Sdim-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
181283015Sdim+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
182283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
183283015Sdim }
184283015Sdim 
185283015Sdim@@ -6749,7 +6749,7 @@ void minix::Link::ConstructJob(Compilation &C, con
186283015Sdim          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
187283015Sdim   }
188283015Sdim 
189283015Sdim-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
190283015Sdim+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
191283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
192283015Sdim }
193283015Sdim 
194283015Sdim@@ -6933,7 +6933,7 @@ void dragonfly::Link::ConstructJob(Compilation &C,
195283015Sdim   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
196283015Sdim 
197283015Sdim   const char *Exec =
198283015Sdim-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
199283015Sdim+    Args.MakeArgString(getToolChain().GetLinkerPath());
200283015Sdim   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
201283015Sdim }
202283015Sdim 
203283015SdimIndex: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
204283015Sdim===================================================================
205283015Sdim
206283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
207283015Sdim___________________________________________________________________
208283015SdimAdded: svn:executable
209283015Sdim## -0,0 +1 ##
210283015Sdim+*
211283015Sdim\ No newline at end of property
212283015SdimIndex: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
213283015Sdim===================================================================
214283015Sdim
215283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
216283015Sdim___________________________________________________________________
217283015SdimAdded: svn:executable
218283015Sdim## -0,0 +1 ##
219283015Sdim+*
220283015Sdim\ No newline at end of property
221283015SdimIndex: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
222283015Sdim===================================================================
223283015Sdim
224283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
225283015Sdim___________________________________________________________________
226283015SdimAdded: svn:executable
227283015Sdim## -0,0 +1 ##
228283015Sdim+*
229283015Sdim\ No newline at end of property
230283015SdimIndex: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
231283015Sdim===================================================================
232283015Sdim
233283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
234283015Sdim___________________________________________________________________
235283015SdimAdded: svn:executable
236283015Sdim## -0,0 +1 ##
237283015Sdim+*
238283015Sdim\ No newline at end of property
239283015SdimIndex: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
240283015Sdim===================================================================
241283015Sdim
242283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
243283015Sdim___________________________________________________________________
244283015SdimAdded: svn:executable
245283015Sdim## -0,0 +1 ##
246283015Sdim+*
247283015Sdim\ No newline at end of property
248283015SdimIndex: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
249283015Sdim===================================================================
250283015Sdim
251283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
252283015Sdim___________________________________________________________________
253283015SdimAdded: svn:executable
254283015Sdim## -0,0 +1 ##
255283015Sdim+*
256283015Sdim\ No newline at end of property
257283015SdimIndex: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
258283015Sdim===================================================================
259283015Sdim
260283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
261283015Sdim___________________________________________________________________
262283015SdimAdded: svn:executable
263283015Sdim## -0,0 +1 ##
264283015Sdim+*
265283015Sdim\ No newline at end of property
266283015SdimIndex: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
267283015Sdim===================================================================
268283015Sdim
269283015SdimProperty changes on: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
270283015Sdim___________________________________________________________________
271283015SdimAdded: svn:executable
272283015Sdim## -0,0 +1 ##
273283015Sdim+*
274283015Sdim\ No newline at end of property
275283015SdimIndex: tools/clang/test/Driver/fuse-ld.c
276283015Sdim===================================================================
277283015Sdim--- tools/clang/test/Driver/fuse-ld.c
278283015Sdim+++ tools/clang/test/Driver/fuse-ld.c
279283015Sdim@@ -0,0 +1,63 @@
280283015Sdim+// RUN: %clang %s -### \
281283015Sdim+// RUN:     -target x86_64-unknown-freebsd 2>&1 \
282283015Sdim+// RUN:   | FileCheck %s --check-prefix=CHECK-FREEBSD-LD
283283015Sdim+// CHECK-FREEBSD-LD: ld
284283015Sdim+
285283015Sdim+// RUN: %clang %s -### -fuse-ld=bfd \
286283015Sdim+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
287283015Sdim+// RUN:     -target x86_64-unknown-freebsd \
288283015Sdim+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
289283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-BFD
290283015Sdim+// CHECK-FREEBSD-BFD: Inputs/basic_freebsd_tree/usr/bin/ld.bfd
291283015Sdim+
292283015Sdim+// RUN: %clang %s -### -fuse-ld=gold \
293283015Sdim+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
294283015Sdim+// RUN:     -target x86_64-unknown-freebsd \
295283015Sdim+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
296283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-GOLD
297283015Sdim+// CHECK-FREEBSD-GOLD: Inputs/basic_freebsd_tree/usr/bin/ld.gold
298283015Sdim+
299283015Sdim+// RUN: %clang %s -### -fuse-ld=plib \
300283015Sdim+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
301283015Sdim+// RUN:     -target x86_64-unknown-freebsd \
302283015Sdim+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
303283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-PLIB
304283015Sdim+// CHECK-FREEBSD-PLIB: error: invalid linker name
305283015Sdim+
306283015Sdim+
307283015Sdim+
308283015Sdim+// RUN: %clang %s -### \
309283015Sdim+// RUN:     -target arm-linux-androideabi \
310283015Sdim+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
311283015Sdim+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD
312283015Sdim+// CHECK-ANDROID-ARM-LD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
313283015Sdim+
314283015Sdim+// RUN: %clang %s -### -fuse-ld=bfd \
315283015Sdim+// RUN:     -target arm-linux-androideabi \
316283015Sdim+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
317283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD
318283015Sdim+// CHECK-ANDROID-ARM-BFD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
319283015Sdim+
320283015Sdim+// RUN: %clang %s -### -fuse-ld=gold \
321283015Sdim+// RUN:     -target arm-linux-androideabi \
322283015Sdim+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
323283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD
324283015Sdim+// CHECK-ANDROID-ARM-GOLD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
325283015Sdim+
326283015Sdim+// RUN: %clang %s -### \
327283015Sdim+// RUN:     -target arm-linux-androideabi \
328283015Sdim+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
329283015Sdim+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD-TC
330283015Sdim+// CHECK-ANDROID-ARM-LD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld
331283015Sdim+
332283015Sdim+// RUN: %clang %s -### -fuse-ld=bfd \
333283015Sdim+// RUN:     -target arm-linux-androideabi \
334283015Sdim+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
335283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD-TC
336283015Sdim+// CHECK-ANDROID-ARM-BFD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.bfd
337283015Sdim+
338283015Sdim+// RUN: %clang %s -### -fuse-ld=gold \
339283015Sdim+// RUN:     -target arm-linux-androideabi \
340283015Sdim+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
341283015Sdim+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC
342283015Sdim+// CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.gold
343