diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2023-01-18 12:23:03 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2023-02-08 12:02:41 +0100 |
commit | b9501cbe2624a80365e33550fc92035620a64e7b (patch) | |
tree | 2c614cb8667353d323ad6c5c04305d20e5af08bb /gcc/rust | |
parent | b1de4bb869845c6c7dadbc1cf84626e922e80ab9 (diff) | |
download | gcc-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.cc | 72 |
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) { |