aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2023-01-18 12:23:03 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2023-02-08 12:02:41 +0100
commitb9501cbe2624a80365e33550fc92035620a64e7b (patch)
tree2c614cb8667353d323ad6c5c04305d20e5af08bb /gcc/rust
parentb1de4bb869845c6c7dadbc1cf84626e922e80ab9 (diff)
downloadgcc-b9501cbe2624a80365e33550fc92035620a64e7b.zip
gcc-b9501cbe2624a80365e33550fc92035620a64e7b.tar.gz
gcc-b9501cbe2624a80365e33550fc92035620a64e7b.tar.bz2
macro: Allow builtin `MacroInvocation`s within the AST
This commit turns AST::MacroInvocation into a sum type. The class can now represent a regular macro invocation (lazily expanded) or a builtin one (eagerly expanded) gcc/rust/ChangeLog: * expand/rust-macro-builtins.cc (make_macro_invocation): Add short hand function for returning fragments containing macro invocations. (MacroBuiltin::compile_error_handler): Add explanation for eager invocation
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc72
1 files changed, 71 insertions, 1 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index f6ddb1a..11b5d5f 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -37,8 +37,39 @@ make_string (Location locus, std::string value)
PrimitiveCoreType::CORETYPE_STR, {}, locus));
}
-/* Match the end token of a macro given the start delimiter of the macro */
+// TODO: Is this correct?
+static std::unique_ptr<AST::Expr>
+make_macro_invocation (AST::BuiltinMacro kind, AST::DelimTokenTree arguments)
+{
+ std::string path_str;
+
+ switch (kind)
+ {
+ case AST::BuiltinMacro::Assert:
+ case AST::BuiltinMacro::File:
+ case AST::BuiltinMacro::Line:
+ case AST::BuiltinMacro::Column:
+ case AST::BuiltinMacro::IncludeBytes:
+ case AST::BuiltinMacro::IncludeStr:
+ case AST::BuiltinMacro::CompileError:
+ case AST::BuiltinMacro::Concat:
+ path_str = "concat";
+ break;
+ case AST::BuiltinMacro::Env:
+ case AST::BuiltinMacro::Cfg:
+ case AST::BuiltinMacro::Include:
+ break;
+ }
+ return AST::MacroInvocation::builtin (
+ kind,
+ AST::MacroInvocData (AST::SimplePath (
+ {AST::SimplePathSegment (path_str, Location ())}),
+ std::move (arguments)),
+ {}, Location ());
+}
+
+/* Match the end token of a macro given the start delimiter of the macro */
static inline TokenId
macro_end_token (AST::DelimTokenTree &invoc_token_tree,
Parser<MacroInvocLexer> &parser)
@@ -386,6 +417,45 @@ MacroBuiltin::compile_error_handler (Location invoc_locus,
/* Expand builtin macro concat!(), which joins all the literal parameters
into a string with no delimiter. */
+// This is a weird one. We want to do something where, if something cannot be
+// expanded yet (i.e. macro invocation?) we return the whole MacroInvocation
+// node again but expanded as much as possible.
+// Is that possible? How do we do that?
+//
+// Let's take a few examples:
+//
+// 1. concat!(1, 2, true);
+// 2. concat!(a!(), 2, true);
+// 3. concat!(concat!(1, false), 2, true);
+// 4. concat!(concat!(1, a!()), 2, true);
+//
+// 1. We simply want to return the new fragment: "12true"
+// 2. We want to return `concat!(a_expanded, 2, true)` as a fragment
+// 3. We want to return `concat!(1, false, 2, true)`
+// 4. We want to return `concat!(concat!(1, a_expanded), 2, true);
+//
+// How do we do that?
+//
+// For each (un)expanded fragment: we check if it is expanded fully
+//
+// 1. What is expanded fully?
+// 2. How to check?
+//
+// If it is expanded fully and not a literal, then we error out.
+// Otherwise we simply emplace it back and keep going.
+//
+// In the second case, we must mark that this concat invocation still has some
+// expansion to do: This allows us to return a `MacroInvocation { ... }` as an
+// AST fragment, instead of a completed string.
+//
+// This means that we must change all the `try_expand_many_*` APIs and so on to
+// return some sort of index or way to signify that we might want to reuse some
+// bits and pieces of the original token tree.
+//
+// Now, before that: How do we resolve the names used in a builtin macro
+// invocation?
+// Do we split the two passes of parsing the token tree and then expanding it?
+// Can we do that easily?
AST::Fragment
MacroBuiltin::concat_handler (Location invoc_locus, AST::MacroInvocData &invoc)
{