Correct option forwarding: initial implementation.

Does not work, but the infrastructure changes are in place.

llvm-svn: 96920
This commit is contained in:
Mikhail Glushenkov 2010-02-23 09:04:44 +00:00
parent 328ae37049
commit 232ae779ee
7 changed files with 166 additions and 194 deletions

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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),

View File

@ -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>;

View File

@ -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 'command' property.
O << '\n';
EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
O << '\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);
// 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) {