From 1c18759b45140c85e62ac6367fbee51f363e3c81 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 30 Apr 2013 22:01:21 +0000 Subject: [PATCH] [driver] Allow multiple -arch options with -save-temps by adding the arch name to the temporary files. rdar://13218604 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180813 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Driver.h | 7 ++++- lib/Driver/Driver.cpp | 56 ++++++++++++++++++++++------------- test/Driver/save-temps.c | 19 ++++++++++++ 3 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 test/Driver/save-temps.c diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 1330e95ac9..d9053d1972 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -335,6 +335,7 @@ public: const ToolChain *TC, const char *BoundArch, bool AtTopLevel, + bool MultipleArchs, const char *LinkingOutput, InputInfo &Result) const; @@ -346,11 +347,15 @@ public: /// \param JA - The action of interest. /// \param BaseInput - The original input file that this action was /// triggered by. + /// \param BoundArch - The bound architecture. /// \param AtTopLevel - Whether this is a "top-level" action. + /// \param MultipleArchs - Whether multiple -arch options were supplied. const char *GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, - bool AtTopLevel) const; + const char *BoundArch, + bool AtTopLevel, + bool MultipleArchs) const; /// GetTemporaryPath - Return the pathname of a temporary file to use /// as part of compilation; the file will have the given prefix and suffix. diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index ad1921b838..1dbbc9a342 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -491,9 +491,8 @@ void Driver::generateCompilationDiagnostics(Compilation &C, << "\n\n********************"; } else { // Failure, remove preprocessed files. - if (!C.getArgs().hasArg(options::OPT_save_temps)) { + if (!C.getArgs().hasArg(options::OPT_save_temps)) C.CleanupFileList(C.getTempFiles(), true); - } Diag(clang::diag::note_drv_command_failed_diag_msg) << "Error generating preprocessed source(s)."; @@ -825,17 +824,6 @@ void Driver::BuildUniversalActions(const ToolChain &TC, if (!Archs.size()) Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName())); - // FIXME: We killed off some others but these aren't yet detected in a - // functional manner. If we added information to jobs about which "auxiliary" - // files they wrote then we could detect the conflict these cause downstream. - if (Archs.size() > 1) { - // No recovery needed, the point of this is just to prevent - // overwriting the same files. - if (const Arg *A = Args.getLastArg(options::OPT_save_temps)) - Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs) - << A->getAsString(Args); - } - ActionList SingleActions; BuildActions(TC, Args, BAInputs, SingleActions); @@ -1221,6 +1209,17 @@ void Driver::BuildJobs(Compilation &C) const { } } + // Collect the list of architectures. + llvm::StringSet<> ArchNames; + if (C.getDefaultToolChain().getTriple().isOSDarwin()) { + for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end(); + it != ie; ++it) { + Arg *A = *it; + if (A->getOption().matches(options::OPT_arch)) + ArchNames.insert(A->getValue()); + } + } + for (ActionList::const_iterator it = C.getActions().begin(), ie = C.getActions().end(); it != ie; ++it) { Action *A = *it; @@ -1243,6 +1242,7 @@ void Driver::BuildJobs(Compilation &C) const { BuildJobsForAction(C, A, &C.getDefaultToolChain(), /*BoundArch*/0, /*AtTopLevel*/ true, + /*MultipleArchs*/ ArchNames.size() > 1, /*LinkingOutput*/ LinkingOutput, II); } @@ -1337,6 +1337,7 @@ void Driver::BuildJobsForAction(Compilation &C, const ToolChain *TC, const char *BoundArch, bool AtTopLevel, + bool MultipleArchs, const char *LinkingOutput, InputInfo &Result) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); @@ -1364,7 +1365,7 @@ void Driver::BuildJobsForAction(Compilation &C, TC = &C.getDefaultToolChain(); BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(), - AtTopLevel, LinkingOutput, Result); + AtTopLevel, MultipleArchs, LinkingOutput, Result); return; } @@ -1387,8 +1388,8 @@ void Driver::BuildJobsForAction(Compilation &C, SubJobAtTopLevel = true; InputInfo II; - BuildJobsForAction(C, *it, TC, BoundArch, - SubJobAtTopLevel, LinkingOutput, II); + BuildJobsForAction(C, *it, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, + LinkingOutput, II); InputInfos.push_back(II); } @@ -1404,7 +1405,8 @@ void Driver::BuildJobsForAction(Compilation &C, if (JA->getType() == types::TY_Nothing) Result = InputInfo(A->getType(), BaseInput); else - Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel), + Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, BoundArch, + AtTopLevel, MultipleArchs), A->getType(), BaseInput); if (CCCPrintBindings && !CCGenDiagnostics) { @@ -1425,7 +1427,9 @@ void Driver::BuildJobsForAction(Compilation &C, const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, - bool AtTopLevel) const { + const char *BoundArch, + bool AtTopLevel, + bool MultipleArchs) const { llvm::PrettyStackTraceString CrashInfo("Computing output path"); // Output to a user requested destination? if (AtTopLevel && !isa(JA) && @@ -1460,8 +1464,14 @@ const char *Driver::GetNamedOutputPath(Compilation &C, // Determine what the derived output name should be. const char *NamedOutput; - if (JA.getType() == types::TY_Image) { - NamedOutput = DefaultImageName.c_str(); + if (JA.getType() == types::TY_Image) { + if (MultipleArchs && BoundArch) { + SmallString<128> Output(DefaultImageName.c_str()); + Output += "-"; + Output.append(BoundArch); + NamedOutput = C.getArgs().MakeArgString(Output.c_str()); + } else + NamedOutput = DefaultImageName.c_str(); } else { const char *Suffix = types::getTypeTempSuffix(JA.getType()); assert(Suffix && "All types used for output should have a suffix."); @@ -1469,7 +1479,11 @@ const char *Driver::GetNamedOutputPath(Compilation &C, std::string::size_type End = std::string::npos; if (!types::appendSuffixForType(JA.getType())) End = BaseName.rfind('.'); - std::string Suffixed(BaseName.substr(0, End)); + SmallString<128> Suffixed(BaseName.substr(0, End)); + if (MultipleArchs && BoundArch) { + Suffixed += "-"; + Suffixed.append(BoundArch); + } Suffixed += '.'; Suffixed += Suffix; NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str()); diff --git a/test/Driver/save-temps.c b/test/Driver/save-temps.c new file mode 100644 index 0000000000..a4ca3b2664 --- /dev/null +++ b/test/Driver/save-temps.c @@ -0,0 +1,19 @@ +// RUN: %clang -target x86_64-apple-darwin -save-temps -arch x86_64 %s -### 2>&1 \ +// RUN: | FileCheck %s +// CHECK: "-o" "save-temps.i" +// CHECK: "-o" "save-temps.s" +// CHECK: "-o" "save-temps.o" +// CHECK: "-o" "a.out" + +// RUN: %clang -target x86_64-apple-darwin -save-temps -arch i386 -arch x86_64 %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=MULT-ARCH +// MULT-ARCH: "-o" "save-temps-i386.i" +// MULT-ARCH: "-o" "save-temps-i386.s" +// MULT-ARCH: "-o" "save-temps-i386.o" +// MULT-ARCH: "-o" "a.out-i386" +// MULT-ARCH: "-o" "save-temps-x86_64.i" +// MULT-ARCH: "-o" "save-temps-x86_64.s" +// MULT-ARCH: "-o" "save-temps-x86_64.o" +// MULT-ARCH: "-o" "a.out-x86_64" +// MULT-ARCH: lipo +// MULT-ARCH: "-create" "-output" "a.out" "a.out-i386" "a.out-x86_64" -- 2.40.0