From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 10A1038493C9; Mon, 13 Feb 2023 12:02:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 10A1038493C9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676289720; bh=SQM4n/5vAEP49gVVqapHgvpEEC/EPrUfOLEDRTFPq6M=; h=From:To:Subject:Date:From; b=pZ5E7wwd3Xh0blUjBSKWQQOOtqFk5zODvopiTYN+b72ejUZH7msTvxSbHWupXt9WE Ku/I+VJ3M5EJMpjpKTxLM6qcENcYi0GvPoIXqt2JiZM/bh+c2spbb8TZMEceaUxQud u1tmCkY4/WpcQ7wfSjo3KCraWTbEhYnoenaGL5Bc= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] macro: Allow builtin `MacroInvocation`s within the AST X-Act-Checkin: gcc X-Git-Author: Arthur Cohen X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: b1de4bb869845c6c7dadbc1cf84626e922e80ab9 X-Git-Newrev: b9501cbe2624a80365e33550fc92035620a64e7b Message-Id: <20230213120200.10A1038493C9@sourceware.org> Date: Mon, 13 Feb 2023 12:02:00 +0000 (GMT) List-Id: https://gcc.gnu.org/g:b9501cbe2624a80365e33550fc92035620a64e7b commit b9501cbe2624a80365e33550fc92035620a64e7b Author: Arthur Cohen Date: Wed Jan 18 12:23:03 2023 +0100 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 Diff: --- gcc/rust/expand/rust-macro-builtins.cc | 72 +++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index f6ddb1a803e..11b5d5fbc9d 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 +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 &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) {