From e0b6570d2472e469ea80edd3216156e1ddb99178 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Wed, 23 Dec 2009 12:49:30 +0000 Subject: [PATCH] Allow (set_option SwitchOption, true). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91997 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/LLVMC/OptionPreprocessor.td | 9 ++++- tools/llvmc/doc/LLVMC-Reference.rst | 15 ++++--- utils/TableGen/LLVMCConfigurationEmitter.cpp | 41 ++++++++++++++------ 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/test/LLVMC/OptionPreprocessor.td b/test/LLVMC/OptionPreprocessor.td index e5d6bbb383a..8d748eee532 100644 --- a/test/LLVMC/OptionPreprocessor.td +++ b/test/LLVMC/OptionPreprocessor.td @@ -1,4 +1,4 @@ -// Test for the OptionPreprocessor and any*. +// Test for the OptionPreprocessor and related functionality. // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: FileCheck -input-file %t %s // RUN: %compile_cxx -fexceptions -x c++ %t @@ -26,13 +26,18 @@ def Preprocess : OptionPreprocessor< (unset_option "foo_p"), (unset_option "foo_l")], // CHECK: W2 // CHECK: foo = true; + // CHECK: bar = true; + // CHECK: baz = false; // CHECK: foo_p = "asdf"; // CHECK: foo_l.clear(); // CHECK: foo_l.push_back("qwert"); // CHECK: foo_l.push_back("yuiop"); // CHECK: foo_l.push_back("asdf"); (and (switch_on ["foo", "bar"]), (any_empty ["foo_p", "bar_p"])), - [(warning "W2"), (set_option "foo"), (set_option "foo_p", "asdf"), + [(warning "W2"), (set_option "foo"), + (set_option "bar", true), + (set_option "baz", false), + (set_option "foo_p", "asdf"), (set_option "foo_l", ["qwert", "yuiop", "asdf"])], // CHECK: W3 // CHECK: foo = true; diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst index 7336195dfed..dfe38980375 100644 --- a/tools/llvmc/doc/LLVMC-Reference.rst +++ b/tools/llvmc/doc/LLVMC-Reference.rst @@ -690,13 +690,16 @@ specified, ``-O2`` is enabled. ``OptionPreprocessor`` is basically a single big ``case`` expression, which is evaluated only once right after the plugin is loaded. The only allowed actions -in ``OptionPreprocessor`` are ``error``, ``warning`` and two special actions: +in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions: ``unset_option`` and ``set_option``. As their names suggest, they can be used to -set or unset a given option. To set a parameter option with ``set_option``, use -the two-argument form: ``(set_option "parameter", "value")``. 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"])``). +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. More advanced topics diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 8b04b6fecc7..16e1c547f48 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" + #include #include #include @@ -89,6 +90,17 @@ const std::string GetOperatorName(const DagInit& D) { return D.getOperator()->getAsString(); } +/// CheckBooleanConstant - Check that the provided value is a boolean constant. +void CheckBooleanConstant(const Init* I) { + const DefInit& val = dynamic_cast(*I); + const std::string& str = val.getAsString(); + + if (str != "true" && str != "false") { + throw "Incorrect boolean value: '" + str + + "': must be either 'true' or 'false'"; + } +} + // checkNumberOfArguments - Ensure that the number of args in d is // greater than or equal to min_arguments, otherwise throw an exception. void checkNumberOfArguments (const DagInit& d, unsigned minArgs) { @@ -2309,8 +2321,8 @@ class EmitPreprocessOptionsCallback : const OptionDescriptions& OptDescs_; - void onListOrDag(HandlerImpl h, - const DagInit& d, unsigned IndentLevel, raw_ostream& O) const + void onListOrDag(const DagInit& d, HandlerImpl h, + unsigned IndentLevel, raw_ostream& O) const { checkNumberOfArguments(d, 1); const Init* I = d.getArg(0); @@ -2350,12 +2362,12 @@ class EmitPreprocessOptionsCallback : void onUnsetOption(const DagInit& d, unsigned IndentLevel, raw_ostream& O) const { - this->onListOrDag(&EmitPreprocessOptionsCallback::onUnsetOptionImpl, - d, IndentLevel, O); + this->onListOrDag(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl, + IndentLevel, O); } - void onSetListOrParameter(const DagInit& d, - unsigned IndentLevel, raw_ostream& O) const { + 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); @@ -2371,13 +2383,18 @@ class EmitPreprocessOptionsCallback : << InitPtrToString(*B) << "\");\n"; } } + else if (OptDesc.isSwitch()) { + CheckBooleanConstant(Value); + O.indent(IndentLevel) << OptDesc.GenVariableName() + << " = " << Value->getAsString() << ";\n"; + } else if (OptDesc.isParameter()) { const std::string& Str = InitPtrToString(Value); O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"" << Str << "\";\n"; } else { - throw "set_option: -" + OptName + ": is not a list or parameter option!"; + throw "Can't apply 'set_option' to alias option -" + OptName + " !"; } } @@ -2397,15 +2414,15 @@ class EmitPreprocessOptionsCallback : { checkNumberOfArguments(d, 1); - // Two arguments: (set_option "parameter", VALUE), where VALUE is either a - // string or a string list. + // Two arguments: (set_option "parameter", VALUE), where VALUE can be a + // boolean, a string or a string list. if (d.getNumArgs() > 1) - this->onSetListOrParameter(d, IndentLevel, O); + this->onSetOptionImpl(d, IndentLevel, O); // One argument: (set_option "switch") // or (set_option ["switch1", "switch2", ...]) else - this->onListOrDag(&EmitPreprocessOptionsCallback::onSetSwitch, - d, IndentLevel, O); + this->onListOrDag(d, &EmitPreprocessOptionsCallback::onSetSwitch, + IndentLevel, O); } public: