X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FLLVMCConfigurationEmitter.cpp;h=b7ac85c5ed54489488d9516bcfb143fc083dcb73;hb=17ef94fe1b714c437dfeca3bfdd72b37d8771c49;hp=9dbbfe48486c7584190ec681c6c6cb2008be3982;hpb=8c67e4cb3ab9b658301040c54a62350c5f12e0b7;p=oota-llvm.git diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 9dbbfe48486..b7ac85c5ed5 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -25,6 +25,7 @@ #include #include + using namespace llvm; namespace { @@ -164,18 +165,6 @@ void CheckedIncrement(I& P, I E, S ErrorString) { throw ErrorString; } -// apply is needed because C++'s syntax doesn't let us construct a function -// object and call it in the same statement. -template -void apply(F Fun, T0& Arg0) { - return Fun(Arg0); -} - -template -void apply(F Fun, T0& Arg0, T1& Arg1) { - return Fun(Arg0, Arg1); -} - //===----------------------------------------------------------------------===// /// Back-end specific code @@ -468,7 +457,6 @@ public: // wrong type. const OptionDescription& FindSwitch(const std::string& OptName) const; const OptionDescription& FindParameter(const std::string& OptName) const; - const OptionDescription& FindList(const std::string& OptName) const; const OptionDescription& FindParameterList(const std::string& OptName) const; const OptionDescription& FindListOrParameter(const std::string& OptName) const; @@ -502,14 +490,6 @@ OptionDescriptions::FindSwitch(const std::string& OptName) const { return OptDesc; } -const OptionDescription& -OptionDescriptions::FindList(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isList()) - throw OptName + ": incorrect option type - should be a list!"; - return OptDesc; -} - const OptionDescription& OptionDescriptions::FindParameterList(const std::string& OptName) const { const OptionDescription& OptDesc = this->FindOption(OptName); @@ -818,13 +798,12 @@ void CollectOptionDescriptions (const RecordVector& V, OptionDescriptions& OptDescs) { // For every OptionList: - for (RecordVector::const_iterator B = V.begin(), - E = V.end(); B!=E; ++B) { + for (RecordVector::const_iterator B = V.begin(), E = V.end(); B!=E; ++B) + { // Throws an exception if the value does not exist. ListInit* PropList = (*B)->getValueAsListInit("options"); - // For every option description in this list: - // collect the information and + // For every option description in this list: invoke AddOption. std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs)); } } @@ -842,7 +821,7 @@ struct ToolDescription : public RefCountedBase { StrVector InLanguage; std::string InFileOption; std::string OutFileOption; - std::string OutLanguage; + StrVector OutLanguage; std::string OutputSuffix; unsigned Flags; const Init* OnEmpty; @@ -855,11 +834,7 @@ struct ToolDescription : public RefCountedBase { // Default ctor here is needed because StringMap can only store // DefaultConstructible objects - ToolDescription () - : CmdLine(0), Actions(0), OutFileOption("-o"), - Flags(0), OnEmpty(0) - {} - ToolDescription (const std::string& n) + ToolDescription (const std::string &n = "") : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"), Flags(0), OnEmpty(0) {} @@ -932,31 +907,24 @@ private: toolDesc_.CmdLine = d.getArg(0); } - void onInLanguage (const DagInit& d) { + /// onInOutLanguage - Common implementation of on{In,Out}Language(). + void onInOutLanguage (const DagInit& d, StrVector& OutVec) { CheckNumberOfArguments(d, 1); - Init* arg = d.getArg(0); - // Find out the argument's type. - if (typeid(*arg) == typeid(StringInit)) { - // It's a string. - toolDesc_.InLanguage.push_back(InitPtrToString(arg)); + // Copy strings to the output vector. + for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { + OutVec.push_back(InitPtrToString(d.getArg(i))); } - else { - // It's a list. - const ListInit& lst = InitPtrToList(arg); - StrVector& out = toolDesc_.InLanguage; - // Copy strings to the output vector. - for (ListInit::const_iterator B = lst.begin(), E = lst.end(); - B != E; ++B) { - out.push_back(InitPtrToString(*B)); - } + // Remove duplicates. + std::sort(OutVec.begin(), OutVec.end()); + StrVector::iterator newE = std::unique(OutVec.begin(), OutVec.end()); + OutVec.erase(newE, OutVec.end()); + } - // Remove duplicates. - std::sort(out.begin(), out.end()); - StrVector::iterator newE = std::unique(out.begin(), out.end()); - out.erase(newE, out.end()); - } + + void onInLanguage (const DagInit& d) { + this->onInOutLanguage(d, toolDesc_.InLanguage); } void onJoin (const DagInit& d) { @@ -965,8 +933,7 @@ private: } void onOutLanguage (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.OutLanguage = InitPtrToString(d.getArg(0)); + this->onInOutLanguage(d, toolDesc_.OutLanguage); } void onOutFileOption (const DagInit& d) { @@ -1075,18 +1042,29 @@ void FilterNotInGraph (const DagVector& EdgeVector, } /// FillInToolToLang - Fills in two tables that map tool names to -/// (input, output) languages. Helper function used by TypecheckGraph(). +/// input & output language names. Helper function used by TypecheckGraph(). void FillInToolToLang (const ToolDescriptions& ToolDescs, StringMap >& ToolToInLang, - StringMap& ToolToOutLang) { + StringMap >& ToolToOutLang) { for (ToolDescriptions::const_iterator B = ToolDescs.begin(), E = ToolDescs.end(); B != E; ++B) { const ToolDescription& D = *(*B); for (StrVector::const_iterator B = D.InLanguage.begin(), E = D.InLanguage.end(); B != E; ++B) ToolToInLang[D.Name].insert(*B); - ToolToOutLang[D.Name] = D.OutLanguage; + for (StrVector::const_iterator B = D.OutLanguage.begin(), + E = D.OutLanguage.end(); B != E; ++B) + ToolToOutLang[D.Name].insert(*B); + } +} + +/// Intersect - Is set intersection non-empty? +bool Intersect (const StringSet<>& S1, const StringSet<>& S2) { + for (StringSet<>::const_iterator B = S1.begin(), E = S1.end(); B != E; ++B) { + if (S2.count(B->first()) != 0) + return true; } + return false; } /// TypecheckGraph - Check that names for output and input languages @@ -1094,28 +1072,32 @@ void FillInToolToLang (const ToolDescriptions& ToolDescs, void TypecheckGraph (const DagVector& EdgeVector, const ToolDescriptions& ToolDescs) { StringMap > ToolToInLang; - StringMap ToolToOutLang; + StringMap > ToolToOutLang; FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang); - StringMap::iterator IAE = ToolToOutLang.end(); - StringMap >::iterator IBE = ToolToInLang.end(); for (DagVector::const_iterator B = EdgeVector.begin(), E = EdgeVector.end(); B != E; ++B) { const DagInit* Edge = *B; const std::string& NodeA = InitPtrToString(Edge->getArg(0)); const std::string& NodeB = InitPtrToString(Edge->getArg(1)); - StringMap::iterator IA = ToolToOutLang.find(NodeA); + StringMap >::iterator IA = ToolToOutLang.find(NodeA); StringMap >::iterator IB = ToolToInLang.find(NodeB); + if (NodeB == "root") + throw "Edges back to the root are not allowed!"; + if (NodeA != "root") { - if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0) + if (IA == ToolToOutLang.end()) + throw NodeA + ": no output language defined!"; + if (IB == ToolToInLang.end()) + throw NodeB + ": no input language defined!"; + + if (!Intersect(IA->second, IB->second)) { throw "Edge " + NodeA + "->" + NodeB + ": output->input language mismatch"; + } } - - if (NodeB == "root") - throw "Edges back to the root are not allowed!"; } } @@ -1191,25 +1173,20 @@ class ExtractOptionNames { if (ActionName == "forward" || ActionName == "forward_as" || ActionName == "forward_value" || ActionName == "forward_transformed_value" || - ActionName == "switch_on" || ActionName == "any_switch_on" || - ActionName == "parameter_equals" || - ActionName == "element_in_list" || ActionName == "not_empty" || - ActionName == "empty") { + ActionName == "parameter_equals" || ActionName == "element_in_list") { CheckNumberOfArguments(Stmt, 1); Init* Arg = Stmt.getArg(0); - if (typeid(*Arg) == typeid(StringInit)) { - const std::string& Name = InitPtrToString(Arg); - OptionNames_.insert(Name); - } - else { - // It's a list. - const ListInit& List = InitPtrToList(Arg); - for (ListInit::const_iterator B = List.begin(), E = List.end(); - B != E; ++B) { - const std::string& Name = InitPtrToString(*B); - OptionNames_.insert(Name); - } + if (typeid(*Arg) == typeid(StringInit)) + OptionNames_.insert(InitPtrToString(Arg)); + } + else if (ActionName == "any_switch_on" || ActionName == "switch_on" || + ActionName == "any_not_empty" || ActionName == "any_empty" || + ActionName == "not_empty" || ActionName == "empty") { + for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) { + Init* Arg = Stmt.getArg(i); + if (typeid(*Arg) == typeid(StringInit)) + OptionNames_.insert(InitPtrToString(Arg)); } } else if (ActionName == "and" || ActionName == "or" || ActionName == "not") { @@ -1224,6 +1201,7 @@ public: {} void operator()(const Init* Statement) { + // Statement is either a dag, or a list of dags. if (typeid(*Statement) == typeid(ListInit)) { const ListInit& DagList = *static_cast(Statement); for (ListInit::const_iterator B = DagList.begin(), E = DagList.end(); @@ -1304,24 +1282,20 @@ bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) { return false; } -/// EmitListTest - Helper function used by EmitCaseTest1ArgList(). +/// EmitMultipleArgumentTest - Helper function used by +/// EmitCaseTestMultipleArgs() template -void EmitListTest(const ListInit& L, const char* LogicOp, - F Callback, raw_ostream& O) +void EmitMultipleArgumentTest(const DagInit& D, const char* LogicOp, + F Callback, raw_ostream& O) { - // This is a lot like EmitLogicalOperationTest, but works on ListInits instead - // of Dags... - bool isFirst = true; - for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) { - if (isFirst) - isFirst = false; - else - O << ' ' << LogicOp << ' '; - Callback(InitPtrToString(*B), O); + for (unsigned i = 0, NumArgs = D.getNumArgs(); i < NumArgs; ++i) { + if (i != 0) + O << ' ' << LogicOp << ' '; + Callback(InitPtrToString(D.getArg(i)), O); } } -// Callbacks for use with EmitListTest. +// Callbacks for use with EmitMultipleArgumentTest class EmitSwitchOn { const OptionDescriptions& OptDescs_; @@ -1359,54 +1333,48 @@ public: }; -/// EmitCaseTest1ArgList - Helper function used by EmitCaseTest1Arg(); -bool EmitCaseTest1ArgList(const std::string& TestName, - const DagInit& d, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - const ListInit& L = InitPtrToList(d.getArg(0)); - +/// EmitCaseTestMultipleArgs - Helper function used by EmitCaseTest1Arg() +bool EmitCaseTestMultipleArgs (const std::string& TestName, + const DagInit& d, + const OptionDescriptions& OptDescs, + raw_ostream& O) { if (TestName == "any_switch_on") { - EmitListTest(L, "||", EmitSwitchOn(OptDescs), O); + EmitMultipleArgumentTest(d, "||", EmitSwitchOn(OptDescs), O); return true; } else if (TestName == "switch_on") { - EmitListTest(L, "&&", EmitSwitchOn(OptDescs), O); + EmitMultipleArgumentTest(d, "&&", EmitSwitchOn(OptDescs), O); return true; } else if (TestName == "any_not_empty") { - EmitListTest(L, "||", EmitEmptyTest(true, OptDescs), O); + EmitMultipleArgumentTest(d, "||", EmitEmptyTest(true, OptDescs), O); return true; } else if (TestName == "any_empty") { - EmitListTest(L, "||", EmitEmptyTest(false, OptDescs), O); + EmitMultipleArgumentTest(d, "||", EmitEmptyTest(false, OptDescs), O); return true; } else if (TestName == "not_empty") { - EmitListTest(L, "&&", EmitEmptyTest(true, OptDescs), O); + EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(true, OptDescs), O); return true; } else if (TestName == "empty") { - EmitListTest(L, "&&", EmitEmptyTest(false, OptDescs), O); + EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(false, OptDescs), O); return true; } return false; } -/// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg(); -bool EmitCaseTest1ArgStr(const std::string& TestName, - const DagInit& d, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - const std::string& OptName = InitPtrToString(d.getArg(0)); +/// EmitCaseTest1Arg - Helper function used by EmitCaseTest1OrMoreArgs() +bool EmitCaseTest1Arg (const std::string& TestName, + const DagInit& d, + const OptionDescriptions& OptDescs, + raw_ostream& O) { + const std::string& Arg = InitPtrToString(d.getArg(0)); - if (TestName == "switch_on") { - apply(EmitSwitchOn(OptDescs), OptName, O); - return true; - } - else if (TestName == "input_languages_contain") { - O << "InLangs.count(\"" << OptName << "\") != 0"; + if (TestName == "input_languages_contain") { + O << "InLangs.count(\"" << Arg << "\") != 0"; return true; } else if (TestName == "in_language") { @@ -1414,28 +1382,22 @@ bool EmitCaseTest1ArgStr(const std::string& TestName, // tools can process several files in different languages simultaneously. // TODO: make this work with Edge::Weight (if possible). - O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"'; - return true; - } - else if (TestName == "not_empty" || TestName == "empty") { - bool EmitNegate = (TestName == "not_empty"); - apply(EmitEmptyTest(EmitNegate, OptDescs), OptName, O); + O << "LangMap.GetLanguage(inFile) == \"" << Arg << '\"'; return true; } return false; } -/// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler(); -bool EmitCaseTest1Arg(const std::string& TestName, - const DagInit& d, - const OptionDescriptions& OptDescs, - raw_ostream& O) { +/// EmitCaseTest1OrMoreArgs - Helper function used by +/// EmitCaseConstructHandler() +bool EmitCaseTest1OrMoreArgs(const std::string& TestName, + const DagInit& d, + const OptionDescriptions& OptDescs, + raw_ostream& O) { CheckNumberOfArguments(d, 1); - if (typeid(*d.getArg(0)) == typeid(ListInit)) - return EmitCaseTest1ArgList(TestName, d, OptDescs, O); - else - return EmitCaseTest1ArgStr(TestName, d, OptDescs, O); + return EmitCaseTest1Arg(TestName, d, OptDescs, O) || + EmitCaseTestMultipleArgs(TestName, d, OptDescs, O); } /// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler(). @@ -1479,10 +1441,10 @@ void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp, const OptionDescriptions& OptDescs, raw_ostream& O) { O << '('; - for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) { - const DagInit& InnerTest = InitPtrToDag(d.getArg(j)); + for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { + const DagInit& InnerTest = InitPtrToDag(d.getArg(i)); EmitCaseTest(InnerTest, IndentLevel, OptDescs, O); - if (j != NumArgs - 1) { + if (i != NumArgs - 1) { O << ")\n"; O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " ("; } @@ -1516,7 +1478,7 @@ void EmitCaseTest(const DagInit& d, unsigned IndentLevel, EmitLogicalNot(d, IndentLevel, OptDescs, O); else if (EmitCaseTest0Args(TestName, O)) return; - else if (EmitCaseTest1Arg(TestName, d, OptDescs, O)) + else if (EmitCaseTest1OrMoreArgs(TestName, d, OptDescs, O)) return; else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O)) return; @@ -1563,10 +1525,12 @@ public: {} void operator() (const Init* Statement, unsigned IndentLevel) { + // Is this a nested 'case'? + bool IsCase = dynamic_cast(Statement) && + GetOperatorName(static_cast(*Statement)) == "case"; - // Ignore nested 'case' DAG. - if (!(dynamic_cast(Statement) && - GetOperatorName(static_cast(*Statement)) == "case")) { + // If so, ignore it, it is handled by our caller, WalkCase. + if (!IsCase) { if (typeid(*Statement) == typeid(ListInit)) { const ListInit& DagList = *static_cast(Statement); for (ListInit::const_iterator B = DagList.begin(), E = DagList.end(); @@ -2263,11 +2227,8 @@ void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) { 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.indent(Indent1) << "const char* OutputLanguage() const {\n"; - O.indent(Indent2) << "return \"" << D.OutLanguage << "\";\n"; + O.indent(Indent1) << "const char** OutputLanguages() const {\n"; + O.indent(Indent2) << "return OutputLanguages_;\n"; O.indent(Indent1) << "}\n\n"; } @@ -2312,17 +2273,28 @@ void EmitWorksOnEmptyMethod (const ToolDescription& D, O.indent(Indent1) << "}\n\n"; } +/// EmitStrArray - Emit definition of a 'const char**' static member +/// variable. Helper used by EmitStaticMemberDefinitions(); +void EmitStrArray(const std::string& Name, const std::string& VarName, + const StrVector& StrVec, raw_ostream& O) { + O << "const char* " << Name << "::" << VarName << "[] = {"; + for (StrVector::const_iterator B = StrVec.begin(), E = StrVec.end(); + B != E; ++B) + O << '\"' << *B << "\", "; + O << "0};\n"; +} + /// EmitStaticMemberDefinitions - Emit static member definitions for a /// given Tool class. void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) { if (D.InLanguage.empty()) throw "Tool " + D.Name + " has no 'in_language' property!"; + if (D.OutLanguage.empty()) + throw "Tool " + D.Name + " has no 'out_language' property!"; - O << "const char* " << D.Name << "::InputLanguages_[] = {"; - for (StrVector::const_iterator B = D.InLanguage.begin(), - E = D.InLanguage.end(); B != E; ++B) - O << '\"' << *B << "\", "; - O << "0};\n\n"; + EmitStrArray(D.Name, "InputLanguages_", D.InLanguage, O); + EmitStrArray(D.Name, "OutputLanguages_", D.OutLanguage, O); + O << '\n'; } /// EmitToolClassDefinition - Emit a Tool class definition. @@ -2340,7 +2312,8 @@ void EmitToolClassDefinition (const ToolDescription& D, O << "Tool"; O << " {\nprivate:\n"; - O.indent(Indent1) << "static const char* InputLanguages_[];\n\n"; + O.indent(Indent1) << "static const char* InputLanguages_[];\n"; + O.indent(Indent1) << "static const char* OutputLanguages_[];\n\n"; O << "public:\n"; EmitNameMethod(D, O); @@ -2461,21 +2434,13 @@ class EmitPreprocessOptionsCallback : const OptionDescriptions& OptDescs_; - void onListOrDag(const DagInit& d, HandlerImpl h, - unsigned IndentLevel, raw_ostream& O) const + void onEachArgument(const DagInit& d, HandlerImpl h, + unsigned IndentLevel, raw_ostream& O) const { CheckNumberOfArguments(d, 1); - const Init* I = d.getArg(0); - // If I is a list, apply h to each element. - if (typeid(*I) == typeid(ListInit)) { - const ListInit& L = *static_cast(I); - for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) - ((this)->*(h))(*B, IndentLevel, O); - } - // Otherwise, apply h to I. - else { - ((this)->*(h))(I, IndentLevel, O); + for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { + ((this)->*(h))(d.getArg(i), IndentLevel, O); } } @@ -2502,16 +2467,17 @@ class EmitPreprocessOptionsCallback : void onUnsetOption(const DagInit& d, unsigned IndentLevel, raw_ostream& O) const { - this->onListOrDag(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl, - IndentLevel, O); + this->onEachArgument(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl, + IndentLevel, O); } - void onSetOptionImpl(const DagInit& d, + void onSetOptionImpl(const DagInit& D, unsigned IndentLevel, raw_ostream& O) const { - CheckNumberOfArguments(d, 2); - const std::string& OptName = InitPtrToString(d.getArg(0)); - const Init* Value = d.getArg(1); + CheckNumberOfArguments(D, 2); + + const std::string& OptName = InitPtrToString(D.getArg(0)); const OptionDescription& OptDesc = OptDescs_.FindOption(OptName); + const Init* Value = D.getArg(1); if (OptDesc.isList()) { const ListInit& List = InitPtrToList(Value); @@ -2541,7 +2507,7 @@ class EmitPreprocessOptionsCallback : << " = \"" << Str << "\";\n"; } else { - throw "Can't apply 'set_option' to alias option -" + OptName + " !"; + throw "Can't apply 'set_option' to alias option '" + OptName + "'!"; } } @@ -2561,15 +2527,22 @@ class EmitPreprocessOptionsCallback : { CheckNumberOfArguments(d, 1); - // Two arguments: (set_option "parameter", VALUE), where VALUE can be a - // boolean, a string or a string list. - if (d.getNumArgs() > 1) - this->onSetOptionImpl(d, IndentLevel, O); - // One argument: (set_option "switch") - // or (set_option ["switch1", "switch2", ...]) - else - this->onListOrDag(d, &EmitPreprocessOptionsCallback::onSetSwitch, - IndentLevel, O); + // 2-argument form: (set_option "A", true), (set_option "B", "C"), + // (set_option "D", ["E", "F"]) + if (d.getNumArgs() == 2) { + const OptionDescription& OptDesc = + OptDescs_.FindOption(InitPtrToString(d.getArg(0))); + const Init* Opt2 = d.getArg(1); + + if (!OptDesc.isSwitch() || typeid(*Opt2) != typeid(StringInit)) { + this->onSetOptionImpl(d, IndentLevel, O); + return; + } + } + + // Multiple argument form: (set_option "A"), (set_option "B", "C", "D") + this->onEachArgument(d, &EmitPreprocessOptionsCallback::onSetSwitch, + IndentLevel, O); } public: @@ -2674,10 +2647,11 @@ void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O) { O << "int PopulateLanguageMap (LanguageMap& langMap) {\n"; - // For each LangMap: + // For each LanguageMap: const RecordVector& LangMaps = Records.getAllDerivedDefinitions("LanguageMap"); + // Call DoEmitPopulateLanguageMap. for (RecordVector::const_iterator B = LangMaps.begin(), E = LangMaps.end(); B!=E; ++B) { ListInit* LangMap = (*B)->getValueAsListInit("map"); @@ -2912,13 +2886,10 @@ public: return; } - // We're invoked on a command line. + // We're invoked on a command line string. this->onCmdLine(InitPtrToString(Arg)); } - void operator()(const DagInit* Test, unsigned, bool) { - this->operator()(Test); - } void operator()(const Init* Statement, unsigned) { this->operator()(Statement); }