Fix the addition of Clang's profile runtime library to the link step
when specifying --coverage (or related) flags.

The system for doing this was based on the old LLVM-hosted profile_rt
library, and hadn't been updated for Linux to use the new compiler-rt
library. Also, it couldn't possibly work on multiarch or biarch systems
in many cases. The whole thing now works much the same as the sanitizer
libraries that are built and used out of the compiler-rt repo.

Note that other target OSes haven't been updated because I don't know if
they're doing anything special with the installation path of profile_rt.
I suspect however that *all* of these are wrong and would encourage
maintainers of each target to take a hard look at how compiler-rt
runtime libraries are linked on their platforms.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184666 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 8707174..050db6c 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1674,6 +1674,24 @@
   }
 }
 
+static void addProfileRTLinux(
+    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
+  if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
+        Args.hasArg(options::OPT_fprofile_generate) ||
+        Args.hasArg(options::OPT_fcreate_profile) ||
+        Args.hasArg(options::OPT_coverage)))
+    return;
+
+  // The profile runtime is located in the Linux library directory and has name
+  // "libclang_rt.profile-<ArchName>.a".
+  SmallString<128> LibProfile(TC.getDriver().ResourceDir);
+  llvm::sys::path::append(
+      LibProfile, "lib", "linux",
+      Twine("libclang_rt.profile-") + TC.getArchName() + ".a");
+
+  CmdArgs.push_back(Args.MakeArgString(LibProfile));
+}
+
 static void addSanitizerRTLinkFlagsLinux(
     const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
     const StringRef Sanitizer, bool BeforeLibStdCXX,
@@ -6244,7 +6262,7 @@
     }
   }
 
-  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+  addProfileRTLinux(getToolChain(), Args, CmdArgs);
 
   C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
 }
diff --git a/test/Driver/coverage-ld.c b/test/Driver/coverage-ld.c
new file mode 100644
index 0000000..2ec0486
--- /dev/null
+++ b/test/Driver/coverage-ld.c
@@ -0,0 +1,19 @@
+// Test coverage ld flags.
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux --coverage \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LINUX-I386 %s
+//
+// CHECK-LINUX-I386: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-LINUX-I386: "{{.*}}/Inputs/resource_dir/lib/linux/libclang_rt.profile-i386.a"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux --coverage \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LINUX-X86-64 %s
+//
+// CHECK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-LINUX-X86-64: "{{.*}}/Inputs/resource_dir/lib/linux/libclang_rt.profile-x86_64.a"