diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /utils/TableGen/LLVMCConfigurationEmitter.cpp | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'utils/TableGen/LLVMCConfigurationEmitter.cpp')
-rw-r--r-- | utils/TableGen/LLVMCConfigurationEmitter.cpp | 502 |
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" |