Skip to content

Commit

Permalink
gccrs: use tl::optional for macro transcribers
Browse files Browse the repository at this point in the history
refs #2421.

gcc/rust/ChangeLog:

	* ast/rust-ast-fragment.cc (Fragment::create_empty): New.
	* ast/rust-ast-fragment.h (std::function<tl::optional): New.
	* ast/rust-macro.h (MacroRulesDefinition): Use transcriber_t.
	* 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
	transcriber_t.
	(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 <[email protected]>
  • Loading branch information
dkm committed Jul 27, 2023
1 parent 1bc8f08 commit f765177
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 54 deletions.
6 changes: 6 additions & 0 deletions gcc/rust/ast/rust-ast-fragment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
13 changes: 13 additions & 0 deletions gcc/rust/ast/rust-ast-fragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class Fragment
*/
static Fragment create_error ();

/**
* Create an empty fragment
*/
static Fragment create_empty ();

/**
* Create a complete AST fragment
*/
Expand Down Expand Up @@ -117,6 +122,14 @@ class Fragment
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 transcriber_t
= std::function<tl::optional<Fragment> (location_t, MacroInvocData &)>;

} // namespace AST
} // namespace Rust

Expand Down
14 changes: 6 additions & 8 deletions gcc/rust/ast/rust-macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ class MacroRulesDefinition : public VisItem
std::vector<MacroRule> rules; // inlined form
location_t locus;

std::function<Fragment (location_t, MacroInvocData &)> associated_transcriber;
transcriber_t associated_transcriber;

// Since we can't compare std::functions, we need to use an extra boolean
bool is_builtin_rule;
MacroKind kind;
Expand Down Expand Up @@ -503,9 +504,8 @@ class MacroRulesDefinition : public VisItem
{}

MacroRulesDefinition (Identifier builtin_name, DelimType delim_type,
std::function<Fragment (location_t, MacroInvocData &)>
associated_transcriber,
MacroKind kind, Visibility vis)
transcriber_t associated_transcriber, MacroKind kind,
Visibility vis)
: VisItem (std::move (vis), std::vector<Attribute> ()),
outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name),
delim_type (delim_type), rules (std::vector<MacroRule> ()),
Expand Down Expand Up @@ -560,14 +560,12 @@ class MacroRulesDefinition : public VisItem
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 transcriber_t &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 (transcriber_t transcriber)
{
associated_transcriber = transcriber;
is_builtin_rule = true;
Expand Down
31 changes: 15 additions & 16 deletions gcc/rust/expand/rust-macro-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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::transcriber_t>
MacroBuiltin::builtin_transcribers = {
{"assert", MacroBuiltin::assert_handler},
{"file", MacroBuiltin::file_handler},
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 ();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down Expand Up @@ -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",
Expand All @@ -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)
{
Expand Down
58 changes: 29 additions & 29 deletions gcc/rust/expand/rust-macro-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::transcriber_t>
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,
AST::MacroInvocData &invoc);
static tl::optional<AST::Fragment>
include_str_handler (location_t invoc_locus, AST::MacroInvocData &invoc);

static AST::Fragment stringify_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);
static tl::optional<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 tl::optional<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 tl::optional<AST::Fragment>
concat_handler (location_t invoc_locus, AST::MacroInvocData &invoc);

static AST::Fragment env_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);
static tl::optional<AST::Fragment> env_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);

static AST::Fragment cfg_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);
static tl::optional<AST::Fragment> cfg_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);

static AST::Fragment include_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);
static tl::optional<AST::Fragment>
include_handler (location_t invoc_locus, AST::MacroInvocData &invoc);

static AST::Fragment line_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);
static tl::optional<AST::Fragment> line_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);

static AST::Fragment sorry (location_t invoc_locus,
AST::MacroInvocData &invoc);
static tl::optional<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

Expand Down
3 changes: 2 additions & 1 deletion gcc/rust/expand/rust-macro-expand.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit f765177

Please sign in to comment.