aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Glushenkov <foldr@codedgers.com>2010-02-23 09:04:44 +0000
committerMikhail Glushenkov <foldr@codedgers.com>2010-02-23 09:04:44 +0000
commita34f97ab22d55b38423d25663cc26408ac34a721 (patch)
tree0579d1e6e25177b71043e6d569185240e9281d1a
parentc6e0dbf1ddb767e6587bbf340b8dc66a20b7cfea (diff)
downloadexternal_llvm-a34f97ab22d55b38423d25663cc26408ac34a721.zip
external_llvm-a34f97ab22d55b38423d25663cc26408ac34a721.tar.gz
external_llvm-a34f97ab22d55b38423d25663cc26408ac34a721.tar.bz2
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
-rw-r--r--include/llvm/CompilerDriver/Common.td5
-rw-r--r--include/llvm/CompilerDriver/Tool.h6
-rw-r--r--lib/CompilerDriver/Tool.cpp9
-rw-r--r--tools/llvmc/Makefile2
-rw-r--r--tools/llvmc/plugins/Base/Base.td.in40
-rw-r--r--tools/llvmc/plugins/Clang/Clang.td9
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp289
7 files changed, 166 insertions, 194 deletions
diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td
index aa15482..479bd6e 100644
--- a/include/llvm/CompilerDriver/Common.td
+++ b/include/llvm/CompilerDriver/Common.td
@@ -20,7 +20,9 @@ class Tool<list<dag> 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 6fc0ae6..85d1690 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 <string>
#include <vector>
+#include <utility>
namespace llvmc {
class LanguageMap;
+ typedef std::vector<std::pair<unsigned, std::string> > ArgsVector;
typedef std::vector<llvm::sys::Path> PathVector;
+ typedef std::vector<std::string> 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 9f4ab49..7be2414 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 8f99526..d915934 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 5f09664..9dea5c0 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 <string cmd_prefix, string in_lang,
string E_ext, string out_lang> : 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 <string cmd_prefix> : 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 ac8ac15..cea2b5d 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 836a775..e5bd34a 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<ToolDescription> {
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<ToolDescription> {
// 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<std::string>::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<std::string> vec;\n";
+ O.indent(Indent2) << "std::string out_file;\n";
+ O.indent(Indent2) << "std::vector<std::pair<unsigned, std::string> > 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<std::string>::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) {