diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2033,13 +2033,17 @@ Arg *A = Args.getLastArg(options::OPT_g_Group); bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_gstabs); + bool isGeneratingTemporaryObject = + ContainsCompileOrAssembleAction(Actions.back()) || isUsingLTO(); if ((enablesDebugInfo || willEmitRemarks(Args)) && - ContainsCompileOrAssembleAction(Actions.back())) { + isGeneratingTemporaryObject) { // Add a 'dsymutil' step if necessary, when debug info is enabled and we - // have a compile input. We need to run 'dsymutil' ourselves in such cases - // because the debug info will refer to a temporary object file which - // will be removed at the end of the compilation process. + // are linking a temporary object. This occurs when we have a compiler + // or assmbler input or if LTO is enabled. We need to run 'dsymutil' + // ourselves in such cases because the debug info will refer to the + // temporary object file which will be removed at the end of the + // compilation process. if (Act->getType() == types::TY_Image) { ActionList Inputs; Inputs.push_back(Actions.back()); diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -59,7 +59,8 @@ }; class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { - bool NeedsTempPath(const InputInfoList &Inputs) const; + bool NeedsTempPath(const InputInfoList &Inputs, + const llvm::opt::ArgList &Args) const; void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfoList &Inputs, unsigned Version[5]) const; diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -167,7 +167,13 @@ CmdArgs.push_back("-force_cpusubtype_ALL"); } -bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const { +bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs, + const ArgList &Args) const { + Arg *A = Args.getLastArg(options::OPT_g_Group); + if (A && !A->getOption().matches(options::OPT_g0) && + !A->getOption().matches(options::OPT_gstabs)) + return true; + // We only need to generate a temp path for LTO if we aren't compiling object // files. When compiling source files, we run 'dsymutil' after linking. We // don't run 'dsymutil' when compiling object files. @@ -222,7 +228,7 @@ options::OPT_fno_application_extension, false)) CmdArgs.push_back("-application_extension"); - if (D.isUsingLTO() && Version[0] >= 116 && NeedsTempPath(Inputs)) { + if (D.isUsingLTO() && Version[0] >= 116 && NeedsTempPath(Inputs, Args)) { std::string TmpPathName; if (D.getLTOMode() == LTOK_Full) { // If we are using full LTO, then automatically create a temporary file diff --git a/clang/test/Driver/darwin-dsymutil.c b/clang/test/Driver/darwin-dsymutil.c --- a/clang/test/Driver/darwin-dsymutil.c +++ b/clang/test/Driver/darwin-dsymutil.c @@ -47,3 +47,13 @@ // Check that we don't crash when translating arguments for dsymutil. // RUN: %clang -m32 -arch x86_64 -g %s -### + +// Check that clang provides the linker with a temporary object file path and +// runs dsymutil when -flto is specified and no source is provided +// RUN: touch %t.o +// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 %t.o -g -flto -### \ +// RUN: 2> %t +// RUN: FileCheck -check-prefix=CHECK-DSYMUTIL-LTO < %t %s + +// CHECK-DSYMUTIL-LTO: "/usr/bin/ld" "-demangle" "-object_path_lto" +// CHECK-DSYMUTIL-LTO: "/usr/bin/dsymutil" "-o" "a.out.dSYM" "a.out"