Skip to content

Commit 48b3fe6

Browse files
committed
macros: Add optional builtin transcribers to MacroRulesDefinition
1 parent 0b46175 commit 48b3fe6

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

gcc/rust/ast/rust-macro.h

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,26 @@ class MacroRulesDefinition : public MacroItem
361361
DelimType delim_type;
362362
// MacroRules rules;
363363
std::vector<MacroRule> rules; // inlined form
364-
365364
Location locus;
366365

366+
std::function<ASTFragment (Location, MacroInvocData &)>
367+
associated_transcriber;
368+
// Since we can't compare std::functions, we need to use an extra boolean
369+
bool is_builtin_rule;
370+
371+
/**
372+
* Default function to use as an associated transcriber. This function should
373+
* never be called, hence the gcc_unreachable().
374+
* If this function is used, then the macro is not builtin and the compiler
375+
* should make use of the actual rules. If the macro is builtin, then another
376+
* associated transcriber should be used
377+
*/
378+
static ASTFragment dummy_builtin (Location, MacroInvocData &)
379+
{
380+
gcc_unreachable ();
381+
return ASTFragment::create_empty ();
382+
}
383+
367384
/* NOTE: in rustc, macro definitions are considered (and parsed as) a type
368385
* of macro, whereas here they are considered part of the language itself.
369386
* I am not aware of the implications of this decision. The rustc spec does
@@ -377,7 +394,17 @@ class MacroRulesDefinition : public MacroItem
377394
std::vector<MacroRule> rules,
378395
std::vector<Attribute> outer_attrs, Location locus)
379396
: outer_attrs (std::move (outer_attrs)), rule_name (std::move (rule_name)),
380-
delim_type (delim_type), rules (std::move (rules)), locus (locus)
397+
delim_type (delim_type), rules (std::move (rules)), locus (locus),
398+
associated_transcriber (dummy_builtin), is_builtin_rule (false)
399+
{}
400+
401+
MacroRulesDefinition (Identifier builtin_name, DelimType delim_type,
402+
std::function<ASTFragment (Location, MacroInvocData &)>
403+
associated_transcriber)
404+
: outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name),
405+
delim_type (delim_type), rules (std::vector<MacroRule> ()),
406+
locus (Location ()), associated_transcriber (associated_transcriber),
407+
is_builtin_rule (true)
381408
{}
382409

383410
void accept_vis (ASTVisitor &vis) override;
@@ -400,6 +427,20 @@ class MacroRulesDefinition : public MacroItem
400427
std::vector<MacroRule> &get_rules () { return rules; }
401428
const std::vector<MacroRule> &get_rules () const { return rules; }
402429

430+
bool is_builtin () const { return is_builtin_rule; }
431+
const std::function<ASTFragment (Location, MacroInvocData &)> &
432+
get_builtin_transcriber () const
433+
{
434+
rust_assert (is_builtin ());
435+
return associated_transcriber;
436+
}
437+
void set_builtin_transcriber (
438+
std::function<ASTFragment (Location, MacroInvocData &)> transcriber)
439+
{
440+
associated_transcriber = transcriber;
441+
is_builtin_rule = true;
442+
}
443+
403444
protected:
404445
/* Use covariance to implement clone function as returning this object rather
405446
* than base */

gcc/rust/expand/rust-macro-expand.cc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,8 +3194,14 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc)
31943194
bool ok = mappings->lookup_macro_def (resolved_node, &rules_def);
31953195
rust_assert (ok);
31963196

3197-
auto fragment
3198-
= expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, false);
3197+
auto fragment = AST::ASTFragment::create_empty ();
3198+
3199+
if (rules_def->is_builtin ())
3200+
fragment
3201+
= rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data);
3202+
else
3203+
fragment
3204+
= expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, false);
31993205

32003206
// lets attach this fragment to the invocation
32013207
invoc.set_fragment (std::move (fragment));
@@ -3229,8 +3235,14 @@ MacroExpander::expand_invoc_semi (AST::MacroInvocationSemi &invoc)
32293235
bool ok = mappings->lookup_macro_def (resolved_node, &rules_def);
32303236
rust_assert (ok);
32313237

3232-
auto fragment
3233-
= expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, true);
3238+
auto fragment = AST::ASTFragment::create_empty ();
3239+
3240+
if (rules_def->is_builtin ())
3241+
fragment
3242+
= rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data);
3243+
else
3244+
fragment
3245+
= expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, true);
32343246

32353247
// lets attach this fragment to the invocation
32363248
invoc.set_fragment (std::move (fragment));

gcc/rust/util/rust-hir-map.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "rust-hir-map.h"
2020
#include "rust-ast-full.h"
2121
#include "rust-hir-full.h"
22+
#include "rust-macro-builtins.h"
2223

2324
namespace Rust {
2425
namespace Analysis {
@@ -741,6 +742,16 @@ Mappings::iterate_trait_items (
741742
void
742743
Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
743744
{
745+
static std::map<std::string, std::function<AST::ASTFragment (
746+
Location, AST::MacroInvocData &)>>
747+
builtin_macros = {
748+
{"assert", MacroBuiltin::assert},
749+
};
750+
751+
auto builtin = builtin_macros.find (macro->get_rule_name ());
752+
if (builtin != builtin_macros.end ())
753+
macro->set_builtin_transcriber (builtin->second);
754+
744755
auto it = macroMappings.find (macro->get_node_id ());
745756
rust_assert (it == macroMappings.end ());
746757

0 commit comments

Comments
 (0)