mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-30 22:37:28 +00:00
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
This commit is contained in:
parent
c761f7dca2
commit
17ef94fe1b
@ -456,22 +456,22 @@ use TableGen inheritance instead.
|
|||||||
* Possible tests are:
|
* Possible tests are:
|
||||||
|
|
||||||
- ``switch_on`` - Returns true if a given command-line switch is provided by
|
- ``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",
|
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", "baz")`` is equivalent to ``(and (switch_on "foo"), (switch_on
|
||||||
"bar"), (switch_on "baz"))``.
|
"bar"), (switch_on "baz"))``.
|
||||||
Example: ``(switch_on "opt")``.
|
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.
|
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"))``.
|
(switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``.
|
||||||
|
|
||||||
- ``parameter_equals`` - Returns true if a command-line parameter equals
|
- ``parameter_equals`` - Returns true if a command-line parameter (first
|
||||||
a given value.
|
argument) equals a given value (second argument).
|
||||||
Example: ``(parameter_equals "W", "all")``.
|
Example: ``(parameter_equals "W", "all")``.
|
||||||
|
|
||||||
- ``element_in_list`` - Returns true if a command-line parameter
|
- ``element_in_list`` - Returns true if a command-line parameter list (first
|
||||||
list contains a given value.
|
argument) contains a given value (second argument).
|
||||||
Example: ``(element_in_list "l", "pthread")``.
|
Example: ``(element_in_list "l", "pthread")``.
|
||||||
|
|
||||||
- ``input_languages_contain`` - Returns true if a given language
|
- ``input_languages_contain`` - Returns true if a given language
|
||||||
@ -479,27 +479,27 @@ use TableGen inheritance instead.
|
|||||||
Example: ``(input_languages_contain "c++")``.
|
Example: ``(input_languages_contain "c++")``.
|
||||||
|
|
||||||
- ``in_language`` - Evaluates to true if the input file language is equal to
|
- ``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).
|
non-join nodes).
|
||||||
Example: ``(in_language "c++")``.
|
Example: ``(in_language "c++")``.
|
||||||
|
|
||||||
- ``not_empty`` - Returns true if a given option (which should be either a
|
- ``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
|
parameter or a parameter list) is set by the user. Like ``switch_on``, can
|
||||||
be also given a list as argument.
|
be also given multiple arguments.
|
||||||
Example: ``(not_empty "o")``.
|
Examples: ``(not_empty "o")``, ``(not_empty "o", "l")``.
|
||||||
|
|
||||||
- ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
|
- ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
|
||||||
the options in the list.
|
the provided options.
|
||||||
Example: ``(any_not_empty ["foo", "bar", "baz"])`` is equivalent to ``(or
|
Example: ``(any_not_empty "foo", "bar", "baz")`` is equivalent to ``(or
|
||||||
(not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
|
(not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
|
||||||
|
|
||||||
- ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty
|
- ``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
|
- ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
|
||||||
the options in the list.
|
the provided options.
|
||||||
Example: ``(any_empty ["foo", "bar", "baz"])`` is equivalent to ``(not (and
|
Example: ``(any_empty "foo", "bar", "baz")`` is equivalent to ``(or
|
||||||
(not_empty "foo"), (not_empty "bar"), (not_empty "baz")))``.
|
(not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
|
||||||
|
|
||||||
- ``single_input_file`` - Returns true if there was only one input file
|
- ``single_input_file`` - Returns true if there was only one input file
|
||||||
provided on the command-line. Used without arguments:
|
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
|
- ``default`` - Always evaluates to true. Should always be the last
|
||||||
test in the ``case`` expression.
|
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),
|
its arguments return true. Used like this: ``(and (test1), (test2),
|
||||||
... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not
|
... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not
|
||||||
encouraged.
|
encouraged.
|
||||||
|
|
||||||
- ``or`` - A binary logical combinator that returns true iff any of its
|
- ``or`` - A logical combinator that returns true iff any of its arguments
|
||||||
arguments returns true. Example: ``(or (test1), (test2), ... (testN))``.
|
return true.
|
||||||
|
Example: ``(or (test1), (test2), ... (testN))``.
|
||||||
|
|
||||||
- ``not`` - Standard unary logical combinator that negates its
|
- ``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:
|
* Possible tool properties:
|
||||||
|
|
||||||
- ``in_language`` - input language name. Can be either a string or a
|
- ``in_language`` - input language name. Can be given multiple arguments, in
|
||||||
list, in case the tool supports multiple input languages.
|
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.
|
allowed.
|
||||||
|
|
||||||
- ``output_suffix`` - output file suffix. Can also be changed
|
- ``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<
|
def Preprocess : OptionPreprocessor<
|
||||||
(case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
|
(case (not (any_switch_on "O0", "O1", "O2", "O3")),
|
||||||
(set_option "O2"),
|
(set_option "O2"),
|
||||||
(and (switch_on "O3"), (any_switch_on ["O0", "O1", "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"),
|
||||||
(and (switch_on "O1"), (switch_on "O0")),
|
(and (switch_on "O1"), (switch_on "O0")),
|
||||||
(unset_option "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
|
two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be
|
||||||
either a string, a string list, or a boolean constant.
|
either a string, a string list, or a boolean constant.
|
||||||
|
|
||||||
For convenience, ``set_option`` and ``unset_option`` also work on lists. That
|
For convenience, ``set_option`` and ``unset_option`` also work with multiple
|
||||||
is, instead of ``[(unset_option "A"), (unset_option "B")]`` you can use
|
arguments. That is, instead of ``[(unset_option "A"), (unset_option "B")]`` you
|
||||||
``(unset_option ["A", "B"])``. Obviously, ``(set_option ["A", "B"])`` is valid
|
can use ``(unset_option "A", "B")``. Obviously, ``(set_option "A", "B")`` is
|
||||||
only if both ``A`` and ``B`` are switches.
|
only valid if both ``A`` and ``B`` are switches.
|
||||||
|
|
||||||
|
|
||||||
More advanced topics
|
More advanced topics
|
||||||
|
@ -152,23 +152,22 @@ def LinkerOptList : OptionList<[
|
|||||||
// Option preprocessor.
|
// Option preprocessor.
|
||||||
|
|
||||||
def Preprocess : OptionPreprocessor<
|
def Preprocess : OptionPreprocessor<
|
||||||
(case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
|
(case (not (any_switch_on "O0", "O1", "O2", "O3")),
|
||||||
(set_option "O2"),
|
(set_option "O2"),
|
||||||
(and (switch_on "O3"), (any_switch_on ["O0", "O1", "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"),
|
||||||
(switch_on ["O1", "O0"]),
|
(switch_on "O1", "O0"),
|
||||||
(unset_option "O0"))
|
(unset_option "O0"))
|
||||||
>;
|
>;
|
||||||
|
|
||||||
// Tools
|
// Tools
|
||||||
|
|
||||||
class llvm_gcc_based <string cmd, string in_lang,
|
class llvm_gcc_based <string cmd, string in_lang, string E_ext, dag out_lang,
|
||||||
string E_ext, list<string> out_lang,
|
|
||||||
string out_ext> : Tool<
|
string out_ext> : Tool<
|
||||||
[(in_language in_lang),
|
[(in_language in_lang),
|
||||||
(out_language out_lang),
|
out_lang,
|
||||||
(output_suffix out_ext),
|
(output_suffix out_ext),
|
||||||
(command cmd),
|
(command cmd),
|
||||||
(actions
|
(actions
|
||||||
@ -184,7 +183,7 @@ class llvm_gcc_based <string cmd, string in_lang,
|
|||||||
(and (switch_on "emit-llvm"), (not (switch_on "opt"))),
|
(and (switch_on "emit-llvm"), (not (switch_on "opt"))),
|
||||||
(stop_compilation),
|
(stop_compilation),
|
||||||
// ('-S' && '-emit-llvm') && !('opt') -> output .ll
|
// ('-S' && '-emit-llvm') && !('opt') -> 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")],
|
[(forward "S"), (output_suffix "ll")],
|
||||||
// Ususally just output .bc
|
// Ususally just output .bc
|
||||||
(not (switch_on "fsyntax-only")),
|
(not (switch_on "fsyntax-only")),
|
||||||
@ -222,10 +221,12 @@ class llvm_gcc_based <string cmd, string in_lang,
|
|||||||
]>;
|
]>;
|
||||||
|
|
||||||
class llvm_gcc_comp_based <string cmd, string in_lang, string E_ext>
|
class llvm_gcc_comp_based <string cmd, string in_lang, string E_ext>
|
||||||
: llvm_gcc_based<cmd, in_lang, E_ext, ["llvm-bitcode", "object-code"], "bc">;
|
: llvm_gcc_based<cmd, in_lang, E_ext,
|
||||||
|
(out_language "llvm-bitcode", "object-code"), "bc">;
|
||||||
|
|
||||||
class llvm_gcc_pch_based <string cmd, string in_lang, string E_ext>
|
class llvm_gcc_pch_based <string cmd, string in_lang, string E_ext>
|
||||||
: llvm_gcc_based<cmd, in_lang, E_ext, ["precompiled-header"], "gch">;
|
: llvm_gcc_based<cmd, in_lang, E_ext,
|
||||||
|
(out_language "precompiled-header"), "gch">;
|
||||||
|
|
||||||
def llvm_gcc_c : llvm_gcc_comp_based
|
def llvm_gcc_c : llvm_gcc_comp_based
|
||||||
<"@LLVMGCCCOMMAND@ -x c", "c", "i">;
|
<"@LLVMGCCCOMMAND@ -x c", "c", "i">;
|
||||||
@ -250,7 +251,7 @@ def opt : Tool<
|
|||||||
(out_language "llvm-bitcode"),
|
(out_language "llvm-bitcode"),
|
||||||
(output_suffix "opt.bc"),
|
(output_suffix "opt.bc"),
|
||||||
(actions (case (switch_on "emit-llvm"), (stop_compilation),
|
(actions (case (switch_on "emit-llvm"), (stop_compilation),
|
||||||
(switch_on ["emit-llvm", "S"]),
|
(switch_on "emit-llvm", "S"),
|
||||||
[(append_cmd "-S"), (output_suffix "ll")],
|
[(append_cmd "-S"), (output_suffix "ll")],
|
||||||
(not_empty "Wo,"), (forward_value "Wo,"),
|
(not_empty "Wo,"), (forward_value "Wo,"),
|
||||||
(switch_on "O1"), (forward "O1"),
|
(switch_on "O1"), (forward "O1"),
|
||||||
@ -282,7 +283,7 @@ def llvm_gcc_assembler : Tool<
|
|||||||
]>;
|
]>;
|
||||||
|
|
||||||
def llc : Tool<
|
def llc : Tool<
|
||||||
[(in_language ["llvm-bitcode", "llvm-assembler"]),
|
[(in_language "llvm-bitcode", "llvm-assembler"),
|
||||||
(out_language "assembler"),
|
(out_language "assembler"),
|
||||||
(output_suffix "s"),
|
(output_suffix "s"),
|
||||||
(command "llc"),
|
(command "llc"),
|
||||||
@ -304,7 +305,7 @@ def llc : Tool<
|
|||||||
|
|
||||||
// Base class for linkers
|
// Base class for linkers
|
||||||
class llvm_gcc_based_linker <string cmd, dag on_empty> : Tool<
|
class llvm_gcc_based_linker <string cmd, dag on_empty> : Tool<
|
||||||
[(in_language ["object-code", "static-library", "dynamic-library"]),
|
[(in_language "object-code", "static-library", "dynamic-library"),
|
||||||
(out_language "executable"),
|
(out_language "executable"),
|
||||||
(output_suffix "out"),
|
(output_suffix "out"),
|
||||||
(command cmd),
|
(command cmd),
|
||||||
|
@ -25,12 +25,12 @@ class clang_based<string language, string cmd, string ext_E> : Tool<
|
|||||||
[(forward "E"), (stop_compilation), (output_suffix ext_E)],
|
[(forward "E"), (stop_compilation), (output_suffix ext_E)],
|
||||||
(and (switch_on "E"), (empty "o")), (no_out_file),
|
(and (switch_on "E"), (empty "o")), (no_out_file),
|
||||||
(switch_on "fsyntax-only"), (stop_compilation),
|
(switch_on "fsyntax-only"), (stop_compilation),
|
||||||
(switch_on ["S", "emit-llvm"]),
|
(switch_on "S", "emit-llvm"),
|
||||||
[(append_cmd "-emit-llvm"),
|
[(append_cmd "-emit-llvm"),
|
||||||
(stop_compilation), (output_suffix "ll")],
|
(stop_compilation), (output_suffix "ll")],
|
||||||
(not (switch_on ["S", "emit-llvm"])),
|
(not (switch_on "S", "emit-llvm")),
|
||||||
(append_cmd "-emit-llvm-bc"),
|
(append_cmd "-emit-llvm-bc"),
|
||||||
(switch_on ["c", "emit-llvm"]),
|
(switch_on "c", "emit-llvm"),
|
||||||
(stop_compilation),
|
(stop_compilation),
|
||||||
(not_empty "include"), (forward "include"),
|
(not_empty "include"), (forward "include"),
|
||||||
(not_empty "I"), (forward "I"))),
|
(not_empty "I"), (forward "I"))),
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -164,18 +165,6 @@ void CheckedIncrement(I& P, I E, S ErrorString) {
|
|||||||
throw 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<typename F, typename T0>
|
|
||||||
void apply(F Fun, T0& Arg0) {
|
|
||||||
return Fun(Arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename F, typename T0, typename T1>
|
|
||||||
void apply(F Fun, T0& Arg0, T1& Arg1) {
|
|
||||||
return Fun(Arg0, Arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// Back-end specific code
|
/// Back-end specific code
|
||||||
|
|
||||||
@ -809,13 +798,12 @@ void CollectOptionDescriptions (const RecordVector& V,
|
|||||||
OptionDescriptions& OptDescs)
|
OptionDescriptions& OptDescs)
|
||||||
{
|
{
|
||||||
// For every OptionList:
|
// For every OptionList:
|
||||||
for (RecordVector::const_iterator B = V.begin(),
|
for (RecordVector::const_iterator B = V.begin(), E = V.end(); B!=E; ++B)
|
||||||
E = V.end(); B!=E; ++B) {
|
{
|
||||||
// Throws an exception if the value does not exist.
|
// Throws an exception if the value does not exist.
|
||||||
ListInit* PropList = (*B)->getValueAsListInit("options");
|
ListInit* PropList = (*B)->getValueAsListInit("options");
|
||||||
|
|
||||||
// For every option description in this list:
|
// For every option description in this list: invoke AddOption.
|
||||||
// collect the information and
|
|
||||||
std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs));
|
std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -922,26 +910,16 @@ private:
|
|||||||
/// onInOutLanguage - Common implementation of on{In,Out}Language().
|
/// onInOutLanguage - Common implementation of on{In,Out}Language().
|
||||||
void onInOutLanguage (const DagInit& d, StrVector& OutVec) {
|
void onInOutLanguage (const DagInit& d, StrVector& OutVec) {
|
||||||
CheckNumberOfArguments(d, 1);
|
CheckNumberOfArguments(d, 1);
|
||||||
Init* arg = d.getArg(0);
|
|
||||||
|
|
||||||
// Find out the argument's type.
|
// Copy strings to the output vector.
|
||||||
if (typeid(*arg) == typeid(StringInit)) {
|
for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
|
||||||
// It's a string.
|
OutVec.push_back(InitPtrToString(d.getArg(i)));
|
||||||
OutVec.push_back(InitPtrToString(arg));
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// It's a list.
|
|
||||||
const ListInit& lst = InitPtrToList(arg);
|
|
||||||
|
|
||||||
// Copy strings to the output vector.
|
// Remove duplicates.
|
||||||
for (ListInit::const_iterator B = lst.begin(), E = lst.end(); B != E; ++B)
|
std::sort(OutVec.begin(), OutVec.end());
|
||||||
OutVec.push_back(InitPtrToString(*B));
|
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" ||
|
if (ActionName == "forward" || ActionName == "forward_as" ||
|
||||||
ActionName == "forward_value" ||
|
ActionName == "forward_value" ||
|
||||||
ActionName == "forward_transformed_value" ||
|
ActionName == "forward_transformed_value" ||
|
||||||
ActionName == "switch_on" || ActionName == "any_switch_on" ||
|
ActionName == "parameter_equals" || ActionName == "element_in_list") {
|
||||||
ActionName == "parameter_equals" ||
|
|
||||||
ActionName == "element_in_list" || ActionName == "not_empty" ||
|
|
||||||
ActionName == "empty") {
|
|
||||||
CheckNumberOfArguments(Stmt, 1);
|
CheckNumberOfArguments(Stmt, 1);
|
||||||
|
|
||||||
Init* Arg = Stmt.getArg(0);
|
Init* Arg = Stmt.getArg(0);
|
||||||
if (typeid(*Arg) == typeid(StringInit)) {
|
if (typeid(*Arg) == typeid(StringInit))
|
||||||
const std::string& Name = InitPtrToString(Arg);
|
OptionNames_.insert(InitPtrToString(Arg));
|
||||||
OptionNames_.insert(Name);
|
}
|
||||||
}
|
else if (ActionName == "any_switch_on" || ActionName == "switch_on" ||
|
||||||
else {
|
ActionName == "any_not_empty" || ActionName == "any_empty" ||
|
||||||
// It's a list.
|
ActionName == "not_empty" || ActionName == "empty") {
|
||||||
const ListInit& List = InitPtrToList(Arg);
|
for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
|
||||||
for (ListInit::const_iterator B = List.begin(), E = List.end();
|
Init* Arg = Stmt.getArg(i);
|
||||||
B != E; ++B) {
|
if (typeid(*Arg) == typeid(StringInit))
|
||||||
const std::string& Name = InitPtrToString(*B);
|
OptionNames_.insert(InitPtrToString(Arg));
|
||||||
OptionNames_.insert(Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ActionName == "and" || ActionName == "or" || ActionName == "not") {
|
else if (ActionName == "and" || ActionName == "or" || ActionName == "not") {
|
||||||
@ -1228,6 +1201,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
void operator()(const Init* Statement) {
|
void operator()(const Init* Statement) {
|
||||||
|
// Statement is either a dag, or a list of dags.
|
||||||
if (typeid(*Statement) == typeid(ListInit)) {
|
if (typeid(*Statement) == typeid(ListInit)) {
|
||||||
const ListInit& DagList = *static_cast<const ListInit*>(Statement);
|
const ListInit& DagList = *static_cast<const ListInit*>(Statement);
|
||||||
for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitListTest - Helper function used by EmitCaseTest1ArgList().
|
/// EmitMultipleArgumentTest - Helper function used by
|
||||||
|
/// EmitCaseTestMultipleArgs()
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void EmitListTest(const ListInit& L, const char* LogicOp,
|
void EmitMultipleArgumentTest(const DagInit& D, const char* LogicOp,
|
||||||
F Callback, raw_ostream& O)
|
F Callback, raw_ostream& O)
|
||||||
{
|
{
|
||||||
// This is a lot like EmitLogicalOperationTest, but works on ListInits instead
|
for (unsigned i = 0, NumArgs = D.getNumArgs(); i < NumArgs; ++i) {
|
||||||
// of Dags...
|
if (i != 0)
|
||||||
bool isFirst = true;
|
O << ' ' << LogicOp << ' ';
|
||||||
for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) {
|
Callback(InitPtrToString(D.getArg(i)), O);
|
||||||
if (isFirst)
|
|
||||||
isFirst = false;
|
|
||||||
else
|
|
||||||
O << ' ' << LogicOp << ' ';
|
|
||||||
Callback(InitPtrToString(*B), O);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callbacks for use with EmitListTest.
|
// Callbacks for use with EmitMultipleArgumentTest
|
||||||
|
|
||||||
class EmitSwitchOn {
|
class EmitSwitchOn {
|
||||||
const OptionDescriptions& OptDescs_;
|
const OptionDescriptions& OptDescs_;
|
||||||
@ -1363,54 +1333,48 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// EmitCaseTest1ArgList - Helper function used by EmitCaseTest1Arg();
|
/// EmitCaseTestMultipleArgs - Helper function used by EmitCaseTest1Arg()
|
||||||
bool EmitCaseTest1ArgList(const std::string& TestName,
|
bool EmitCaseTestMultipleArgs (const std::string& TestName,
|
||||||
const DagInit& d,
|
const DagInit& d,
|
||||||
const OptionDescriptions& OptDescs,
|
const OptionDescriptions& OptDescs,
|
||||||
raw_ostream& O) {
|
raw_ostream& O) {
|
||||||
const ListInit& L = InitPtrToList(d.getArg(0));
|
|
||||||
|
|
||||||
if (TestName == "any_switch_on") {
|
if (TestName == "any_switch_on") {
|
||||||
EmitListTest(L, "||", EmitSwitchOn(OptDescs), O);
|
EmitMultipleArgumentTest(d, "||", EmitSwitchOn(OptDescs), O);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TestName == "switch_on") {
|
else if (TestName == "switch_on") {
|
||||||
EmitListTest(L, "&&", EmitSwitchOn(OptDescs), O);
|
EmitMultipleArgumentTest(d, "&&", EmitSwitchOn(OptDescs), O);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TestName == "any_not_empty") {
|
else if (TestName == "any_not_empty") {
|
||||||
EmitListTest(L, "||", EmitEmptyTest(true, OptDescs), O);
|
EmitMultipleArgumentTest(d, "||", EmitEmptyTest(true, OptDescs), O);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TestName == "any_empty") {
|
else if (TestName == "any_empty") {
|
||||||
EmitListTest(L, "||", EmitEmptyTest(false, OptDescs), O);
|
EmitMultipleArgumentTest(d, "||", EmitEmptyTest(false, OptDescs), O);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TestName == "not_empty") {
|
else if (TestName == "not_empty") {
|
||||||
EmitListTest(L, "&&", EmitEmptyTest(true, OptDescs), O);
|
EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(true, OptDescs), O);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TestName == "empty") {
|
else if (TestName == "empty") {
|
||||||
EmitListTest(L, "&&", EmitEmptyTest(false, OptDescs), O);
|
EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(false, OptDescs), O);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg();
|
/// EmitCaseTest1Arg - Helper function used by EmitCaseTest1OrMoreArgs()
|
||||||
bool EmitCaseTest1ArgStr(const std::string& TestName,
|
bool EmitCaseTest1Arg (const std::string& TestName,
|
||||||
const DagInit& d,
|
const DagInit& d,
|
||||||
const OptionDescriptions& OptDescs,
|
const OptionDescriptions& OptDescs,
|
||||||
raw_ostream& O) {
|
raw_ostream& O) {
|
||||||
const std::string& OptName = InitPtrToString(d.getArg(0));
|
const std::string& Arg = InitPtrToString(d.getArg(0));
|
||||||
|
|
||||||
if (TestName == "switch_on") {
|
if (TestName == "input_languages_contain") {
|
||||||
apply(EmitSwitchOn(OptDescs), OptName, O);
|
O << "InLangs.count(\"" << Arg << "\") != 0";
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (TestName == "input_languages_contain") {
|
|
||||||
O << "InLangs.count(\"" << OptName << "\") != 0";
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TestName == "in_language") {
|
else if (TestName == "in_language") {
|
||||||
@ -1418,28 +1382,22 @@ bool EmitCaseTest1ArgStr(const std::string& TestName,
|
|||||||
// tools can process several files in different languages simultaneously.
|
// tools can process several files in different languages simultaneously.
|
||||||
|
|
||||||
// TODO: make this work with Edge::Weight (if possible).
|
// TODO: make this work with Edge::Weight (if possible).
|
||||||
O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"';
|
O << "LangMap.GetLanguage(inFile) == \"" << Arg << '\"';
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (TestName == "not_empty" || TestName == "empty") {
|
|
||||||
bool EmitNegate = (TestName == "not_empty");
|
|
||||||
apply(EmitEmptyTest(EmitNegate, OptDescs), OptName, O);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler();
|
/// EmitCaseTest1OrMoreArgs - Helper function used by
|
||||||
bool EmitCaseTest1Arg(const std::string& TestName,
|
/// EmitCaseConstructHandler()
|
||||||
const DagInit& d,
|
bool EmitCaseTest1OrMoreArgs(const std::string& TestName,
|
||||||
const OptionDescriptions& OptDescs,
|
const DagInit& d,
|
||||||
raw_ostream& O) {
|
const OptionDescriptions& OptDescs,
|
||||||
|
raw_ostream& O) {
|
||||||
CheckNumberOfArguments(d, 1);
|
CheckNumberOfArguments(d, 1);
|
||||||
if (typeid(*d.getArg(0)) == typeid(ListInit))
|
return EmitCaseTest1Arg(TestName, d, OptDescs, O) ||
|
||||||
return EmitCaseTest1ArgList(TestName, d, OptDescs, O);
|
EmitCaseTestMultipleArgs(TestName, d, OptDescs, O);
|
||||||
else
|
|
||||||
return EmitCaseTest1ArgStr(TestName, d, OptDescs, O);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
|
/// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
|
||||||
@ -1483,10 +1441,10 @@ void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
|
|||||||
const OptionDescriptions& OptDescs,
|
const OptionDescriptions& OptDescs,
|
||||||
raw_ostream& O) {
|
raw_ostream& O) {
|
||||||
O << '(';
|
O << '(';
|
||||||
for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
|
for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
|
||||||
const DagInit& InnerTest = InitPtrToDag(d.getArg(j));
|
const DagInit& InnerTest = InitPtrToDag(d.getArg(i));
|
||||||
EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
|
EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
|
||||||
if (j != NumArgs - 1) {
|
if (i != NumArgs - 1) {
|
||||||
O << ")\n";
|
O << ")\n";
|
||||||
O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
|
O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
|
||||||
}
|
}
|
||||||
@ -1520,7 +1478,7 @@ void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
|
|||||||
EmitLogicalNot(d, IndentLevel, OptDescs, O);
|
EmitLogicalNot(d, IndentLevel, OptDescs, O);
|
||||||
else if (EmitCaseTest0Args(TestName, O))
|
else if (EmitCaseTest0Args(TestName, O))
|
||||||
return;
|
return;
|
||||||
else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
|
else if (EmitCaseTest1OrMoreArgs(TestName, d, OptDescs, O))
|
||||||
return;
|
return;
|
||||||
else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
|
else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
|
||||||
return;
|
return;
|
||||||
@ -1567,10 +1525,12 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
void operator() (const Init* Statement, unsigned IndentLevel) {
|
void operator() (const Init* Statement, unsigned IndentLevel) {
|
||||||
|
// Is this a nested 'case'?
|
||||||
|
bool IsCase = dynamic_cast<const DagInit*>(Statement) &&
|
||||||
|
GetOperatorName(static_cast<const DagInit&>(*Statement)) == "case";
|
||||||
|
|
||||||
// Ignore nested 'case' DAG.
|
// If so, ignore it, it is handled by our caller, WalkCase.
|
||||||
if (!(dynamic_cast<const DagInit*>(Statement) &&
|
if (!IsCase) {
|
||||||
GetOperatorName(static_cast<const DagInit&>(*Statement)) == "case")) {
|
|
||||||
if (typeid(*Statement) == typeid(ListInit)) {
|
if (typeid(*Statement) == typeid(ListInit)) {
|
||||||
const ListInit& DagList = *static_cast<const ListInit*>(Statement);
|
const ListInit& DagList = *static_cast<const ListInit*>(Statement);
|
||||||
for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
|
for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
|
||||||
@ -2474,21 +2434,13 @@ class EmitPreprocessOptionsCallback :
|
|||||||
|
|
||||||
const OptionDescriptions& OptDescs_;
|
const OptionDescriptions& OptDescs_;
|
||||||
|
|
||||||
void onListOrDag(const DagInit& d, HandlerImpl h,
|
void onEachArgument(const DagInit& d, HandlerImpl h,
|
||||||
unsigned IndentLevel, raw_ostream& O) const
|
unsigned IndentLevel, raw_ostream& O) const
|
||||||
{
|
{
|
||||||
CheckNumberOfArguments(d, 1);
|
CheckNumberOfArguments(d, 1);
|
||||||
const Init* I = d.getArg(0);
|
|
||||||
|
|
||||||
// If I is a list, apply h to each element.
|
for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
|
||||||
if (typeid(*I) == typeid(ListInit)) {
|
((this)->*(h))(d.getArg(i), IndentLevel, O);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2515,16 +2467,17 @@ class EmitPreprocessOptionsCallback :
|
|||||||
void onUnsetOption(const DagInit& d,
|
void onUnsetOption(const DagInit& d,
|
||||||
unsigned IndentLevel, raw_ostream& O) const
|
unsigned IndentLevel, raw_ostream& O) const
|
||||||
{
|
{
|
||||||
this->onListOrDag(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl,
|
this->onEachArgument(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl,
|
||||||
IndentLevel, O);
|
IndentLevel, O);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSetOptionImpl(const DagInit& d,
|
void onSetOptionImpl(const DagInit& D,
|
||||||
unsigned IndentLevel, raw_ostream& O) const {
|
unsigned IndentLevel, raw_ostream& O) const {
|
||||||
CheckNumberOfArguments(d, 2);
|
CheckNumberOfArguments(D, 2);
|
||||||
const std::string& OptName = InitPtrToString(d.getArg(0));
|
|
||||||
const Init* Value = d.getArg(1);
|
const std::string& OptName = InitPtrToString(D.getArg(0));
|
||||||
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
|
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
|
||||||
|
const Init* Value = D.getArg(1);
|
||||||
|
|
||||||
if (OptDesc.isList()) {
|
if (OptDesc.isList()) {
|
||||||
const ListInit& List = InitPtrToList(Value);
|
const ListInit& List = InitPtrToList(Value);
|
||||||
@ -2554,7 +2507,7 @@ class EmitPreprocessOptionsCallback :
|
|||||||
<< " = \"" << Str << "\";\n";
|
<< " = \"" << Str << "\";\n";
|
||||||
}
|
}
|
||||||
else {
|
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);
|
CheckNumberOfArguments(d, 1);
|
||||||
|
|
||||||
// Two arguments: (set_option "parameter", VALUE), where VALUE can be a
|
// 2-argument form: (set_option "A", true), (set_option "B", "C"),
|
||||||
// boolean, a string or a string list.
|
// (set_option "D", ["E", "F"])
|
||||||
if (d.getNumArgs() > 1)
|
if (d.getNumArgs() == 2) {
|
||||||
this->onSetOptionImpl(d, IndentLevel, O);
|
const OptionDescription& OptDesc =
|
||||||
// One argument: (set_option "switch")
|
OptDescs_.FindOption(InitPtrToString(d.getArg(0)));
|
||||||
// or (set_option ["switch1", "switch2", ...])
|
const Init* Opt2 = d.getArg(1);
|
||||||
else
|
|
||||||
this->onListOrDag(d, &EmitPreprocessOptionsCallback::onSetSwitch,
|
if (!OptDesc.isSwitch() || typeid(*Opt2) != typeid(StringInit)) {
|
||||||
IndentLevel, O);
|
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:
|
public:
|
||||||
@ -2687,10 +2647,11 @@ void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
|
|||||||
{
|
{
|
||||||
O << "int PopulateLanguageMap (LanguageMap& langMap) {\n";
|
O << "int PopulateLanguageMap (LanguageMap& langMap) {\n";
|
||||||
|
|
||||||
// For each LangMap:
|
// For each LanguageMap:
|
||||||
const RecordVector& LangMaps =
|
const RecordVector& LangMaps =
|
||||||
Records.getAllDerivedDefinitions("LanguageMap");
|
Records.getAllDerivedDefinitions("LanguageMap");
|
||||||
|
|
||||||
|
// Call DoEmitPopulateLanguageMap.
|
||||||
for (RecordVector::const_iterator B = LangMaps.begin(),
|
for (RecordVector::const_iterator B = LangMaps.begin(),
|
||||||
E = LangMaps.end(); B!=E; ++B) {
|
E = LangMaps.end(); B!=E; ++B) {
|
||||||
ListInit* LangMap = (*B)->getValueAsListInit("map");
|
ListInit* LangMap = (*B)->getValueAsListInit("map");
|
||||||
@ -2925,7 +2886,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're invoked on a command line.
|
// We're invoked on a command line string.
|
||||||
this->onCmdLine(InitPtrToString(Arg));
|
this->onCmdLine(InitPtrToString(Arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user