gccrs: use tl::optional for macro transcribers
refs #2421. gcc/rust/ChangeLog: * ast/rust-ast-fragment.cc (Fragment::create_empty): New. * ast/rust-ast-fragment.h (MacroTranscriberFunc): New. * ast/rust-macro.h (MacroRulesDefinition): Use MacroTranscriberFunc. * expand/rust-macro-builtins.cc (MacroBuiltin::builtin_transcribers): likewise. (MacroBuiltin::assert_handler): Return optional. (MacroBuiltin::file_handler): Likewise. (MacroBuiltin::column_handler): Likewise. (MacroBuiltin::include_bytes_handler): Likewise. (MacroBuiltin::include_str_handler): Likewise. (MacroBuiltin::compile_error_handler): Likewise. (MacroBuiltin::concat_handler): Likewise. (MacroBuiltin::env_handler): Likewise. (MacroBuiltin::cfg_handler): Likewise. (MacroBuiltin::include_handler): Likewise. (MacroBuiltin::line_handler): Likewise. (MacroBuiltin::stringify_handler): Likewise. (MacroBuiltin::sorry): Likewise. * expand/rust-macro-builtins.h (builtin_transcribers): Use MacroTranscriberFunc. (assert_handler): Return optional. (file_handler): Likewise. (column_handler): Likewise. (include_bytes_handler): Likewise. (include_str_handler): Likewise. (compile_error_handler): Likewise. (concat_handler): Likewise. (env_handler): Likewise. (cfg_handler): Likewise. (include_handler): Likewise. (line_handler): Likewise. (stringify_handler): Likewise. (sorry): Likewise. * expand/rust-macro-expand.cc (MacroExpander::expand_invoc): Adjust to transcribers returning optional. Signed-off-by: Marc Poulhiès <dkm@kataplop.net>
This commit is contained in:
parent
432cdee6a6
commit
58b49a65a3
6 changed files with 77 additions and 60 deletions
|
@ -55,6 +55,12 @@ Fragment::create_error ()
|
|||
return Fragment (FragmentKind::Error, {}, {});
|
||||
}
|
||||
|
||||
Fragment
|
||||
Fragment::create_empty ()
|
||||
{
|
||||
return Fragment (FragmentKind::Complete, {}, {});
|
||||
}
|
||||
|
||||
Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
|
||||
std::vector<std::unique_ptr<AST::Token>> tokens)
|
||||
: kind (FragmentKind::Complete), nodes (std::move (nodes)),
|
||||
|
|
|
@ -60,6 +60,11 @@ public:
|
|||
*/
|
||||
static Fragment create_error ();
|
||||
|
||||
/**
|
||||
* Create an empty fragment
|
||||
*/
|
||||
static Fragment create_empty ();
|
||||
|
||||
/**
|
||||
* Create a complete AST fragment
|
||||
*/
|
||||
|
@ -117,6 +122,14 @@ private:
|
|||
bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const;
|
||||
void assert_single_fragment (SingleASTNode::NodeType expected) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the type for transcriber functions found in
|
||||
* rust-macro-builtins.{h,cc}.
|
||||
*/
|
||||
using MacroTranscriberFunc
|
||||
= std::function<tl::optional<Fragment> (location_t, MacroInvocData &)>;
|
||||
|
||||
} // namespace AST
|
||||
} // namespace Rust
|
||||
|
||||
|
|
|
@ -468,7 +468,8 @@ private:
|
|||
std::vector<MacroRule> rules; // inlined form
|
||||
location_t locus;
|
||||
|
||||
std::function<Fragment (location_t, MacroInvocData &)> associated_transcriber;
|
||||
MacroTranscriberFunc associated_transcriber;
|
||||
|
||||
// Since we can't compare std::functions, we need to use an extra boolean
|
||||
bool is_builtin_rule;
|
||||
MacroKind kind;
|
||||
|
@ -503,8 +504,7 @@ private:
|
|||
{}
|
||||
|
||||
MacroRulesDefinition (Identifier builtin_name, DelimType delim_type,
|
||||
std::function<Fragment (location_t, MacroInvocData &)>
|
||||
associated_transcriber,
|
||||
MacroTranscriberFunc associated_transcriber,
|
||||
MacroKind kind, Visibility vis)
|
||||
: VisItem (std::move (vis), std::vector<Attribute> ()),
|
||||
outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name),
|
||||
|
@ -560,14 +560,12 @@ public:
|
|||
const std::vector<MacroRule> &get_rules () const { return rules; }
|
||||
|
||||
bool is_builtin () const { return is_builtin_rule; }
|
||||
const std::function<Fragment (location_t, MacroInvocData &)> &
|
||||
get_builtin_transcriber () const
|
||||
const MacroTranscriberFunc &get_builtin_transcriber () const
|
||||
{
|
||||
rust_assert (is_builtin ());
|
||||
return associated_transcriber;
|
||||
}
|
||||
void set_builtin_transcriber (
|
||||
std::function<Fragment (location_t, MacroInvocData &)> transcriber)
|
||||
void set_builtin_transcriber (MacroTranscriberFunc transcriber)
|
||||
{
|
||||
associated_transcriber = transcriber;
|
||||
is_builtin_rule = true;
|
||||
|
|
|
@ -74,8 +74,7 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
|
|||
|
||||
}};
|
||||
|
||||
std::unordered_map<
|
||||
std::string, std::function<AST::Fragment (location_t, AST::MacroInvocData &)>>
|
||||
std::unordered_map<std::string, AST::MacroTranscriberFunc>
|
||||
MacroBuiltin::builtin_transcribers = {
|
||||
{"assert", MacroBuiltin::assert_handler},
|
||||
{"file", MacroBuiltin::file_handler},
|
||||
|
@ -398,7 +397,7 @@ load_file_bytes (location_t invoc_locus, const char *filename)
|
|||
}
|
||||
} // namespace
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::assert_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -407,7 +406,7 @@ MacroBuiltin::assert_handler (location_t invoc_locus,
|
|||
return AST::Fragment::create_error ();
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &)
|
||||
{
|
||||
auto current_file = LOCATION_FILE (invoc_locus);
|
||||
|
@ -418,7 +417,7 @@ MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &)
|
|||
return AST::Fragment ({file_str}, std::move (str_token));
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::column_handler (location_t invoc_locus, AST::MacroInvocData &)
|
||||
{
|
||||
auto current_column = LOCATION_COLUMN (invoc_locus);
|
||||
|
@ -436,7 +435,7 @@ MacroBuiltin::column_handler (location_t invoc_locus, AST::MacroInvocData &)
|
|||
of the given file as reference to a byte array. Yields an expression of type
|
||||
&'static [u8; N]. */
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::include_bytes_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -496,7 +495,7 @@ MacroBuiltin::include_bytes_handler (location_t invoc_locus,
|
|||
of the given file as a string. The file must be UTF-8 encoded. Yields an
|
||||
expression of type &'static str. */
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::include_str_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -581,7 +580,7 @@ MacroBuiltin::include_str_handler (location_t invoc_locus,
|
|||
|
||||
/* Expand builtin macro compile_error!("error"), which forces a compile error
|
||||
during the compile time. */
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::compile_error_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -642,7 +641,7 @@ MacroBuiltin::compile_error_handler (location_t invoc_locus,
|
|||
// invocation?
|
||||
// Do we split the two passes of parsing the token tree and then expanding it?
|
||||
// Can we do that easily?
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::concat_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -707,7 +706,7 @@ MacroBuiltin::concat_handler (location_t invoc_locus,
|
|||
|
||||
/* Expand builtin macro env!(), which inspects an environment variable at
|
||||
compile time. */
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
|
||||
{
|
||||
auto invoc_token_tree = invoc.get_delim_tok_tree ();
|
||||
|
@ -781,7 +780,7 @@ MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
|
|||
return AST::Fragment ({node}, std::move (tok));
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
|
||||
{
|
||||
// only parse if not already parsed
|
||||
|
@ -823,7 +822,7 @@ MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
|
|||
/* Expand builtin macro include!(), which includes a source file at the current
|
||||
scope compile time. */
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::include_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -893,7 +892,7 @@ MacroBuiltin::include_handler (location_t invoc_locus,
|
|||
return AST::Fragment (nodes, std::vector<std::unique_ptr<AST::Token>> ());
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &)
|
||||
{
|
||||
auto current_line = LOCATION_LINE (invoc_locus);
|
||||
|
@ -908,7 +907,7 @@ MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &)
|
|||
return AST::Fragment ({line_no}, std::move (tok));
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::stringify_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
@ -938,7 +937,7 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
|
|||
return AST::Fragment ({node}, std::move (token));
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc)
|
||||
{
|
||||
rust_sorry_at (invoc_locus, "unimplemented builtin macro: %qs",
|
||||
|
@ -947,7 +946,7 @@ MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc)
|
|||
return AST::Fragment::create_error ();
|
||||
}
|
||||
|
||||
AST::Fragment
|
||||
tl::optional<AST::Fragment>
|
||||
MacroBuiltin::proc_macro_builtin (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc)
|
||||
{
|
||||
|
|
|
@ -118,52 +118,52 @@ class MacroBuiltin
|
|||
{
|
||||
public:
|
||||
static const BiMap<std::string, BuiltinMacro> builtins;
|
||||
static std::unordered_map<std::string, std::function<AST::Fragment (
|
||||
location_t, AST::MacroInvocData &)>>
|
||||
static std::unordered_map<std::string, AST::MacroTranscriberFunc>
|
||||
builtin_transcribers;
|
||||
|
||||
static AST::Fragment assert_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
static tl::optional<AST::Fragment>
|
||||
assert_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment file_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
static tl::optional<AST::Fragment> file_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment column_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
static tl::optional<AST::Fragment>
|
||||
column_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment include_bytes_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
static tl::optional<AST::Fragment>
|
||||
include_bytes_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment include_str_handler (location_t invoc_locus,
|
||||
static tl::optional<AST::Fragment>
|
||||
include_str_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment>
|
||||
stringify_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment>
|
||||
compile_error_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment>
|
||||
concat_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment> env_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment> cfg_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment>
|
||||
include_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment> line_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static tl::optional<AST::Fragment> sorry (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment stringify_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment compile_error_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment concat_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment env_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment cfg_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment include_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment line_handler (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
static AST::Fragment sorry (location_t invoc_locus,
|
||||
AST::MacroInvocData &invoc);
|
||||
|
||||
/* Builtin procedural macros do not work directly on tokens, but still need a
|
||||
* builtin transcriber to be considered proper builtin macros */
|
||||
static AST::Fragment proc_macro_builtin (location_t, AST::MacroInvocData &);
|
||||
static tl::optional<AST::Fragment> proc_macro_builtin (location_t,
|
||||
AST::MacroInvocData &);
|
||||
};
|
||||
} // namespace Rust
|
||||
|
||||
|
|
|
@ -286,7 +286,8 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon)
|
|||
|
||||
if (rules_def->is_builtin ())
|
||||
fragment
|
||||
= rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data);
|
||||
= rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data)
|
||||
.value_or (AST::Fragment::create_empty ());
|
||||
else
|
||||
fragment = expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def,
|
||||
has_semicolon);
|
||||
|
|
Loading…
Add table
Reference in a new issue