From: Mikhail Glushenkov Date: Sat, 23 Oct 2010 07:32:46 +0000 (+0000) Subject: Syntax tweak in llvmc: (something [a,b,c]) -> (something a, b, c). X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=17ef94fe1b714c437dfeca3bfdd72b37d8771c49;p=oota-llvm.git Syntax tweak in llvmc: (something [a,b,c]) -> (something a, b, c). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117196 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst index d160e758ea6..6409608507b 100644 --- a/tools/llvmc/doc/LLVMC-Reference.rst +++ b/tools/llvmc/doc/LLVMC-Reference.rst @@ -456,22 +456,22 @@ use TableGen inheritance instead. * Possible tests are: - ``switch_on`` - Returns true if a given command-line switch is provided by - the user. Can be given a list as argument, in that case ``(switch_on ["foo", - "bar", "baz"])`` is equivalent to ``(and (switch_on "foo"), (switch_on + the user. Can be given multiple arguments, in that case ``(switch_on "foo", + "bar", "baz")`` is equivalent to ``(and (switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``. Example: ``(switch_on "opt")``. - - ``any_switch_on`` - Given a list of switch options, returns true if any of + - ``any_switch_on`` - Given a number of switch options, returns true if any of the switches is turned on. - Example: ``(any_switch_on ["foo", "bar", "baz"])`` is equivalent to ``(or + Example: ``(any_switch_on "foo", "bar", "baz")`` is equivalent to ``(or (switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``. - - ``parameter_equals`` - Returns true if a command-line parameter equals - a given value. + - ``parameter_equals`` - Returns true if a command-line parameter (first + argument) equals a given value (second argument). Example: ``(parameter_equals "W", "all")``. - - ``element_in_list`` - Returns true if a command-line parameter - list contains a given value. + - ``element_in_list`` - Returns true if a command-line parameter list (first + argument) contains a given value (second argument). Example: ``(element_in_list "l", "pthread")``. - ``input_languages_contain`` - Returns true if a given language @@ -479,27 +479,27 @@ use TableGen inheritance instead. Example: ``(input_languages_contain "c++")``. - ``in_language`` - Evaluates to true if the input file language is equal to - the argument. At the moment works only with ``cmd_line`` and ``actions`` (on + the argument. At the moment works only with ``command`` and ``actions`` (on non-join nodes). Example: ``(in_language "c++")``. - ``not_empty`` - Returns true if a given option (which should be either a parameter or a parameter list) is set by the user. Like ``switch_on``, can - be also given a list as argument. - Example: ``(not_empty "o")``. + be also given multiple arguments. + Examples: ``(not_empty "o")``, ``(not_empty "o", "l")``. - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of - the options in the list. - Example: ``(any_not_empty ["foo", "bar", "baz"])`` is equivalent to ``(or + the provided options. + Example: ``(any_not_empty "foo", "bar", "baz")`` is equivalent to ``(or (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``. - ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty - X))``. Provided for convenience. Can be given a list as argument. + X))``. Can be given multiple arguments. - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of - the options in the list. - Example: ``(any_empty ["foo", "bar", "baz"])`` is equivalent to ``(not (and - (not_empty "foo"), (not_empty "bar"), (not_empty "baz")))``. + the provided options. + Example: ``(any_empty "foo", "bar", "baz")`` is equivalent to ``(or + (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``. - ``single_input_file`` - Returns true if there was only one input file provided on the command-line. Used without arguments: @@ -511,16 +511,18 @@ use TableGen inheritance instead. - ``default`` - Always evaluates to true. Should always be the last test in the ``case`` expression. - - ``and`` - A standard binary logical combinator that returns true iff all of + - ``and`` - A standard logical combinator that returns true iff all of its arguments return true. Used like this: ``(and (test1), (test2), ... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not encouraged. - - ``or`` - A binary logical combinator that returns true iff any of its - arguments returns true. Example: ``(or (test1), (test2), ... (testN))``. + - ``or`` - A logical combinator that returns true iff any of its arguments + return true. + Example: ``(or (test1), (test2), ... (testN))``. - ``not`` - Standard unary logical combinator that negates its - argument. Example: ``(not (or (test1), (test2), ... (testN)))``. + argument. + Example: ``(not (or (test1), (test2), ... (testN)))``. @@ -549,10 +551,10 @@ The complete list of all currently implemented tool properties follows. * Possible tool properties: - - ``in_language`` - input language name. Can be either a string or a - list, in case the tool supports multiple input languages. + - ``in_language`` - input language name. Can be given multiple arguments, in + case the tool supports multiple input languages. - - ``out_language`` - output language name. Multiple output languages are not + - ``out_language`` - output language name. Multiple output languages are allowed. - ``output_suffix`` - output file suffix. Can also be changed @@ -687,12 +689,12 @@ occasions. Example (adapted from the built-in Base plugin):: def Preprocess : OptionPreprocessor< - (case (not (any_switch_on ["O0", "O1", "O2", "O3"])), + (case (not (any_switch_on "O0", "O1", "O2", "O3")), (set_option "O2"), - (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), - (unset_option ["O0", "O1", "O2"]), - (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), - (unset_option ["O0", "O1"]), + (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")), + (unset_option "O0", "O1", "O2"), + (and (switch_on "O2"), (any_switch_on "O0", "O1")), + (unset_option "O0", "O1"), (and (switch_on "O1"), (switch_on "O0")), (unset_option "O0")) >; @@ -709,10 +711,10 @@ set or unset a given option. To set an option with ``set_option``, use the two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be either a string, a string list, or a boolean constant. -For convenience, ``set_option`` and ``unset_option`` also work on lists. That -is, instead of ``[(unset_option "A"), (unset_option "B")]`` you can use -``(unset_option ["A", "B"])``. Obviously, ``(set_option ["A", "B"])`` is valid -only if both ``A`` and ``B`` are switches. +For convenience, ``set_option`` and ``unset_option`` also work with multiple +arguments. That is, instead of ``[(unset_option "A"), (unset_option "B")]`` you +can use ``(unset_option "A", "B")``. Obviously, ``(set_option "A", "B")`` is +only valid if both ``A`` and ``B`` are switches. More advanced topics diff --git a/tools/llvmc/src/Base.td.in b/tools/llvmc/src/Base.td.in index a53ac9e65cc..cefaf487e89 100644 --- a/tools/llvmc/src/Base.td.in +++ b/tools/llvmc/src/Base.td.in @@ -152,23 +152,22 @@ def LinkerOptList : OptionList<[ // Option preprocessor. def Preprocess : OptionPreprocessor< -(case (not (any_switch_on ["O0", "O1", "O2", "O3"])), +(case (not (any_switch_on "O0", "O1", "O2", "O3")), (set_option "O2"), - (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), - (unset_option ["O0", "O1", "O2"]), - (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), - (unset_option ["O0", "O1"]), - (switch_on ["O1", "O0"]), + (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")), + (unset_option "O0", "O1", "O2"), + (and (switch_on "O2"), (any_switch_on "O0", "O1")), + (unset_option "O0", "O1"), + (switch_on "O1", "O0"), (unset_option "O0")) >; // Tools -class llvm_gcc_based out_lang, +class llvm_gcc_based : Tool< [(in_language in_lang), - (out_language out_lang), + out_lang, (output_suffix out_ext), (command cmd), (actions @@ -184,7 +183,7 @@ class llvm_gcc_based output .ll - (and (switch_on ["emit-llvm", "S"]), (not (switch_on "opt"))), + (and (switch_on "emit-llvm", "S"), (not (switch_on "opt"))), [(forward "S"), (output_suffix "ll")], // Ususally just output .bc (not (switch_on "fsyntax-only")), @@ -222,10 +221,12 @@ class llvm_gcc_based ; class llvm_gcc_comp_based -: llvm_gcc_based; +: llvm_gcc_based; class llvm_gcc_pch_based -: llvm_gcc_based; +: llvm_gcc_based; def llvm_gcc_c : llvm_gcc_comp_based <"@LLVMGCCCOMMAND@ -x c", "c", "i">; @@ -250,7 +251,7 @@ def opt : Tool< (out_language "llvm-bitcode"), (output_suffix "opt.bc"), (actions (case (switch_on "emit-llvm"), (stop_compilation), - (switch_on ["emit-llvm", "S"]), + (switch_on "emit-llvm", "S"), [(append_cmd "-S"), (output_suffix "ll")], (not_empty "Wo,"), (forward_value "Wo,"), (switch_on "O1"), (forward "O1"), @@ -282,7 +283,7 @@ def llvm_gcc_assembler : Tool< ]>; def llc : Tool< -[(in_language ["llvm-bitcode", "llvm-assembler"]), +[(in_language "llvm-bitcode", "llvm-assembler"), (out_language "assembler"), (output_suffix "s"), (command "llc"), @@ -304,7 +305,7 @@ def llc : Tool< // Base class for linkers class llvm_gcc_based_linker : Tool< -[(in_language ["object-code", "static-library", "dynamic-library"]), +[(in_language "object-code", "static-library", "dynamic-library"), (out_language "executable"), (output_suffix "out"), (command cmd), diff --git a/tools/llvmc/src/Clang.td b/tools/llvmc/src/Clang.td index 1d75743f4fe..e2d32e88ff2 100644 --- a/tools/llvmc/src/Clang.td +++ b/tools/llvmc/src/Clang.td @@ -25,12 +25,12 @@ class clang_based : Tool< [(forward "E"), (stop_compilation), (output_suffix ext_E)], (and (switch_on "E"), (empty "o")), (no_out_file), (switch_on "fsyntax-only"), (stop_compilation), - (switch_on ["S", "emit-llvm"]), + (switch_on "S", "emit-llvm"), [(append_cmd "-emit-llvm"), (stop_compilation), (output_suffix "ll")], - (not (switch_on ["S", "emit-llvm"])), + (not (switch_on "S", "emit-llvm")), (append_cmd "-emit-llvm-bc"), - (switch_on ["c", "emit-llvm"]), + (switch_on "c", "emit-llvm"), (stop_compilation), (not_empty "include"), (forward "include"), (not_empty "I"), (forward "I"))), diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 7ad981f4e49..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 @@ -809,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)); } } @@ -922,26 +910,16 @@ private: /// 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. - OutVec.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); - - // Copy strings to the output vector. - for (ListInit::const_iterator B = lst.begin(), E = lst.end(); B != E; ++B) - OutVec.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(OutVec.begin(), OutVec.end()); + StrVector::iterator newE = std::unique(OutVec.begin(), OutVec.end()); + OutVec.erase(newE, OutVec.end()); } @@ -1195,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") { @@ -1228,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(); @@ -1308,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_; @@ -1363,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") { @@ -1418,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(). @@ -1483,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 << " ("; } @@ -1520,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; @@ -1567,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(); @@ -2474,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); } } @@ -2515,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); @@ -2554,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 + "'!"; } } @@ -2574,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: @@ -2687,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"); @@ -2925,7 +2886,7 @@ public: return; } - // We're invoked on a command line. + // We're invoked on a command line string. this->onCmdLine(InitPtrToString(Arg)); }