mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Add a 'set_option' action for use in OptionPreprocessor.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91594 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
24723288a2
commit
994dbe0073
@ -84,6 +84,7 @@ def stop_compilation;
|
|||||||
def unpack_values;
|
def unpack_values;
|
||||||
def warning;
|
def warning;
|
||||||
def error;
|
def error;
|
||||||
|
def set_option;
|
||||||
def unset_option;
|
def unset_option;
|
||||||
|
|
||||||
// Increase/decrease the edge weight.
|
// Increase/decrease the edge weight.
|
||||||
|
@ -11,20 +11,30 @@ def OptList : OptionList<[
|
|||||||
(switch_option "baz", (help "dummy")),
|
(switch_option "baz", (help "dummy")),
|
||||||
(parameter_option "foo_p", (help "dummy")),
|
(parameter_option "foo_p", (help "dummy")),
|
||||||
(parameter_option "bar_p", (help "dummy")),
|
(parameter_option "bar_p", (help "dummy")),
|
||||||
(parameter_option "baz_p", (help "dummy"))
|
(parameter_option "baz_p", (help "dummy")),
|
||||||
|
(parameter_list_option "foo_l", (help "dummy"))
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def Preprocess : OptionPreprocessor<
|
def Preprocess : OptionPreprocessor<
|
||||||
(case
|
(case
|
||||||
// CHECK: W1
|
// CHECK: W1
|
||||||
|
// CHECK: foo = false;
|
||||||
|
// CHECK: foo_p = "";
|
||||||
|
// CHECK: foo_l.clear();
|
||||||
(and (switch_on "foo"), (any_switch_on ["bar", "baz"])),
|
(and (switch_on "foo"), (any_switch_on ["bar", "baz"])),
|
||||||
(warning "W1"),
|
[(warning "W1"), (unset_option "foo"),
|
||||||
|
(unset_option "foo_p"), (unset_option "foo_l")],
|
||||||
// CHECK: W2
|
// CHECK: W2
|
||||||
|
// CHECK: foo = true;
|
||||||
|
// CHECK: foo_p = "asdf";
|
||||||
(and (switch_on ["foo", "bar"]), (any_empty ["foo_p", "bar_p"])),
|
(and (switch_on ["foo", "bar"]), (any_empty ["foo_p", "bar_p"])),
|
||||||
(warning "W2"),
|
[(warning "W2"), (set_option "foo"), (set_option "foo_p", "asdf")],
|
||||||
// CHECK: W3
|
// CHECK: W3
|
||||||
|
// CHECK: foo = true;
|
||||||
|
// CHECK: bar = true;
|
||||||
|
// CHECK: baz = true;
|
||||||
(and (empty ["foo_p", "bar_p"]), (any_not_empty ["baz_p"])),
|
(and (empty ["foo_p", "bar_p"]), (any_not_empty ["baz_p"])),
|
||||||
(warning "W3"))
|
[(warning "W3"), (set_option ["foo", "bar", "baz"])])
|
||||||
>;
|
>;
|
||||||
|
|
||||||
// Shut up warnings...
|
// Shut up warnings...
|
||||||
@ -38,7 +48,8 @@ def dummy : Tool<
|
|||||||
(switch_on "baz"), (error),
|
(switch_on "baz"), (error),
|
||||||
(not_empty "foo_p"), (error),
|
(not_empty "foo_p"), (error),
|
||||||
(not_empty "bar_p"), (error),
|
(not_empty "bar_p"), (error),
|
||||||
(not_empty "baz_p"), (error)))
|
(not_empty "baz_p"), (error),
|
||||||
|
(not_empty "foo_l"), (error)))
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def Graph : CompilationGraph<[Edge<"root", "dummy">]>;
|
def Graph : CompilationGraph<[Edge<"root", "dummy">]>;
|
||||||
|
@ -656,10 +656,10 @@ For example, without those definitions the following command wouldn't work::
|
|||||||
$ llvmc hello.cpp
|
$ llvmc hello.cpp
|
||||||
llvmc: Unknown suffix: cpp
|
llvmc: Unknown suffix: cpp
|
||||||
|
|
||||||
The language map entries should be added only for tools that are
|
The language map entries are needed only for the tools that are linked from the
|
||||||
linked with the root node. Since tools are not allowed to have
|
root node. Since a tool can't have multiple output languages, for inner nodes of
|
||||||
multiple output languages, for nodes "inside" the graph the input and
|
the graph the input and output languages should match. This is enforced at
|
||||||
output languages should match. This is enforced at compile-time.
|
compile-time.
|
||||||
|
|
||||||
Option preprocessor
|
Option preprocessor
|
||||||
===================
|
===================
|
||||||
@ -672,24 +672,31 @@ the driver with both of these options enabled.
|
|||||||
The ``OptionPreprocessor`` feature is reserved specially for these
|
The ``OptionPreprocessor`` feature is reserved specially for these
|
||||||
occasions. Example (adapted from the built-in Base plugin)::
|
occasions. Example (adapted from the built-in Base plugin)::
|
||||||
|
|
||||||
def Preprocess : OptionPreprocessor<
|
|
||||||
(case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
|
|
||||||
[(unset_option ["O0", "O1", "O2"]),
|
|
||||||
(warning "Multiple -O options specified, defaulted to -O3.")],
|
|
||||||
(and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
|
|
||||||
(unset_option ["O0", "O1"]),
|
|
||||||
(and (switch_on "O1"), (switch_on "O0")),
|
|
||||||
(unset_option "O0"))
|
|
||||||
>;
|
|
||||||
|
|
||||||
Here, ``OptionPreprocessor`` is used to unset all spurious optimization options
|
def Preprocess : OptionPreprocessor<
|
||||||
(so that they are not forwarded to the compiler).
|
(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 "O1"), (switch_on "O0")),
|
||||||
|
(unset_option "O0"))
|
||||||
|
>;
|
||||||
|
|
||||||
|
Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so
|
||||||
|
that they are not forwarded to the compiler. If no optimization options are
|
||||||
|
specified, ``-O2`` is enabled.
|
||||||
|
|
||||||
``OptionPreprocessor`` is basically a single big ``case`` expression, which is
|
``OptionPreprocessor`` is basically a single big ``case`` expression, which is
|
||||||
evaluated only once right after the plugin is loaded. The only allowed actions
|
evaluated only once right after the plugin is loaded. The only allowed actions
|
||||||
in ``OptionPreprocessor`` are ``error``, ``warning`` and a special action
|
in ``OptionPreprocessor`` are ``error``, ``warning`` and two special actions:
|
||||||
``unset_option``, which, as the name suggests, unsets a given option. For
|
``unset_option`` and ``set_option``. As their names suggest, they can be used to
|
||||||
convenience, ``unset_option`` also works on lists.
|
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"])``).
|
||||||
|
|
||||||
|
|
||||||
More advanced topics
|
More advanced topics
|
||||||
|
@ -91,7 +91,9 @@ def OptList : OptionList<[
|
|||||||
// Option preprocessor.
|
// Option preprocessor.
|
||||||
|
|
||||||
def Preprocess : OptionPreprocessor<
|
def Preprocess : OptionPreprocessor<
|
||||||
(case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
|
(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"]),
|
(unset_option ["O0", "O1", "O2"]),
|
||||||
(and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
|
(and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
|
||||||
(unset_option ["O0", "O1"]),
|
(unset_option ["O0", "O1"]),
|
||||||
|
@ -2303,11 +2303,32 @@ class EmitPreprocessOptionsCallback :
|
|||||||
public HandlerTable<EmitPreprocessOptionsCallbackHandler>
|
public HandlerTable<EmitPreprocessOptionsCallbackHandler>
|
||||||
{
|
{
|
||||||
typedef EmitPreprocessOptionsCallbackHandler Handler;
|
typedef EmitPreprocessOptionsCallbackHandler Handler;
|
||||||
|
typedef void
|
||||||
|
(EmitPreprocessOptionsCallback::* HandlerImpl)
|
||||||
|
(const Init*, unsigned, raw_ostream&) const;
|
||||||
|
|
||||||
const OptionDescriptions& OptDescs_;
|
const OptionDescriptions& OptDescs_;
|
||||||
|
|
||||||
void onUnsetOptionStr(const Init* I,
|
void onListOrDag(HandlerImpl h,
|
||||||
unsigned IndentLevel, raw_ostream& O) const
|
const DagInit& d, 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<const ListInit*>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUnsetOptionImpl(const Init* I,
|
||||||
|
unsigned IndentLevel, raw_ostream& O) const
|
||||||
{
|
{
|
||||||
const std::string& OptName = InitPtrToString(I);
|
const std::string& OptName = InitPtrToString(I);
|
||||||
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
|
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
|
||||||
@ -2326,26 +2347,52 @@ class EmitPreprocessOptionsCallback :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUnsetOptionList(const ListInit& L,
|
|
||||||
unsigned IndentLevel, raw_ostream& O) const
|
|
||||||
{
|
|
||||||
for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B)
|
|
||||||
this->onUnsetOptionStr(*B, IndentLevel, O);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onUnsetOption(const DagInit& d,
|
void onUnsetOption(const DagInit& d,
|
||||||
unsigned IndentLevel, raw_ostream& O) const
|
unsigned IndentLevel, raw_ostream& O) const
|
||||||
{
|
{
|
||||||
checkNumberOfArguments(d, 1);
|
this->onListOrDag(&EmitPreprocessOptionsCallback::onUnsetOptionImpl,
|
||||||
Init* I = d.getArg(0);
|
d, IndentLevel, O);
|
||||||
|
}
|
||||||
|
|
||||||
if (typeid(*I) == typeid(ListInit)) {
|
void onSetParameter(const DagInit& d,
|
||||||
const ListInit& L = *static_cast<const ListInit*>(I);
|
unsigned IndentLevel, raw_ostream& O) const {
|
||||||
this->onUnsetOptionList(L, IndentLevel, O);
|
checkNumberOfArguments(d, 2);
|
||||||
}
|
const std::string& OptName = InitPtrToString(d.getArg(0));
|
||||||
else {
|
const std::string& Value = InitPtrToString(d.getArg(1));
|
||||||
this->onUnsetOptionStr(I, IndentLevel, O);
|
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
|
||||||
}
|
|
||||||
|
if (OptDesc.isParameter())
|
||||||
|
O.indent(IndentLevel) << OptDesc.GenVariableName()
|
||||||
|
<< " = \"" << Value << "\";\n";
|
||||||
|
else
|
||||||
|
throw "Two-argument 'set_option' "
|
||||||
|
"can be only applied to parameter options!";
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSetSwitch(const Init* I,
|
||||||
|
unsigned IndentLevel, raw_ostream& O) const {
|
||||||
|
const std::string& OptName = InitPtrToString(I);
|
||||||
|
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
|
||||||
|
|
||||||
|
if (OptDesc.isSwitch())
|
||||||
|
O.indent(IndentLevel) << OptDesc.GenVariableName() << " = true;\n";
|
||||||
|
else
|
||||||
|
throw "One-argument 'set_option' can be only applied to switch options!";
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSetOption(const DagInit& d,
|
||||||
|
unsigned IndentLevel, raw_ostream& O) const
|
||||||
|
{
|
||||||
|
checkNumberOfArguments(d, 1);
|
||||||
|
|
||||||
|
// Two arguments: (set_option "parameter", "value")
|
||||||
|
if (d.getNumArgs() > 1)
|
||||||
|
this->onSetParameter(d, IndentLevel, O);
|
||||||
|
// One argument: (set_option "switch")
|
||||||
|
// or (set_option ["switch1", "switch2", ...])
|
||||||
|
else
|
||||||
|
this->onListOrDag(&EmitPreprocessOptionsCallback::onSetSwitch,
|
||||||
|
d, IndentLevel, O);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -2357,6 +2404,7 @@ public:
|
|||||||
AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag);
|
AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag);
|
||||||
AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag);
|
AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag);
|
||||||
AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption);
|
AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption);
|
||||||
|
AddHandler("set_option", &EmitPreprocessOptionsCallback::onSetOption);
|
||||||
|
|
||||||
staticMembersInitialized_ = true;
|
staticMembersInitialized_ = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user