summaryrefslogtreecommitdiffstats
path: root/utils/TableGen/LLVMCConfigurationEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/LLVMCConfigurationEmitter.cpp')
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp502
1 files changed, 318 insertions, 184 deletions
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index fc182ce..06afaf7 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -39,10 +39,11 @@ typedef std::vector<std::string> StrVector;
//===----------------------------------------------------------------------===//
/// Constants
-// Indentation strings.
-const char * Indent1 = " ";
-const char * Indent2 = " ";
-const char * Indent3 = " ";
+// Indentation.
+unsigned TabWidth = 4;
+unsigned Indent1 = TabWidth*1;
+unsigned Indent2 = TabWidth*2;
+unsigned Indent3 = TabWidth*3;
// Default help string.
const char * DefaultHelpString = "NO HELP MESSAGE PROVIDED";
@@ -81,16 +82,15 @@ const DagInit& InitPtrToDag(const Init* ptr) {
}
// checkNumberOfArguments - Ensure that the number of args in d is
-// less than or equal to min_arguments, otherwise throw an exception.
+// greater than or equal to min_arguments, otherwise throw an exception.
void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
if (!d || d->getNumArgs() < min_arguments)
- throw d->getOperator()->getAsString()
- + ": too few arguments!";
+ throw d->getOperator()->getAsString() + ": too few arguments!";
}
// isDagEmpty - is this DAG marked with an empty marker?
bool isDagEmpty (const DagInit* d) {
- return d->getOperator()->getAsString() == "empty";
+ return d->getOperator()->getAsString() == "empty_dag_marker";
}
// EscapeVariableName - Escape commas and other symbols not allowed
@@ -139,20 +139,21 @@ void checkedIncrement(I& P, I E, S ErrorString) {
/// OptionType - One of six different option types. See the
/// documentation for detailed description of differences.
namespace OptionType {
+
enum OptionType { Alias, Switch, Parameter, ParameterList,
Prefix, PrefixList};
-bool IsList (OptionType t) {
- return (t == ParameterList || t == PrefixList);
-}
+ bool IsList (OptionType t) {
+ return (t == ParameterList || t == PrefixList);
+ }
-bool IsSwitch (OptionType t) {
- return (t == Switch);
-}
+ bool IsSwitch (OptionType t) {
+ return (t == Switch);
+ }
-bool IsParameter (OptionType t) {
- return (t == Parameter || t == Prefix);
-}
+ bool IsParameter (OptionType t) {
+ return (t == Parameter || t == Prefix);
+ }
}
@@ -187,11 +188,12 @@ struct OptionDescription {
unsigned Flags;
std::string Help;
unsigned MultiVal;
+ Init* InitVal;
OptionDescription(OptionType::OptionType t = OptionType::Switch,
const std::string& n = "",
const std::string& h = DefaultHelpString)
- : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1)
+ : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1), InitVal(0)
{}
/// GenTypeDeclaration - Returns the C++ variable type of this
@@ -229,6 +231,15 @@ struct OptionDescription {
bool isReallyHidden() const;
void setReallyHidden();
+ bool isParameter() const
+ { return OptionType::IsParameter(this->Type); }
+
+ bool isSwitch() const
+ { return OptionType::IsSwitch(this->Type); }
+
+ bool isList() const
+ { return OptionType::IsList(this->Type); }
+
};
void OptionDescription::Merge (const OptionDescription& other)
@@ -438,6 +449,7 @@ public:
AddHandler("extern", &CollectOptionProperties::onExtern);
AddHandler("help", &CollectOptionProperties::onHelp);
AddHandler("hidden", &CollectOptionProperties::onHidden);
+ AddHandler("init", &CollectOptionProperties::onInit);
AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
@@ -481,6 +493,20 @@ private:
optDesc_.setRequired();
}
+ void onInit (const DagInit* d) {
+ checkNumberOfArguments(d, 1);
+ Init* i = d->getArg(0);
+ const std::string& str = i->getAsString();
+
+ bool correct = optDesc_.isParameter() && dynamic_cast<StringInit*>(i);
+ correct |= (optDesc_.isSwitch() && (str == "true" || str == "false"));
+
+ if (!correct)
+ throw std::string("Incorrect usage of the 'init' option property!");
+
+ optDesc_.InitVal = i;
+ }
+
void onOneOrMore (const DagInit* d) {
checkNumberOfArguments(d, 0);
if (optDesc_.isRequired() || optDesc_.isZeroOrOne())
@@ -950,8 +976,22 @@ void CheckForSuperfluousOptions (const RecordVector& Edges,
}
}
-/// EmitCaseTest1Arg - Helper function used by
-/// EmitCaseConstructHandler.
+/// EmitCaseTest0Args - Helper function used by EmitCaseConstructHandler().
+bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) {
+ if (TestName == "single_input_file") {
+ O << "InputFilenames.size() == 1";
+ return true;
+ }
+ else if (TestName == "multiple_input_files") {
+ O << "InputFilenames.size() > 1";
+ return true;
+ }
+
+ return false;
+}
+
+
+/// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler().
bool EmitCaseTest1Arg(const std::string& TestName,
const DagInit& d,
const OptionDescriptions& OptDescs,
@@ -961,7 +1001,7 @@ bool EmitCaseTest1Arg(const std::string& TestName,
if (TestName == "switch_on") {
const OptionDescription& OptDesc = OptDescs.FindOption(OptName);
- if (!OptionType::IsSwitch(OptDesc.Type))
+ if (!OptDesc.isSwitch())
throw OptName + ": incorrect option type - should be a switch!";
O << OptDesc.GenVariableName();
return true;
@@ -984,7 +1024,7 @@ bool EmitCaseTest1Arg(const std::string& TestName,
}
else {
const OptionDescription& OptDesc = OptDescs.FindOption(OptName);
- if (OptionType::IsSwitch(OptDesc.Type))
+ if (OptDesc.isSwitch())
throw OptName
+ ": incorrect option type - should be a list or parameter!";
O << Test << OptDesc.GenVariableName() << ".empty()";
@@ -995,11 +1035,10 @@ bool EmitCaseTest1Arg(const std::string& TestName,
return false;
}
-/// EmitCaseTest2Args - Helper function used by
-/// EmitCaseConstructHandler.
+/// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
bool EmitCaseTest2Args(const std::string& TestName,
const DagInit& d,
- const char* IndentLevel,
+ unsigned IndentLevel,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
checkNumberOfArguments(&d, 2);
@@ -1008,17 +1047,18 @@ bool EmitCaseTest2Args(const std::string& TestName,
const OptionDescription& OptDesc = OptDescs.FindOption(OptName);
if (TestName == "parameter_equals") {
- if (!OptionType::IsParameter(OptDesc.Type))
+ if (!OptDesc.isParameter())
throw OptName + ": incorrect option type - should be a parameter!";
O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
return true;
}
else if (TestName == "element_in_list") {
- if (!OptionType::IsList(OptDesc.Type))
+ if (!OptDesc.isList())
throw OptName + ": incorrect option type - should be a list!";
const std::string& VarName = OptDesc.GenVariableName();
- O << "std::find(" << VarName << ".begin(),\n"
- << IndentLevel << Indent1 << VarName << ".end(), \""
+ O << "std::find(" << VarName << ".begin(),\n";
+ O.indent(IndentLevel + Indent1)
+ << VarName << ".end(), \""
<< OptArg << "\") != " << VarName << ".end()";
return true;
}
@@ -1028,29 +1068,42 @@ bool EmitCaseTest2Args(const std::string& TestName,
// Forward declaration.
// EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
-void EmitCaseTest(const DagInit& d, const char* IndentLevel,
+void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
const OptionDescriptions& OptDescs,
raw_ostream& O);
/// EmitLogicalOperationTest - Helper function used by
/// EmitCaseConstructHandler.
void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
- const char* IndentLevel,
+ unsigned IndentLevel,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
O << '(';
for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
const DagInit& InnerTest = InitPtrToDag(d.getArg(j));
EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
- if (j != NumArgs - 1)
- O << ")\n" << IndentLevel << Indent1 << ' ' << LogicOp << " (";
- else
+ if (j != NumArgs - 1) {
+ O << ")\n";
+ O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
+ }
+ else {
O << ')';
+ }
}
}
+void EmitLogicalNot(const DagInit& d, unsigned IndentLevel,
+ const OptionDescriptions& OptDescs, raw_ostream& O)
+{
+ checkNumberOfArguments(&d, 1);
+ const DagInit& InnerTest = InitPtrToDag(d.getArg(0));
+ O << "! (";
+ EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
+ O << ")";
+}
+
/// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
-void EmitCaseTest(const DagInit& d, const char* IndentLevel,
+void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
const std::string& TestName = d.getOperator()->getAsString();
@@ -1059,6 +1112,10 @@ void EmitCaseTest(const DagInit& d, const char* IndentLevel,
EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
else if (TestName == "or")
EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
+ else if (TestName == "not")
+ EmitLogicalNot(d, IndentLevel, OptDescs, O);
+ else if (EmitCaseTest0Args(TestName, O))
+ return;
else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
return;
else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
@@ -1070,9 +1127,9 @@ void EmitCaseTest(const DagInit& d, const char* IndentLevel,
// Emit code that handles the 'case' construct.
// Takes a function object that should emit code for every case clause.
// Callback's type is
-// void F(Init* Statement, const char* IndentLevel, raw_ostream& O).
+// void F(Init* Statement, unsigned IndentLevel, raw_ostream& O).
template <typename F>
-void EmitCaseConstructHandler(const Init* Dag, const char* IndentLevel,
+void EmitCaseConstructHandler(const Init* Dag, unsigned IndentLevel,
F Callback, bool EmitElseIf,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
@@ -1094,10 +1151,10 @@ void EmitCaseConstructHandler(const Init* Dag, const char* IndentLevel,
if (i+2 != numArgs)
throw std::string("The 'default' clause should be the last in the"
"'case' construct!");
- O << IndentLevel << "else {\n";
+ O.indent(IndentLevel) << "else {\n";
}
else {
- O << IndentLevel << ((i != 0 && EmitElseIf) ? "else if (" : "if (");
+ O.indent(IndentLevel) << ((i != 0 && EmitElseIf) ? "else if (" : "if (");
EmitCaseTest(Test, IndentLevel, OptDescs, O);
O << ") {\n";
}
@@ -1112,13 +1169,13 @@ void EmitCaseConstructHandler(const Init* Dag, const char* IndentLevel,
const DagInit* nd = dynamic_cast<DagInit*>(arg);
if (nd && (nd->getOperator()->getAsString() == "case")) {
// Handle the nested 'case'.
- EmitCaseConstructHandler(nd, (std::string(IndentLevel) + Indent1).c_str(),
+ EmitCaseConstructHandler(nd, (IndentLevel + Indent1),
Callback, EmitElseIf, OptDescs, O);
}
else {
- Callback(arg, (std::string(IndentLevel) + Indent1).c_str(), O);
+ Callback(arg, (IndentLevel + Indent1), O);
}
- O << IndentLevel << "}\n";
+ O.indent(IndentLevel) << "}\n";
}
}
@@ -1272,7 +1329,7 @@ StrVector::const_iterator SubstituteSpecialCommands
/// EmitCmdLineVecFill - Emit code that fills in the command line
/// vector. Helper function used by EmitGenerateActionMethod().
void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
- bool IsJoin, const char* IndentLevel,
+ bool IsJoin, unsigned IndentLevel,
raw_ostream& O) {
StrVector StrVec;
TokenizeCmdline(InitPtrToString(CmdLine), StrVec);
@@ -1295,22 +1352,28 @@ void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
++I;
}
+ bool hasINFILE = false;
+
for (; I != E; ++I) {
const std::string& cmd = *I;
assert(!cmd.empty());
- O << IndentLevel;
+ O.indent(IndentLevel);
if (cmd.at(0) == '$') {
if (cmd == "$INFILE") {
- if (IsJoin)
+ hasINFILE = true;
+ if (IsJoin) {
O << "for (PathVector::const_iterator B = inFiles.begin()"
- << ", E = inFiles.end();\n"
- << IndentLevel << "B != E; ++B)\n"
- << IndentLevel << Indent1 << "vec.push_back(B->toString());\n";
- else
- O << "vec.push_back(inFile.toString());\n";
+ << ", 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(out_file);\n";
+ O << "vec.push_back(\"\");\n";
+ O.indent(IndentLevel) << "out_file_index = vec.size()-1;\n";
}
else {
O << "vec.push_back(";
@@ -1322,8 +1385,10 @@ void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
O << "vec.push_back(\"" << cmd << "\");\n";
}
}
- O << IndentLevel << "cmd = ";
+ if (!hasINFILE)
+ throw "Tool '" + ToolName + "' doesn't take any input!";
+ O.indent(IndentLevel) << "cmd = ";
if (StrVec[0][0] == '$')
SubstituteSpecialCommands(StrVec.begin(), StrVec.end(), O);
else
@@ -1341,11 +1406,10 @@ class EmitCmdLineVecFillCallback {
EmitCmdLineVecFillCallback(bool J, const std::string& TN)
: IsJoin(J), ToolName(TN) {}
- void operator()(const Init* Statement, const char* IndentLevel,
+ void operator()(const Init* Statement, unsigned IndentLevel,
raw_ostream& O) const
{
- EmitCmdLineVecFill(Statement, ToolName, IsJoin,
- IndentLevel, O);
+ EmitCmdLineVecFill(Statement, ToolName, IsJoin, IndentLevel, O);
}
};
@@ -1353,53 +1417,56 @@ class EmitCmdLineVecFillCallback {
/// implement EmitActionHandler. Emits code for
/// handling the (forward) and (forward_as) option properties.
void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
- const char* Indent,
+ unsigned IndentLevel,
const std::string& NewName,
raw_ostream& O) {
const std::string& Name = NewName.empty()
? ("-" + D.Name)
: NewName;
+ unsigned IndentLevel1 = IndentLevel + Indent1;
switch (D.Type) {
case OptionType::Switch:
- O << Indent << "vec.push_back(\"" << Name << "\");\n";
+ O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n";
break;
case OptionType::Parameter:
- O << Indent << "vec.push_back(\"" << Name << "\");\n";
- O << Indent << "vec.push_back(" << D.GenVariableName() << ");\n";
+ O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n";
+ O.indent(IndentLevel) << "vec.push_back(" << D.GenVariableName() << ");\n";
break;
case OptionType::Prefix:
- O << Indent << "vec.push_back(\"" << Name << "\" + "
- << D.GenVariableName() << ");\n";
+ O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\" + "
+ << D.GenVariableName() << ");\n";
break;
case OptionType::PrefixList:
- O << Indent << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
- << Indent << "E = " << D.GenVariableName() << ".end(); B != E;) {\n"
- << Indent << Indent1 << "vec.push_back(\"" << Name << "\" + "
- << "*B);\n"
- << Indent << Indent1 << "++B;\n";
+ O.indent(IndentLevel)
+ << "for (" << D.GenTypeDeclaration()
+ << "::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) << "++B;\n";
for (int i = 1, j = D.MultiVal; i < j; ++i) {
- O << Indent << Indent1 << "vec.push_back(*B);\n"
- << Indent << Indent1 << "++B;\n";
+ O.indent(IndentLevel1) << "vec.push_back(*B);\n";
+ O.indent(IndentLevel1) << "++B;\n";
}
- O << Indent << "}\n";
+ O.indent(IndentLevel) << "}\n";
break;
case OptionType::ParameterList:
- O << Indent << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
- << Indent << "E = " << D.GenVariableName()
- << ".end() ; B != E;) {\n"
- << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n";
+ O.indent(IndentLevel)
+ << "for (" << D.GenTypeDeclaration() << "::iterator B = "
+ << D.GenVariableName() << ".begin(),\n";
+ O.indent(IndentLevel) << "E = " << D.GenVariableName()
+ << ".end() ; B != E;) {\n";
+ O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\");\n";
for (int i = 0, j = D.MultiVal; i < j; ++i) {
- O << Indent << Indent1 << "vec.push_back(*B);\n"
- << Indent << Indent1 << "++B;\n";
+ O.indent(IndentLevel1) << "vec.push_back(*B);\n";
+ O.indent(IndentLevel1) << "++B;\n";
}
- O << Indent << "}\n";
+ O.indent(IndentLevel) << "}\n";
break;
case OptionType::Alias:
default:
@@ -1413,7 +1480,7 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
class EmitActionHandler {
const OptionDescriptions& OptDescs;
- void processActionDag(const Init* Statement, const char* IndentLevel,
+ void processActionDag(const Init* Statement, unsigned IndentLevel,
raw_ostream& O) const
{
const DagInit& Dag = InitPtrToDag(Statement);
@@ -1427,10 +1494,10 @@ class EmitActionHandler {
for (StrVector::const_iterator B = Out.begin(), E = Out.end();
B != E; ++B)
- O << IndentLevel << "vec.push_back(\"" << *B << "\");\n";
+ O.indent(IndentLevel) << "vec.push_back(\"" << *B << "\");\n";
}
else if (ActionName == "error") {
- O << IndentLevel << "throw std::runtime_error(\"" <<
+ O.indent(IndentLevel) << "throw std::runtime_error(\"" <<
(Dag.getNumArgs() >= 1 ? InitPtrToString(Dag.getArg(0))
: "Unknown error!")
<< "\");\n";
@@ -1451,10 +1518,10 @@ class EmitActionHandler {
else if (ActionName == "output_suffix") {
checkNumberOfArguments(&Dag, 1);
const std::string& OutSuf = InitPtrToString(Dag.getArg(0));
- O << IndentLevel << "output_suffix = \"" << OutSuf << "\";\n";
+ O.indent(IndentLevel) << "output_suffix = \"" << OutSuf << "\";\n";
}
else if (ActionName == "stop_compilation") {
- O << IndentLevel << "stop_compilation = true;\n";
+ O.indent(IndentLevel) << "stop_compilation = true;\n";
}
else if (ActionName == "unpack_values") {
checkNumberOfArguments(&Dag, 1);
@@ -1464,16 +1531,18 @@ class EmitActionHandler {
if (D.isMultiVal())
throw std::string("Can't use unpack_values with multi-valued options!");
- if (OptionType::IsList(D.Type)) {
- O << IndentLevel << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
- << IndentLevel << "E = " << D.GenVariableName()
- << ".end(); B != E; ++B)\n"
- << IndentLevel << Indent1 << "llvm::SplitString(*B, vec, \",\");\n";
+ if (D.isList()) {
+ O.indent(IndentLevel)
+ << "for (" << D.GenTypeDeclaration()
+ << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
+ O.indent(IndentLevel)
+ << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n";
+ O.indent(IndentLevel + Indent1)
+ << "llvm::SplitString(*B, vec, \",\");\n";
}
- else if (OptionType::IsParameter(D.Type)){
- O << Indent3 << "llvm::SplitString("
- << D.GenVariableName() << ", vec, \",\");\n";
+ else if (D.isParameter()){
+ O.indent(IndentLevel) << "llvm::SplitString("
+ << D.GenVariableName() << ", vec, \",\");\n";
}
else {
throw "Option '" + D.Name +
@@ -1488,7 +1557,7 @@ class EmitActionHandler {
EmitActionHandler(const OptionDescriptions& OD)
: OptDescs(OD) {}
- void operator()(const Init* Statement, const char* IndentLevel,
+ void operator()(const Init* Statement, unsigned IndentLevel,
raw_ostream& O) const
{
if (typeid(*Statement) == typeid(ListInit)) {
@@ -1503,56 +1572,111 @@ class EmitActionHandler {
}
};
-// EmitGenerateActionMethod - Emit one of two versions of the
+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) {
+ if (IsOutFileIndexCheckRequiredStr(CmdLine))
+ *ret_ = true;
+ }
+};
+
+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);
+}
+
+// EmitGenerateActionMethod - Emit either a normal or a "join" version of the
// Tool::GenerateAction() method.
void EmitGenerateActionMethod (const ToolDescription& D,
const OptionDescriptions& OptDescs,
bool IsJoin, raw_ostream& O) {
if (IsJoin)
- O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n";
+ O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
else
- O << Indent1 << "Action GenerateAction(const sys::Path& inFile,\n";
-
- O << Indent2 << "bool HasChildren,\n"
- << Indent2 << "const llvm::sys::Path& TempDir,\n"
- << Indent2 << "const InputLanguagesSet& InLangs,\n"
- << Indent2 << "const LanguageMap& LangMap) const\n"
- << Indent1 << "{\n"
- << Indent2 << "std::string cmd;\n"
- << Indent2 << "std::vector<std::string> vec;\n"
- << Indent2 << "bool stop_compilation = !HasChildren;\n"
- << Indent2 << "const char* output_suffix = \"" << D.OutputSuffix << "\";\n"
- << Indent2 << "std::string out_file;\n\n";
-
- // For every understood option, emit handling code.
- if (D.Actions)
- EmitCaseConstructHandler(D.Actions, Indent2, EmitActionHandler(OptDescs),
- false, OptDescs, O);
-
- O << '\n' << Indent2
- << "out_file = OutFilename(" << (IsJoin ? "sys::Path(),\n" : "inFile,\n")
- << Indent3 << "TempDir, stop_compilation, output_suffix).toString();\n\n";
+ O.indent(Indent1) << "Action GenerateAction(const sys::Path& inFile,\n";
+
+ O.indent(Indent2) << "bool HasChildren,\n";
+ O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
+ O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
+ 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) << "bool stop_compilation = !HasChildren;\n";
+ O.indent(Indent2) << "const char* output_suffix = \""
+ << D.OutputSuffix << "\";\n";
- // cmd_line is either a string or a 'case' construct.
if (!D.CmdLine)
throw "Tool " + D.Name + " has no cmd_line property!";
- else if (typeid(*D.CmdLine) == typeid(StringInit))
+
+ 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);
+ // For every understood option, emit handling code.
+ if (D.Actions)
+ EmitCaseConstructHandler(D.Actions, Indent2, EmitActionHandler(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";
+
// Handle the Sink property.
if (D.isSink()) {
- O << Indent2 << "if (!" << SinkOptionName << ".empty()) {\n"
- << Indent3 << "vec.insert(vec.end(), "
- << SinkOptionName << ".begin(), " << SinkOptionName << ".end());\n"
- << Indent2 << "}\n";
+ O.indent(Indent2) << "if (!" << SinkOptionName << ".empty()) {\n";
+ O.indent(Indent3) << "vec.insert(vec.end(), "
+ << SinkOptionName << ".begin(), " << SinkOptionName
+ << ".end());\n";
+ O.indent(Indent2) << "}\n";
}
- O << Indent2 << "return Action(cmd, vec, stop_compilation, out_file);\n"
- << Indent1 << "}\n\n";
+ O.indent(Indent2) << "return Action(cmd, vec, stop_compilation, out_file);\n";
+ O.indent(Indent1) << "}\n\n";
}
/// EmitGenerateActionMethods - Emit two GenerateAction() methods for
@@ -1560,18 +1684,20 @@ void EmitGenerateActionMethod (const ToolDescription& D,
void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
- if (!ToolDesc.isJoin())
- O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n"
- << Indent2 << "bool HasChildren,\n"
- << Indent2 << "const llvm::sys::Path& TempDir,\n"
- << Indent2 << "const InputLanguagesSet& InLangs,\n"
- << Indent2 << "const LanguageMap& LangMap) const\n"
- << Indent1 << "{\n"
- << Indent2 << "throw std::runtime_error(\"" << ToolDesc.Name
- << " is not a Join tool!\");\n"
- << Indent1 << "}\n\n";
- else
+ if (!ToolDesc.isJoin()) {
+ O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
+ O.indent(Indent2) << "bool HasChildren,\n";
+ O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
+ O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
+ O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
+ O.indent(Indent1) << "{\n";
+ O.indent(Indent2) << "throw std::runtime_error(\"" << ToolDesc.Name
+ << " is not a Join tool!\");\n";
+ O.indent(Indent1) << "}\n\n";
+ }
+ else {
EmitGenerateActionMethod(ToolDesc, OptDescs, true, O);
+ }
EmitGenerateActionMethod(ToolDesc, OptDescs, false, O);
}
@@ -1579,34 +1705,34 @@ void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
/// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
/// methods for a given Tool class.
void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) {
- O << Indent1 << "const char** InputLanguages() const {\n"
- << Indent2 << "return InputLanguages_;\n"
- << Indent1 << "}\n\n";
+ O.indent(Indent1) << "const char** InputLanguages() const {\n";
+ O.indent(Indent2) << "return InputLanguages_;\n";
+ O.indent(Indent1) << "}\n\n";
if (D.OutLanguage.empty())
throw "Tool " + D.Name + " has no 'out_language' property!";
- O << Indent1 << "const char* OutputLanguage() const {\n"
- << Indent2 << "return \"" << D.OutLanguage << "\";\n"
- << Indent1 << "}\n\n";
+ O.indent(Indent1) << "const char* OutputLanguage() const {\n";
+ O.indent(Indent2) << "return \"" << D.OutLanguage << "\";\n";
+ O.indent(Indent1) << "}\n\n";
}
/// EmitNameMethod - Emit the Name() method for a given Tool class.
void EmitNameMethod (const ToolDescription& D, raw_ostream& O) {
- O << Indent1 << "const char* Name() const {\n"
- << Indent2 << "return \"" << D.Name << "\";\n"
- << Indent1 << "}\n\n";
+ O.indent(Indent1) << "const char* Name() const {\n";
+ O.indent(Indent2) << "return \"" << D.Name << "\";\n";
+ O.indent(Indent1) << "}\n\n";
}
/// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool
/// class.
void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
- O << Indent1 << "bool IsJoin() const {\n";
+ O.indent(Indent1) << "bool IsJoin() const {\n";
if (D.isJoin())
- O << Indent2 << "return true;\n";
+ O.indent(Indent2) << "return true;\n";
else
- O << Indent2 << "return false;\n";
- O << Indent1 << "}\n\n";
+ O.indent(Indent2) << "return false;\n";
+ O.indent(Indent1) << "}\n\n";
}
/// EmitStaticMemberDefinitions - Emit static member definitions for a
@@ -1636,8 +1762,8 @@ void EmitToolClassDefinition (const ToolDescription& D,
else
O << "Tool";
- O << "{\nprivate:\n"
- << Indent1 << "static const char* InputLanguages_[];\n\n";
+ O << "{\nprivate:\n";
+ O.indent(Indent1) << "static const char* InputLanguages_[];\n\n";
O << "public:\n";
EmitNameMethod(D, O);
@@ -1687,15 +1813,15 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
O << ", cl::Prefix";
if (val.isRequired()) {
- if (OptionType::IsList(val.Type) && !val.isMultiVal())
+ if (val.isList() && !val.isMultiVal())
O << ", cl::OneOrMore";
else
O << ", cl::Required";
}
- else if (val.isOneOrMore() && OptionType::IsList(val.Type)) {
+ else if (val.isOneOrMore() && val.isList()) {
O << ", cl::OneOrMore";
}
- else if (val.isZeroOrOne() && OptionType::IsList(val.Type)) {
+ else if (val.isZeroOrOne() && val.isList()) {
O << ", cl::ZeroOrOne";
}
@@ -1707,7 +1833,12 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
}
if (val.MultiVal > 1)
- O << ", cl::multi_val(" << val.MultiVal << ")";
+ O << ", cl::multi_val(" << val.MultiVal << ')';
+
+ if (val.InitVal) {
+ const std::string& str = val.InitVal->getAsString();
+ O << ", cl::init(" << str << ')';
+ }
if (!val.Help.empty())
O << ", cl::desc(\"" << val.Help << "\")";
@@ -1762,9 +1893,9 @@ void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
for (unsigned i = 0; i < Suffixes->size(); ++i)
- O << Indent1 << "langMap[\""
- << InitPtrToString(Suffixes->getElement(i))
- << "\"] = \"" << Lang << "\";\n";
+ O.indent(Indent1) << "langMap[\""
+ << InitPtrToString(Suffixes->getElement(i))
+ << "\"] = \"" << Lang << "\";\n";
}
}
@@ -1773,21 +1904,22 @@ void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
/// IncDecWeight - Helper function passed to EmitCaseConstructHandler()
/// by EmitEdgeClass().
-void IncDecWeight (const Init* i, const char* IndentLevel,
+void IncDecWeight (const Init* i, unsigned IndentLevel,
raw_ostream& O) {
const DagInit& d = InitPtrToDag(i);
const std::string& OpName = d.getOperator()->getAsString();
if (OpName == "inc_weight") {
- O << IndentLevel << "ret += ";
+ O.indent(IndentLevel) << "ret += ";
}
else if (OpName == "dec_weight") {
- O << IndentLevel << "ret -= ";
+ O.indent(IndentLevel) << "ret -= ";
}
else if (OpName == "error") {
- O << IndentLevel << "throw std::runtime_error(\"" <<
- (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0))
- : "Unknown error!")
+ O.indent(IndentLevel)
+ << "throw std::runtime_error(\"" <<
+ (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0))
+ : "Unknown error!")
<< "\");\n";
return;
}
@@ -1810,19 +1942,20 @@ void EmitEdgeClass (unsigned N, const std::string& Target,
// Class constructor.
O << "class Edge" << N << ": public Edge {\n"
- << "public:\n"
- << Indent1 << "Edge" << N << "() : Edge(\"" << Target
- << "\") {}\n\n"
+ << "public:\n";
+ O.indent(Indent1) << "Edge" << N << "() : Edge(\"" << Target
+ << "\") {}\n\n";
// Function Weight().
- << Indent1 << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n"
- << Indent2 << "unsigned ret = 0;\n";
+ O.indent(Indent1)
+ << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n";
+ O.indent(Indent2) << "unsigned ret = 0;\n";
// Handle the 'case' construct.
EmitCaseConstructHandler(Case, Indent2, IncDecWeight, false, OptDescs, O);
- O << Indent2 << "return ret;\n"
- << Indent1 << "};\n\n};\n\n";
+ O.indent(Indent2) << "return ret;\n";
+ O.indent(Indent1) << "};\n\n};\n\n";
}
/// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
@@ -1852,7 +1985,7 @@ void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
E = ToolDescs.end(); B != E; ++B)
- O << Indent1 << "G.insertNode(new " << (*B)->Name << "());\n";
+ O.indent(Indent1) << "G.insertNode(new " << (*B)->Name << "());\n";
O << '\n';
@@ -1866,7 +1999,7 @@ void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
const std::string& NodeB = Edge->getValueAsString("b");
DagInit* Weight = Edge->getValueAsDag("weight");
- O << Indent1 << "G.insertEdge(\"" << NodeA << "\", ";
+ O.indent(Indent1) << "G.insertEdge(\"" << NodeA << "\", ";
if (isDagEmpty(Weight))
O << "new SimpleEdge(\"" << NodeB << "\")";
@@ -1955,7 +2088,7 @@ void EmitHookDeclarations(const ToolDescriptions& ToolDescs, raw_ostream& O) {
O << "namespace hooks {\n";
for (StringMap<unsigned>::const_iterator B = HookNames.begin(),
E = HookNames.end(); B != E; ++B) {
- O << Indent1 << "std::string " << B->first() << "(";
+ O.indent(Indent1) << "std::string " << B->first() << "(";
for (unsigned i = 0, j = B->second; i < j; ++i) {
O << "const char* Arg" << i << (i+1 == j ? "" : ", ");
@@ -1968,22 +2101,23 @@ void EmitHookDeclarations(const ToolDescriptions& ToolDescs, raw_ostream& O) {
/// EmitRegisterPlugin - Emit code to register this plugin.
void EmitRegisterPlugin(int Priority, raw_ostream& O) {
- O << "struct Plugin : public llvmc::BasePlugin {\n\n"
- << Indent1 << "int Priority() const { return " << Priority << "; }\n\n"
- << Indent1 << "void PopulateLanguageMap(LanguageMap& langMap) const\n"
- << Indent1 << "{ PopulateLanguageMapLocal(langMap); }\n\n"
- << Indent1
- << "void PopulateCompilationGraph(CompilationGraph& graph) const\n"
- << Indent1 << "{ PopulateCompilationGraphLocal(graph); }\n"
- << "};\n\n"
-
- << "static llvmc::RegisterPlugin<Plugin> RP;\n\n";
+ O << "struct Plugin : public llvmc::BasePlugin {\n\n";
+ O.indent(Indent1) << "int Priority() const { return "
+ << Priority << "; }\n\n";
+ O.indent(Indent1) << "void PopulateLanguageMap(LanguageMap& langMap) const\n";
+ O.indent(Indent1) << "{ PopulateLanguageMapLocal(langMap); }\n\n";
+ O.indent(Indent1)
+ << "void PopulateCompilationGraph(CompilationGraph& graph) const\n";
+ O.indent(Indent1) << "{ PopulateCompilationGraphLocal(graph); }\n"
+ << "};\n\n"
+ << "static llvmc::RegisterPlugin<Plugin> RP;\n\n";
}
/// EmitIncludes - Emit necessary #include directives and some
/// additional declarations.
void EmitIncludes(raw_ostream& O) {
- O << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
+ O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
+ << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
<< "#include \"llvm/CompilerDriver/ForceLinkageMacros.h\"\n"
<< "#include \"llvm/CompilerDriver/Plugin.h\"\n"
<< "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
OpenPOWER on IntegriCloud