From a34f97ab22d55b38423d25663cc26408ac34a721 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Tue, 23 Feb 2010 09:04:44 +0000 Subject: [PATCH] Correct option forwarding: initial implementation. Does not work, but the infrastructure changes are in place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96920 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CompilerDriver/Common.td | 5 +- include/llvm/CompilerDriver/Tool.h | 6 + lib/CompilerDriver/Tool.cpp | 9 + tools/llvmc/Makefile | 2 +- tools/llvmc/plugins/Base/Base.td.in | 40 ++- tools/llvmc/plugins/Clang/Clang.td | 9 - utils/TableGen/LLVMCConfigurationEmitter.cpp | 289 ++++++++----------- 7 files changed, 166 insertions(+), 194 deletions(-) diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index aa15482cfae..479bd6e12f0 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -20,7 +20,9 @@ class Tool l> { def in_language; def out_language; def output_suffix; -def cmd_line; +def command; +def out_file_option; +def in_file_option; def join; def sink; def works_on_empty; @@ -83,6 +85,7 @@ def forward_as; def forward_value; def forward_transformed_value; def stop_compilation; +def no_out_file; def unpack_values; def warning; def error; diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h index 6fc0ae63914..85d1690bcfe 100644 --- a/include/llvm/CompilerDriver/Tool.h +++ b/include/llvm/CompilerDriver/Tool.h @@ -20,12 +20,16 @@ #include "llvm/ADT/StringSet.h" #include "llvm/System/Path.h" +#include #include +#include namespace llvmc { class LanguageMap; + typedef std::vector > ArgsVector; typedef std::vector PathVector; + typedef std::vector StrVector; typedef llvm::StringSet<> InputLanguagesSet; /// Tool - Represents a single tool. @@ -59,6 +63,8 @@ namespace llvmc { const llvm::sys::Path& TempDir, bool StopCompilation, const char* OutputSuffix) const; + + StrVector SortArgs(ArgsVector& Args) const; }; /// JoinTool - A Tool that has an associated input file list. diff --git a/lib/CompilerDriver/Tool.cpp b/lib/CompilerDriver/Tool.cpp index 9f4ab495662..7be24147ce7 100644 --- a/lib/CompilerDriver/Tool.cpp +++ b/lib/CompilerDriver/Tool.cpp @@ -71,3 +71,12 @@ sys::Path Tool::OutFilename(const sys::Path& In, } return Out; } + +StrVector Tool::SortArgs(ArgsVector& Args) const { + StrVector Out; + + for (ArgsVector::iterator B = Args.begin(), E = Args.end(); B != E; ++B) + Out.push_back(B->second); + + return Out; +} diff --git a/tools/llvmc/Makefile b/tools/llvmc/Makefile index 8f995265d2c..d915934c577 100644 --- a/tools/llvmc/Makefile +++ b/tools/llvmc/Makefile @@ -10,7 +10,7 @@ LEVEL = ../.. export LLVMC_BASED_DRIVER_NAME = llvmc -export LLVMC_BUILTIN_PLUGINS = Base Clang +export LLVMC_BUILTIN_PLUGINS = Base REQUIRES_RTTI = 1 DIRS = plugins driver diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in index 5f09664cefa..9dea5c03159 100644 --- a/tools/llvmc/plugins/Base/Base.td.in +++ b/tools/llvmc/plugins/Base/Base.td.in @@ -134,28 +134,26 @@ class llvm_gcc_based : Tool< [(in_language in_lang), (out_language "llvm-bitcode"), - (output_suffix out_lang), - (cmd_line (case - (switch_on "E"), - (case (not_empty "o"), - !strconcat(cmd_prefix, " -E $INFILE -o $OUTFILE"), - (default), - !strconcat(cmd_prefix, " -E $INFILE")), - (switch_on "fsyntax-only"), - !strconcat(cmd_prefix, " -fsyntax-only $INFILE"), - (and (switch_on "S"), (switch_on "emit-llvm")), - !strconcat(cmd_prefix, " -S $INFILE -o $OUTFILE -emit-llvm"), - (default), - !strconcat(cmd_prefix, " -c $INFILE -o $OUTFILE -emit-llvm"))), + (output_suffix "bc"), + (command cmd_prefix), (actions (case - (and (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), + (and (not_empty "o"), + (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), (error "cannot specify -o with -c or -S with multiple files"), - (switch_on "E"), [(stop_compilation), (output_suffix E_ext)], + (switch_on "E"), + [(forward "E"), (stop_compilation), (output_suffix E_ext)], + (and (switch_on "E"), (empty "o")), (no_out_file), (switch_on ["emit-llvm", "S"]), [(output_suffix "ll"), (stop_compilation)], (switch_on ["emit-llvm", "c"]), (stop_compilation), - (switch_on "fsyntax-only"), (stop_compilation), + (switch_on "fsyntax-only"), [(forward "fsyntax-only"), + (no_out_file), (stop_compilation)], + (switch_on ["S", "emit-llvm"]), [(forward "S"), (forward "emit-llvm")], + (not (or (switch_on ["S", "emit-llvm"]), (switch_on "fsyntax-only"))), + [(append_cmd "-c"), (append_cmd "-emit-llvm")], + + // Forwards (not_empty "include"), (forward "include"), (not_empty "iquote"), (forward "iquote"), (not_empty "save-temps"), (append_cmd "-save-temps"), @@ -208,14 +206,14 @@ def opt : Tool< (switch_on "O1"), (forward "O1"), (switch_on "O2"), (forward "O2"), (switch_on "O3"), (forward "O3"))), - (cmd_line "opt -f $INFILE -o $OUTFILE") + (command "opt -f") ]>; def llvm_as : Tool< [(in_language "llvm-assembler"), (out_language "llvm-bitcode"), (output_suffix "bc"), - (cmd_line "llvm-as $INFILE -o $OUTFILE"), + (command "llvm-as"), (actions (case (switch_on "emit-llvm"), (stop_compilation))) ]>; @@ -223,7 +221,7 @@ def llvm_gcc_assembler : Tool< [(in_language "assembler"), (out_language "object-code"), (output_suffix "o"), - (cmd_line "@LLVMGCCCOMMAND@ -c -x assembler $INFILE -o $OUTFILE"), + (command "@LLVMGCCCOMMAND@ -c -x assembler"), (actions (case (switch_on "c"), (stop_compilation), (not_empty "arch"), (forward "arch"), @@ -234,7 +232,7 @@ def llc : Tool< [(in_language ["llvm-bitcode", "llvm-assembler"]), (out_language "assembler"), (output_suffix "s"), - (cmd_line "llc -f $INFILE -o $OUTFILE"), + (command "llc -f"), (actions (case (switch_on "S"), (stop_compilation), (switch_on "O0"), (forward "O0"), @@ -256,7 +254,7 @@ class llvm_gcc_based_linker : Tool< [(in_language "object-code"), (out_language "executable"), (output_suffix "out"), - (cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")), + (command cmd_prefix), (works_on_empty (case (not_empty "filelist"), true, (default), false)), (join), diff --git a/tools/llvmc/plugins/Clang/Clang.td b/tools/llvmc/plugins/Clang/Clang.td index ac8ac15dff6..cea2b5d974e 100644 --- a/tools/llvmc/plugins/Clang/Clang.td +++ b/tools/llvmc/plugins/Clang/Clang.td @@ -1,12 +1,3 @@ -// A replacement for the Clang's ccc script. -// Depends on the Base plugin. -// To compile, use this command: -// -// cd $LLVMC2_DIR -// make DRIVER_NAME=ccc2 BUILTIN_PLUGINS=Clang -// -// Or just use the default llvmc, which now has this plugin enabled. - include "llvm/CompilerDriver/Common.td" def Priority : PluginPriority<1>; diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 836a7750c71..e5bd34a977e 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -43,6 +43,7 @@ const unsigned TabWidth = 4; const unsigned Indent1 = TabWidth*1; const unsigned Indent2 = TabWidth*2; const unsigned Indent3 = TabWidth*3; +const unsigned Indent4 = TabWidth*4; // Default help string. const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED"; @@ -780,6 +781,8 @@ struct ToolDescription : public RefCountedBase { Init* CmdLine; Init* Actions; StrVector InLanguage; + std::string InFileOption; + std::string OutFileOption; std::string OutLanguage; std::string OutputSuffix; unsigned Flags; @@ -793,9 +796,13 @@ struct ToolDescription : public RefCountedBase { // Default ctor here is needed because StringMap can only store // DefaultConstructible objects - ToolDescription() : CmdLine(0), Actions(0), Flags(0), OnEmpty(0) {} + ToolDescription () + : CmdLine(0), Actions(0), OutFileOption("-o"), + Flags(0), OnEmpty(0) + {} ToolDescription (const std::string& n) - : Name(n), CmdLine(0), Actions(0), Flags(0), OnEmpty(0) + : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"), + Flags(0), OnEmpty(0) {} }; @@ -826,10 +833,14 @@ public: if (!staticMembersInitialized_) { AddHandler("actions", &CollectToolProperties::onActions); - AddHandler("cmd_line", &CollectToolProperties::onCmdLine); + AddHandler("command", &CollectToolProperties::onCommand); AddHandler("in_language", &CollectToolProperties::onInLanguage); AddHandler("join", &CollectToolProperties::onJoin); AddHandler("out_language", &CollectToolProperties::onOutLanguage); + + AddHandler("out_file_option", &CollectToolProperties::onOutFileOption); + AddHandler("in_file_option", &CollectToolProperties::onInFileOption); + AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix); AddHandler("sink", &CollectToolProperties::onSink); AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty); @@ -857,7 +868,7 @@ private: toolDesc_.Actions = Case; } - void onCmdLine (const DagInit& d) { + void onCommand (const DagInit& d) { CheckNumberOfArguments(d, 1); toolDesc_.CmdLine = d.getArg(0); } @@ -899,6 +910,16 @@ private: toolDesc_.OutLanguage = InitPtrToString(d.getArg(0)); } + void onOutFileOption (const DagInit& d) { + CheckNumberOfArguments(d, 1); + toolDesc_.OutFileOption = InitPtrToString(d.getArg(0)); + } + + void onInFileOption (const DagInit& d) { + CheckNumberOfArguments(d, 1); + toolDesc_.InFileOption = InitPtrToString(d.getArg(0)); + } + void onOutputSuffix (const DagInit& d) { CheckNumberOfArguments(d, 1); toolDesc_.OutputSuffix = InitPtrToString(d.getArg(0)); @@ -1724,82 +1745,41 @@ void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName, if (StrVec.empty()) throw "Tool '" + ToolName + "' has empty command line!"; - StrVector::const_iterator I = StrVec.begin(), E = StrVec.end(); + StrVector::const_iterator B = StrVec.begin(), E = StrVec.end(); - // If there is a hook invocation on the place of the first command, skip it. + // Emit the command itself. assert(!StrVec[0].empty()); + O.indent(IndentLevel) << "cmd = "; if (StrVec[0][0] == '$') { - while (I != E && (*I)[0] != ')' ) - ++I; - - // Skip the ')' symbol. - ++I; + B = SubstituteSpecialCommands(B, E, IsJoin, O); + ++B; } else { - ++I; + O << '"' << StrVec[0] << '"'; + ++B; } + O << ";\n"; - bool hasINFILE = false; + // Go through the command arguments. + assert(B <= E); + for (; B != E; ++B) { + const std::string& cmd = *B; - for (; I != E; ++I) { - const std::string& cmd = *I; assert(!cmd.empty()); O.indent(IndentLevel); + if (cmd.at(0) == '$') { - if (cmd == "$INFILE") { - hasINFILE = true; - if (IsJoin) { - O << "for (PathVector::const_iterator B = inFiles.begin()" - << ", E = inFiles.end();\n"; - O.indent(IndentLevel) << "B != E; ++B)\n"; - O.indent(IndentLevel + Indent1) << "vec.push_back(B->str());\n"; - } - else { - O << "vec.push_back(inFile.str());\n"; - } - } - else if (cmd == "$OUTFILE") { - O << "vec.push_back(\"\");\n"; - O.indent(IndentLevel) << "out_file_index = vec.size()-1;\n"; - } - else { - O << "vec.push_back("; - I = SubstituteSpecialCommands(I, E, IsJoin, O); - O << ");\n"; - } + O << "vec.push_back(std::make_pair(0, "; + B = SubstituteSpecialCommands(B, E, IsJoin, O); + O << "));\n"; } else { - O << "vec.push_back(\"" << cmd << "\");\n"; + O << "vec.push_back(std::make_pair(0, \"" << cmd << "\"));\n"; } } - if (!hasINFILE) - throw "Tool '" + ToolName + "' doesn't take any input!"; - O.indent(IndentLevel) << "cmd = "; - if (StrVec[0][0] == '$') - SubstituteSpecialCommands(StrVec.begin(), StrVec.end(), IsJoin, O); - else - O << '"' << StrVec[0] << '"'; - O << ";\n"; } -/// EmitCmdLineVecFillCallback - A function object wrapper around -/// EmitCmdLineVecFill(). Used by EmitGenerateActionMethod() as an -/// argument to EmitCaseConstructHandler(). -class EmitCmdLineVecFillCallback { - bool IsJoin; - const std::string& ToolName; - public: - EmitCmdLineVecFillCallback(bool J, const std::string& TN) - : IsJoin(J), ToolName(TN) {} - - void operator()(const Init* Statement, unsigned IndentLevel, - raw_ostream& O) const - { - EmitCmdLineVecFill(Statement, ToolName, IsJoin, IndentLevel, O); - } -}; - /// EmitForwardOptionPropertyHandlingCode - Helper function used to /// implement EmitActionHandler. Emits code for /// handling the (forward) and (forward_as) option properties. @@ -1814,23 +1794,25 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D, switch (D.Type) { case OptionType::Switch: - O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n"; + O.indent(IndentLevel) + << "vec.push_back(std::make_pair(0, \"" << Name << "\"));\n"; break; case OptionType::Parameter: - O.indent(IndentLevel) << "vec.push_back(\"" << Name; + O.indent(IndentLevel) << "vec.push_back(std::make_pair(0, \"" << Name; if (!D.isForwardNotSplit()) { - O << "\");\n"; - O.indent(IndentLevel) << "vec.push_back(" - << D.GenVariableName() << ");\n"; + O << "\"));\n"; + O.indent(IndentLevel) << "vec.push_back(std::make_pair(0, " + << D.GenVariableName() << "));\n"; } else { - O << "=\" + " << D.GenVariableName() << ");\n"; + O << "=\" + " << D.GenVariableName() << "));\n"; } break; case OptionType::Prefix: - O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\" + " - << D.GenVariableName() << ");\n"; + O.indent(IndentLevel) << "vec.push_back(std::make_pair(0, \"" + << Name << "\" + " + << D.GenVariableName() << "));\n"; break; case OptionType::PrefixList: O.indent(IndentLevel) @@ -1838,11 +1820,12 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D, << "::iterator B = " << D.GenVariableName() << ".begin(),\n"; O.indent(IndentLevel) << "E = " << D.GenVariableName() << ".end(); B != E;) {\n"; - O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\" + " << "*B);\n"; + O.indent(IndentLevel1) << "vec.push_back(std::make_pair(0, \"" + << Name << "\" + " << "*B));\n"; O.indent(IndentLevel1) << "++B;\n"; for (int i = 1, j = D.MultiVal; i < j; ++i) { - O.indent(IndentLevel1) << "vec.push_back(*B);\n"; + O.indent(IndentLevel1) << "vec.push_back(std::make_pair(0, *B));\n"; O.indent(IndentLevel1) << "++B;\n"; } @@ -1854,10 +1837,11 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D, << D.GenVariableName() << ".begin(),\n"; O.indent(IndentLevel) << "E = " << D.GenVariableName() << ".end() ; B != E;) {\n"; - O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\");\n"; + O.indent(IndentLevel1) << "vec.push_back(std::make_pair(0, \"" + << Name << "\"));\n"; for (int i = 0, j = D.MultiVal; i < j; ++i) { - O.indent(IndentLevel1) << "vec.push_back(*B);\n"; + O.indent(IndentLevel1) << "vec.push_back(std::make_pair(0, *B));\n"; O.indent(IndentLevel1) << "++B;\n"; } @@ -1939,7 +1923,8 @@ class EmitActionHandlersCallback : { CheckNumberOfArguments(Dag, 1); this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)), - "vec.push_back(", ");\n", IndentLevel, O); + "vec.push_back(std::make_pair(0, ", "));\n", + IndentLevel, O); } void onForward (const DagInit& Dag, @@ -1969,13 +1954,18 @@ class EmitActionHandlersCallback : const OptionDescription& D = OptDescs.FindListOrParameter(Name); if (D.isParameter()) { - O.indent(IndentLevel) << "vec.push_back(" - << D.GenVariableName() << ");\n"; + O.indent(IndentLevel) << "vec.push_back(std::make_pair(0, " + << D.GenVariableName() << "));\n"; } else { - O.indent(IndentLevel) << "std::copy(" << D.GenVariableName() - << ".begin(), " << D.GenVariableName() - << ".end(), std::back_inserter(vec));\n"; + O.indent(IndentLevel) << "for (cl::list::iterator B = " + << D.GenVariableName() << ".begin(), \n"; + O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName() + << ".end(); B != E; ++B)\n"; + O.indent(IndentLevel) << "{\n"; + O.indent(IndentLevel + Indent1) + << "vec.push_back(std::make_pair(0, *B));\n"; + O.indent(IndentLevel) << "}\n"; } } @@ -1987,9 +1977,16 @@ class EmitActionHandlersCallback : const std::string& Hook = InitPtrToString(Dag.getArg(1)); const OptionDescription& D = OptDescs.FindListOrParameter(Name); - O.indent(IndentLevel) << "vec.push_back(" << "hooks::" + O.indent(IndentLevel) << "vec.push_back(std::make_pair(0, " << "hooks::" << Hook << "(" << D.GenVariableName() - << (D.isParameter() ? ".c_str()" : "") << "));\n"; + << (D.isParameter() ? ".c_str()" : "") << ")));\n"; + } + + void onNoOutFile (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + CheckNumberOfArguments(Dag, 0); + O.indent(IndentLevel) << "no_out_file = true;\n"; } void onOutputSuffix (const DagInit& Dag, @@ -2028,12 +2025,15 @@ class EmitActionHandlersCallback : AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue); AddHandler("forward_transformed_value", &EmitActionHandlersCallback::onForwardTransformedValue); + AddHandler("no_out_file", + &EmitActionHandlersCallback::onNoOutFile); AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix); AddHandler("stop_compilation", &EmitActionHandlersCallback::onStopCompilation); AddHandler("unpack_values", &EmitActionHandlersCallback::onUnpackValues); + staticMembersInitialized_ = true; } } @@ -2045,58 +2045,6 @@ class EmitActionHandlersCallback : } }; -bool IsOutFileIndexCheckRequiredStr (const Init* CmdLine) { - StrVector StrVec; - TokenizeCmdLine(InitPtrToString(CmdLine), StrVec); - - for (StrVector::const_iterator I = StrVec.begin(), E = StrVec.end(); - I != E; ++I) { - if (*I == "$OUTFILE") - return false; - } - - return true; -} - -class IsOutFileIndexCheckRequiredStrCallback { - bool* ret_; - -public: - IsOutFileIndexCheckRequiredStrCallback(bool* ret) : ret_(ret) - {} - - void operator()(const Init* CmdLine) { - // Ignore nested 'case' DAG. - if (typeid(*CmdLine) == typeid(DagInit)) - return; - - if (IsOutFileIndexCheckRequiredStr(CmdLine)) - *ret_ = true; - } - - void operator()(const DagInit* Test, unsigned, bool) { - this->operator()(Test); - } - void operator()(const Init* Statement, unsigned) { - this->operator()(Statement); - } -}; - -bool IsOutFileIndexCheckRequiredCase (Init* CmdLine) { - bool ret = false; - WalkCase(CmdLine, Id(), IsOutFileIndexCheckRequiredStrCallback(&ret)); - return ret; -} - -/// IsOutFileIndexCheckRequired - Should we emit an "out_file_index != -1" check -/// in EmitGenerateActionMethod() ? -bool IsOutFileIndexCheckRequired (Init* CmdLine) { - if (typeid(*CmdLine) == typeid(StringInit)) - return IsOutFileIndexCheckRequiredStr(CmdLine); - else - return IsOutFileIndexCheckRequiredCase(CmdLine); -} - void EmitGenerateActionMethodHeader(const ToolDescription& D, bool IsJoin, raw_ostream& O) { @@ -2111,8 +2059,10 @@ void EmitGenerateActionMethodHeader(const ToolDescription& D, O.indent(Indent2) << "const LanguageMap& LangMap) const\n"; O.indent(Indent1) << "{\n"; O.indent(Indent2) << "std::string cmd;\n"; - O.indent(Indent2) << "std::vector vec;\n"; + O.indent(Indent2) << "std::string out_file;\n"; + O.indent(Indent2) << "std::vector > vec;\n"; O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n"; + O.indent(Indent2) << "bool no_out_file = false;\n"; O.indent(Indent2) << "const char* output_suffix = \"" << D.OutputSuffix << "\";\n"; } @@ -2128,46 +2078,61 @@ void EmitGenerateActionMethod (const ToolDescription& D, if (!D.CmdLine) throw "Tool " + D.Name + " has no cmd_line property!"; - bool IndexCheckRequired = IsOutFileIndexCheckRequired(D.CmdLine); - O.indent(Indent2) << "int out_file_index" - << (IndexCheckRequired ? " = -1" : "") - << ";\n\n"; - - // Process the cmd_line property. - if (typeid(*D.CmdLine) == typeid(StringInit)) - EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O); - else - EmitCaseConstructHandler(D.CmdLine, Indent2, - EmitCmdLineVecFillCallback(IsJoin, D.Name), - true, OptDescs, O); + // Process the 'command' property. + O << '\n'; + EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O); + O << '\n'; - // For every understood option, emit handling code. + // Process the 'actions' list of this tool. if (D.Actions) EmitCaseConstructHandler(D.Actions, Indent2, EmitActionHandlersCallback(OptDescs), false, OptDescs, O); - O << '\n'; - O.indent(Indent2) - << "std::string out_file = OutFilename(" - << (IsJoin ? "sys::Path(),\n" : "inFile,\n"); - O.indent(Indent3) << "TempDir, stop_compilation, output_suffix).str();\n\n"; - if (IndexCheckRequired) - O.indent(Indent2) << "if (out_file_index != -1)\n"; - O.indent(IndexCheckRequired ? Indent3 : Indent2) - << "vec[out_file_index] = out_file;\n"; + // Input file (s) + if (!D.InFileOption.empty()) { + O.indent(Indent2) << "vec.push_back(std::make_pair(0, \"" + << D.InFileOption << "\");\n"; + } + + if (IsJoin) { + O.indent(Indent2) + << "for (PathVector::const_iterator B = inFiles.begin(),\n"; + O.indent(Indent3) << "E = inFiles.end(); B != E; ++B)\n"; + O.indent(Indent2) << "{\n"; + O.indent(Indent3) << "vec.push_back(std::make_pair(0, B->str()));\n"; + O.indent(Indent2) << "}\n"; + } + else { + O.indent(Indent2) << "vec.push_back(std::make_pair(0, inFile.str()));\n"; + } + + // Output file + O.indent(Indent2) << "if (!no_out_file) {\n"; + if (!D.OutFileOption.empty()) + O.indent(Indent3) << "vec.push_back(std::make_pair(0, \"" + << D.OutFileOption << "\"));\n"; + + O.indent(Indent3) << "out_file = this->OutFilename(" + << (IsJoin ? "sys::Path(),\n" : "inFile,\n"); + O.indent(Indent4) << "TempDir, stop_compilation, output_suffix).str();\n\n"; + O.indent(Indent3) << "vec.push_back(std::make_pair(0, out_file));\n"; + + O.indent(Indent2) << "}\n\n"; // Handle the Sink property. if (D.isSink()) { O.indent(Indent2) << "if (!" << SinkOptionName << ".empty()) {\n"; - O.indent(Indent3) << "vec.insert(vec.end(), " - << SinkOptionName << ".begin(), " << SinkOptionName - << ".end());\n"; + O.indent(Indent3) << "for (cl::list::iterator B = " + << SinkOptionName << ".begin(), E = " << SinkOptionName + << ".end(); B != E; ++B)\n"; + O.indent(Indent4) << "vec.push_back(std::make_pair(0, *B));\n"; O.indent(Indent2) << "}\n"; } - O.indent(Indent2) << "return Action(cmd, vec, stop_compilation, out_file);\n"; + O.indent(Indent2) << "return Action(cmd, this->SortArgs(vec), " + << "stop_compilation, out_file);\n"; O.indent(Indent1) << "}\n\n"; } @@ -3038,7 +3003,7 @@ void LLVMCConfigurationEmitter::run (raw_ostream &O) { CollectPluginData(Records, Data); CheckPluginData(Data); - EmitSourceFileHeader("LLVMC Configuration Library", O); + this->EmitSourceFileHeader("LLVMC Configuration Library", O); EmitPluginCode(Data, O); } catch (std::exception& Error) { -- 2.34.1