diff options
author | Jason Merrill <jason@redhat.com> | 2021-09-01 21:33:30 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-09-01 21:33:30 +0200 |
commit | ac6e77aacfb6581f5e84e4430628152b9b98da2e (patch) | |
tree | 860c5cb23c00a1c5fe42194176931811d9f698e8 | |
parent | e928cf47f350e46eacb48ed954112e603ef3800a (diff) | |
download | gcc-ac6e77aacfb6581f5e84e4430628152b9b98da2e.tar.gz |
libcpp: __VA_OPT__ tweak
> We want to remove the latter <placemarker> but not the former one, and
> the patch adds the vaopt_padding_tokens counter for it to control
> how many placemarkers are removed on vaopt_state::END.
> As can be seen in #c1 and #c2 of the PR, I've tried various approaches,
> but neither worked out for all the cases except the posted one.
I notice that the second placemarker you mention is avoid_paste, which seems
relevant. This seems to also work, at least it doesn't seem to break any of
the va_opt tests.
2021-09-01 Jason Merrill <jason@redhat.com>
* macro.c (replace_args): When __VA_OPT__ is on the LHS of ##,
remove trailing avoid_paste tokens.
-rw-r--r-- | libcpp/macro.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/libcpp/macro.c b/libcpp/macro.c index b3ba352ae09..f214548de1e 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -2026,7 +2026,6 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, i = 0; vaopt_state vaopt_tracker (pfile, macro->variadic, &args[macro->paramc - 1]); const cpp_token **vaopt_start = NULL; - unsigned vaopt_padding_tokens = 0; for (src = macro->exp.tokens; src < limit; src++) { unsigned int arg_tokens_count; @@ -2059,16 +2058,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, const cpp_token **start = vaopt_start; vaopt_start = NULL; - /* Remove any tail padding from inside the __VA_OPT__. */ paste_flag = tokens_buff_last_token_ptr (buff); - while (vaopt_padding_tokens-- - && paste_flag - && paste_flag != start - && (*paste_flag)->type == CPP_PADDING) - { - tokens_buff_remove_last_token (buff); - paste_flag = tokens_buff_last_token_ptr (buff); - } if (vaopt_tracker.stringify ()) { @@ -2089,6 +2079,14 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, } else if (src->flags & PASTE_LEFT) { + /* Don't avoid paste after all. */ + while (paste_flag && paste_flag != start + && *paste_flag == &pfile->avoid_paste) + { + tokens_buff_remove_last_token (buff); + paste_flag = tokens_buff_last_token_ptr (buff); + } + /* With a non-empty __VA_OPT__ on the LHS of ##, the last token should be flagged PASTE_LEFT. */ if (paste_flag && (*paste_flag)->type != CPP_PADDING) @@ -2107,7 +2105,6 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, continue; } - vaopt_padding_tokens = 0; if (src->type != CPP_MACRO_ARG) { /* Allocate a virtual location for token SRC, and add that @@ -2263,10 +2260,6 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, index = expanded_token_index (pfile, macro, src, token_index); const cpp_token *tok = macro_arg_token_iter_get_token (&from); - if (tok->type == CPP_PADDING) - vaopt_padding_tokens++; - else - vaopt_padding_tokens = 0; tokens_buff_add_token (buff, virt_locs, tok, macro_arg_token_iter_get_location (&from), src->src_loc, map, index); @@ -2313,7 +2306,6 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, tokens_buff_add_token (buff, virt_locs, t, t->src_loc, t->src_loc, NULL, 0); - vaopt_padding_tokens++; } /* Add a new paste flag, or remove an unwanted one. */ |