From: Daniel Dunbar Date: Tue, 17 Mar 2009 17:53:55 +0000 (+0000) Subject: Driver: Add logic for computing where to put job outputs (pipe, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=441d060838a5797691777dfcc992ff836b73dcd1;p=clang Driver: Add logic for computing where to put job outputs (pipe, temporary file, user provided name, derived name). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67088 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 679259c925..7bc83ae500 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -28,6 +28,7 @@ namespace driver { class Compilation; class HostInfo; class InputInfo; + class JobAction; class OptTable; class PipedJob; class ToolChain; @@ -203,6 +204,20 @@ public: const char *LinkingOutput, InputInfo &Result) const; + /// GetNamedOutputPath - Return the name to use for the output of + /// the action \arg JA. The result is appended to the compilation's + /// list of temporary or result files, as appropriate. + /// + /// \param C - The compilation. + /// \param JA - The action of interest. + /// \param BaseInput - The original input file that this action was + /// triggered by. + /// \param AtTopLevel - Whether this is a "top-level" action. + const char *GetNamedOutputPath(Compilation &C, + const JobAction &JA, + const char *BaseInput, + bool AtTopLevel) const; + /// GetHostInfo - Construct a new host info object for the given /// host triple. static HostInfo *GetHostInfo(const char *HostTriple); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 980512285d..726823b48c 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -717,18 +717,89 @@ void Driver::BuildJobsForAction(Compilation &C, // Figure out where to put the job (pipes). Job *Dest = &C.getJobs(); if (InputInfos[0].isPipe()) { + assert(TryToUsePipeInput && "Unrequested pipe!"); assert(InputInfos.size() == 1 && "Unexpected pipe with multiple inputs."); Dest = &InputInfos[0].getPipe(); } // Always use the first input as the base input. const char *BaseInput = InputInfos[0].getBaseInput(); - const char *Output = "foo"; + + // Determine the place to write output to (nothing, pipe, or + // filename) and where to put the new job. + PipedJob *OutputJob = 0; + const char *Output = 0; + if (JA->getType() == types::TY_Nothing) { + ; + } else if (OutputToPipe) { + // Append to current piped job or create a new one as appropriate. + if (PipedJob *PJ = dyn_cast(Dest)) { + OutputJob = PJ; + Dest = OutputJob; + } else { + OutputJob = new PipedJob(); + cast(Dest)->addJob(OutputJob); + Dest = OutputJob; + } + } else { + Output = GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel); + } + // FIXME: Make the job. Result = InputInfo(Output, A->getType(), BaseInput); } +const char *Driver::GetNamedOutputPath(Compilation &C, + const JobAction &JA, + const char *BaseInput, + bool AtTopLevel) const { + // Output to a user requested destination? + if (AtTopLevel) { + if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) + return C.addResultFile(FinalOutput->getValue(C.getArgs())); + } + + // Output to a temporary file? + if (!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps)) { + // FIXME: Get temporary name. + std::string Name("/tmp/foo"); + Name += '.'; + Name += types::getTypeTempSuffix(JA.getType()); + return C.addTempFile(C.getArgs().MakeArgString(Name.c_str())); + } + + llvm::sys::Path BasePath(BaseInput); + std::string BaseName(BasePath.getBasename()); + + // Determine what the derived output name should be. + const char *NamedOutput; + if (JA.getType() == types::TY_Image) { + NamedOutput = DefaultImageName.c_str(); + } else { + const char *Suffix = types::getTypeTempSuffix(JA.getType()); + assert(Suffix && "All types used for output should have a suffix."); + + std::string::size_type End = std::string::npos; + if (!types::appendSuffixForType(JA.getType())) + End = BaseName.rfind('.'); + std::string Suffixed(BaseName.substr(0, End)); + Suffixed += '.'; + Suffixed += Suffix; + NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str()); + } + + // As an annoying special case, PCH generation doesn't strip the + // pathname. + if (JA.getType() == types::TY_PCH) { + BasePath.eraseComponent(); + BasePath.appendComponent(NamedOutput); + return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str())); + } else { + return C.addResultFile(NamedOutput); + } +} + llvm::sys::Path Driver::GetFilePath(const char *Name, const ToolChain *TC) const { // FIXME: Implement.