Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -258,6 +258,12 @@ StringRef Component, bool Shared = false) const; + const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared = false) const; + /// needsProfileRT - returns true if instrumentation profile is on. + static bool needsProfileRT(const llvm::opt::ArgList &Args); + /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables /// by default. virtual bool IsUnwindTablesDefault() const; @@ -378,8 +384,11 @@ /// global flags for unsafe floating point math, add it and return true. /// /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags. - virtual bool - AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, + virtual bool AddFastMathRuntimeIfAvailable( + const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + /// addProfileRTLibs - When -fprofile-instr-profile is specified, add profile + /// runtime library, otherwise return false. + virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; /// \brief Return sanitizers which are available in this toolchain. Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -301,9 +301,28 @@ return Path.str(); } +const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared) const { + return Args.MakeArgString(getCompilerRT(Args, Component, Shared)); +} + +bool ToolChain::needsProfileRT(const ArgList &Args) { + if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, + false) || + Args.hasArg(options::OPT_fprofile_generate) || + Args.hasArg(options::OPT_fprofile_generate_EQ) || + Args.hasArg(options::OPT_fprofile_instr_generate) || + Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || + Args.hasArg(options::OPT_fcreate_profile) || + Args.hasArg(options::OPT_coverage)) + return true; + + return false; +} + Tool *ToolChain::SelectTool(const JobAction &JA) const { - if (getDriver().ShouldUseClangCompiler(JA)) - return getClang(); + if (getDriver().ShouldUseClangCompiler(JA)) return getClang(); Action::ActionClass AC = JA.getKind(); if (AC == Action::AssembleJobClass && useIntegratedAs()) return getClangAs(); @@ -491,9 +510,16 @@ void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {} +void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + if (!needsProfileRT(Args)) return; + + CmdArgs.push_back(getCompilerRTArgString(Args, "profile")); + return; +} + ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( - const ArgList &Args) const -{ + const ArgList &Args) const { if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) { StringRef Value = A->getValue(); if (Value == "compiler-rt") Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -282,8 +282,8 @@ /// Add any profiling runtime libraries that are needed. This is essentially a /// MachO specific version of addProfileRT in Tools.cpp. - virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const { + void addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override { // There aren't any profiling libs for embedded targets currently. } Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -300,15 +300,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args, ArgStringList &CmdArgs) const { - if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, - false) || - Args.hasArg(options::OPT_fprofile_generate) || - Args.hasArg(options::OPT_fprofile_generate_EQ) || - Args.hasArg(options::OPT_fprofile_instr_generate) || - Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || - Args.hasArg(options::OPT_fcreate_profile) || - Args.hasArg(options::OPT_coverage))) - return; + if (!needsProfileRT(Args)) return; // Select the appropriate runtime library for the target. if (isTargetIOSBased()) @@ -317,6 +309,7 @@ else AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a", /*AlwaysLink*/ true); + return; } void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2444,34 +2444,12 @@ } } -static const char *getCompilerRTArgString(const ToolChain &TC, - const llvm::opt::ArgList &Args, - StringRef Component, - bool Shared = false) { - return Args.MakeArgString(TC.getCompilerRT(Args, Component, Shared)); -} - // This adds the static libclang_rt.builtins-arch.a directly to the command line // FIXME: Make sure we can also emit shared objects if they're requested // and available, check for possible errors, etc. static void addClangRT(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { - CmdArgs.push_back(getCompilerRTArgString(TC, Args, "builtins")); -} - -static void addProfileRT(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { - if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, - false) || - Args.hasArg(options::OPT_fprofile_generate) || - Args.hasArg(options::OPT_fprofile_generate_EQ) || - Args.hasArg(options::OPT_fprofile_instr_generate) || - Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || - Args.hasArg(options::OPT_fcreate_profile) || - Args.hasArg(options::OPT_coverage))) - return; - - CmdArgs.push_back(getCompilerRTArgString(TC, Args, "profile")); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins")); } namespace { @@ -2550,11 +2528,9 @@ bool IsShared) { // Static runtimes must be forced into executable, so we wrap them in // whole-archive. - if (!IsShared) - CmdArgs.push_back("-whole-archive"); - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Sanitizer, IsShared)); - if (!IsShared) - CmdArgs.push_back("-no-whole-archive"); + if (!IsShared) CmdArgs.push_back("-whole-archive"); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared)); + if (!IsShared) CmdArgs.push_back("-no-whole-archive"); } // Tries to use a file with the list of dynamic symbols that need to be exported @@ -6876,9 +6852,6 @@ if (Args.hasArg(options::OPT_fnested_functions)) CmdArgs.push_back("-allow_stack_execute"); - // TODO: It would be nice to use addProfileRT() here, but darwin's compiler-rt - // paths are different enough from other toolchains that this needs a fair - // amount of refactoring done first. getMachOToolChain().addProfileRTLibs(Args, CmdArgs); if (!Args.hasArg(options::OPT_nostdlib) && @@ -7084,7 +7057,7 @@ } CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -7676,7 +7649,7 @@ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); } - addProfileRT(ToolChain, Args, CmdArgs); + ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -7965,7 +7938,7 @@ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -8489,7 +8462,7 @@ bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); // The profile runtime also needs access to system libraries. - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { @@ -8800,7 +8773,7 @@ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { @@ -8992,7 +8965,7 @@ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -9098,18 +9071,18 @@ "asan_dynamic", "asan_dynamic_runtime_thunk", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Component)); // Make sure the dynamic runtime thunk is not optimized out at link time // to ensure proper SEH handling. CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor")); } else if (DLL) { - CmdArgs.push_back(getCompilerRTArgString(TC, Args, "asan_dll_thunk")); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk")); } else { static const char *const CompilerRTComponents[] = { "asan", "asan_cxx", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Component)); } }