From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id C6B8C380F3CF; Wed, 8 Jun 2022 12:16:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C6B8C380F3CF 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] macros: Parse macro patterns properly in repetition X-Act-Checkin: gcc X-Git-Author: Arthur Cohen X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 865b6090a8f8981cdfc050ea2ee44abbe92de141 X-Git-Newrev: 08b7516191a62e53819e24d08f2a413c84cf4925 Message-Id: <20220608121617.C6B8C380F3CF@sourceware.org> Date: Wed, 8 Jun 2022 12:16:17 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2022 12:16:17 -0000 https://gcc.gnu.org/g:08b7516191a62e53819e24d08f2a413c84cf4925 commit 08b7516191a62e53819e24d08f2a413c84cf4925 Author: Arthur Cohen Date: Mon Mar 7 12:27:30 2022 +0100 macros: Parse macro patterns properly in repetition Co-authored-by: philberty Diff: --- gcc/rust/expand/rust-macro-substitute-ctx.cc | 68 +++++++++++++++++++--------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc index f9f2005b72b..61ab626f101 100644 --- a/gcc/rust/expand/rust-macro-substitute-ctx.cc +++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc @@ -39,9 +39,6 @@ SubstituteCtx::substitute_repetition ( { rust_assert (pattern_end < macro.size ()); - rust_debug ("pattern start: %lu", pattern_start); - rust_debug ("pattern end: %lu", pattern_end); - std::vector> expanded; // Find the first fragment and get the amount of repetitions that we should @@ -154,19 +151,57 @@ SubstituteCtx::substitute_token (size_t token_idx) // We need to parse up until the closing delimiter and expand this // fragment->n times. rust_debug ("expanding repetition"); - std::vector> repetition_pattern; + + // We're in a context where macro repetitions have already been + // parsed and validated: This means that + // 1/ There will be no delimiters as that is an error + // 2/ There are no fragment specifiers anymore, which prevents us + // from reusing parser functions. + // + // Repetition patterns are also special in that they cannot contain + // "rogue" delimiters: For example, this is invalid, as they are + // parsed as MacroMatches and must contain a correct amount of + // delimiters. + // `$($e:expr ) )` + // ^ rogue closing parenthesis + // + // With all of that in mind, we can simply skip ahead from one + // parenthesis to the other to find the pattern to expand. Of course, + // pairs of delimiters, including parentheses, are allowed. + // `$($e:expr ( ) )` + // Parentheses are the sole delimiter for which we need a special + // behavior since they delimit the repetition pattern + size_t pattern_start = token_idx + 1; size_t pattern_end = pattern_start; - for (; pattern_end < macro.size () - && macro.at (pattern_end)->get_id () != RIGHT_PAREN; - pattern_end++) - ; + auto parentheses_stack = 0; + for (size_t idx = pattern_start; idx < macro.size (); idx++) + { + if (macro.at (idx)->get_id () == LEFT_PAREN) + { + parentheses_stack++; + } + else if (macro.at (idx)->get_id () == RIGHT_PAREN) + { + if (parentheses_stack == 0) + { + pattern_end = idx; + break; + } + parentheses_stack--; + } + } + + // Unreachable case, but let's make sure we don't ever run into it + rust_assert (pattern_end != pattern_start); std::unique_ptr separator_token = nullptr; - // FIXME: Can this go out of bounds? - auto &post_pattern_token = macro.at (pattern_end + 1); - if (!is_rep_op (post_pattern_token)) - separator_token = post_pattern_token->clone_token (); + if (pattern_end + 1 <= macro.size ()) + { + auto &post_pattern_token = macro.at (pattern_end + 1); + if (!is_rep_op (post_pattern_token)) + separator_token = post_pattern_token->clone_token (); + } // Amount of tokens to skip auto to_skip = 0; @@ -178,15 +213,6 @@ SubstituteCtx::substitute_token (size_t token_idx) if (separator_token) to_skip += 1; - // FIXME: This skips whitespaces... Is that okay?? - // FIXME: Is there any existing parsing function that allows us to - // parse a macro pattern? - - // FIXME: Add error handling in the case we haven't found a matching - // closing delimiter - - // FIXME: We need to parse the repetition token now - return {substitute_repetition (pattern_start, pattern_end, std::move (separator_token)), pattern_end - pattern_start + to_skip};