+ EmitCmdLineVecFillCallback(bool J, const std::string& TN)
+ : IsJoin(J), ToolName(TN) {}
+
+ void operator()(const Init* Statement, const char* IndentLevel,
+ std::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.
+void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
+ const char* Indent,
+ const std::string& NewName,
+ std::ostream& O) {
+ const std::string& Name = NewName.empty()
+ ? ("-" + D.Name)
+ : NewName;
+
+ switch (D.Type) {
+ case OptionType::Switch:
+ O << Indent << "vec.push_back(\"" << Name << "\");\n";
+ break;
+ case OptionType::Parameter:
+ O << Indent << "vec.push_back(\"" << Name << "\");\n";
+ O << Indent << "vec.push_back(" << D.GenVariableName() << ");\n";
+ break;
+ case OptionType::Prefix:
+ O << Indent << "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";
+
+ for (int i = 1, j = D.MultiVal; i < j; ++i) {
+ O << Indent << Indent1 << "vec.push_back(*B);\n"
+ << Indent << Indent1 << "++B;\n";
+ }
+
+ O << Indent << "}\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";
+
+ for (int i = 0, j = D.MultiVal; i < j; ++i) {
+ O << Indent << Indent1 << "vec.push_back(*B);\n"
+ << Indent << Indent1 << "++B;\n";
+ }
+
+ O << Indent << "}\n";
+ break;
+ case OptionType::Alias:
+ default:
+ throw std::string("Aliases are not allowed in tool option descriptions!");
+ }
+}
+
+/// EmitActionHandler - Emit code that handles actions. Used by
+/// EmitGenerateActionMethod() as an argument to
+/// EmitCaseConstructHandler().
+class EmitActionHandler {
+ const OptionDescriptions& OptDescs;
+
+ void processActionDag(const Init* Statement, const char* IndentLevel,
+ std::ostream& O) const
+ {
+ const DagInit& Dag = InitPtrToDag(Statement);
+ const std::string& ActionName = Dag.getOperator()->getAsString();
+
+ if (ActionName == "append_cmd") {
+ checkNumberOfArguments(&Dag, 1);
+ const std::string& Cmd = InitPtrToString(Dag.getArg(0));
+ StrVector Out;
+ llvm::SplitString(Cmd, Out);
+
+ for (StrVector::const_iterator B = Out.begin(), E = Out.end();
+ B != E; ++B)
+ O << IndentLevel << "vec.push_back(\"" << *B << "\");\n";
+ }
+ else if (ActionName == "error") {
+ O << IndentLevel << "throw std::runtime_error(\"" <<
+ (Dag.getNumArgs() >= 1 ? InitPtrToString(Dag.getArg(0))
+ : "Unknown error!")
+ << "\");\n";
+ }
+ else if (ActionName == "forward") {
+ checkNumberOfArguments(&Dag, 1);
+ const std::string& Name = InitPtrToString(Dag.getArg(0));
+ EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
+ IndentLevel, "", O);
+ }
+ else if (ActionName == "forward_as") {
+ checkNumberOfArguments(&Dag, 2);
+ const std::string& Name = InitPtrToString(Dag.getArg(0));
+ const std::string& NewName = InitPtrToString(Dag.getArg(1));
+ EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
+ IndentLevel, NewName, O);
+ }
+ else if (ActionName == "output_suffix") {
+ checkNumberOfArguments(&Dag, 1);
+ const std::string& OutSuf = InitPtrToString(Dag.getArg(0));
+ O << IndentLevel << "output_suffix = \"" << OutSuf << "\";\n";
+ }
+ else if (ActionName == "stop_compilation") {
+ O << IndentLevel << "stop_compilation = true;\n";
+ }
+ else if (ActionName == "unpack_values") {
+ checkNumberOfArguments(&Dag, 1);
+ const std::string& Name = InitPtrToString(Dag.getArg(0));
+ const OptionDescription& D = OptDescs.FindOption(Name);
+
+ 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";
+ }
+ else if (OptionType::IsParameter(D.Type)){
+ O << Indent3 << "llvm::SplitString("
+ << D.GenVariableName() << ", vec, \",\");\n";
+ }
+ else {
+ throw "Option '" + D.Name +
+ "': switches can't have the 'unpack_values' property!";
+ }
+ }
+ else {
+ throw "Unknown action name: " + ActionName + "!";
+ }
+ }
+ public:
+ EmitActionHandler(const OptionDescriptions& OD)
+ : OptDescs(OD) {}