Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [RFA] Add support for __VA_OPT__
Date: Mon, 18 Sep 2017 02:42:00 -0000	[thread overview]
Message-ID: <20170918024223.5607-1-tom@tromey.com> (raw)

C++2a adds a "__VA_OPT__" feature that can be used to control the
pesky "," emission when the final (variable) argument of a variadic
macro is empty.  This patch implements this feature for gdb.  (A patch
to implement it for gcc is pending.)

gdb/ChangeLog
2017-09-17  Tom Tromey  <tom@tromey.com>

	* macroexp.c (get_next_token_for_substitution): New function.
	(substitute_args): Call it.  Check for __VA_OPT__.

gdb/testsuite/ChangeLog
2017-09-17  Tom Tromey  <tom@tromey.com>

	* gdb.base/macscp.exp: Add __VA_OPT__ tests.
---
 gdb/ChangeLog                     |  5 +++
 gdb/macroexp.c                    | 73 +++++++++++++++++++++++++++++++++++----
 gdb/testsuite/ChangeLog           |  4 +++
 gdb/testsuite/gdb.base/macscp.exp | 12 +++++++
 4 files changed, 87 insertions(+), 7 deletions(-)

diff --git a/gdb/macroexp.c b/gdb/macroexp.c
index e7a0dad..369fc78 100644
--- a/gdb/macroexp.c
+++ b/gdb/macroexp.c
@@ -946,6 +946,22 @@ find_parameter (const struct macro_buffer *tok,
   return -1;
 }
  
+/* Helper function for substitute_args that gets the next token and
+   updates the passed-in state variables.  */
+
+static int
+get_next_token_for_substitution (struct macro_buffer *replacement_list,
+				 struct macro_buffer *token,
+				 char **start,
+				 struct macro_buffer *lookahead,
+				 char **lookahead_start)
+{
+  *token = *lookahead;
+  *start = *lookahead_start;
+  *lookahead_start = replacement_list->text;
+  return get_token (lookahead, replacement_list);
+}
+
 /* Given the macro definition DEF, being invoked with the actual
    arguments given by ARGC and ARGV, substitute the arguments into the
    replacement list, and store the result in DEST.
@@ -996,8 +1012,57 @@ substitute_args (struct macro_buffer *dest,
   lookahead_rl_start = replacement_list.text;
   lookahead_valid = get_token (&lookahead, &replacement_list);
 
-  for (;;)
+  /* __VA_OPT__ state variable.  The states are:
+     0 - nothing happening
+     1 - saw __VA_OPT__
+     >= 2 in __VA_OPT__, the value encodes the parenthesis depth.  */
+  unsigned vaopt_state = 0;
+
+  for (;;
+       lookahead_valid = get_next_token_for_substitution (&replacement_list,
+							  &tok,
+							  &original_rl_start,
+							  &lookahead,
+							  &lookahead_rl_start))
     {
+      if (vaopt_state > 0)
+	{
+	  if (tok.len == 1)
+	    {
+	      if (tok.text[0] == '(')
+		{
+		  ++vaopt_state;
+		  /* We just entered __VA_OPT__, so don't emit this
+		     token.  */
+		  continue;
+		}
+	      else if (tok.text[0] == ')')
+		{
+		  --vaopt_state;
+		  if (vaopt_state == 1)
+		    {
+		      /* Done with __VA_OPT__.  */
+		      vaopt_state = 0;
+		      /* Don't emit.  */
+		      continue;
+		    }
+		}
+	    }
+
+	  /* If __VA_ARGS__ is empty, then drop the contents of
+	     __VA_OPT__.  */
+	  if (argv[argc - 1].len == 0)
+	    continue;
+	}
+      else if (is_varargs
+	       && tok.len == 10
+	       && strncmp (tok.text, "__VA_OPT__", 10) == 0)
+	{
+	  vaopt_state = 1;
+	  /* Don't emit this token.  */
+	  continue;
+	}
+
       /* Just for aesthetics.  If we skipped some whitespace, copy
          that to DEST.  */
       if (tok.text > original_rl_start)
@@ -1160,12 +1225,6 @@ substitute_args (struct macro_buffer *dest,
 
       if (! lookahead_valid)
 	break;
-
-      tok = lookahead;
-      original_rl_start = lookahead_rl_start;
-
-      lookahead_rl_start = replacement_list.text;
-      lookahead_valid = get_token (&lookahead, &replacement_list);
     }
 }
 
diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index 54b5ab2..a08ec46 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -620,6 +620,10 @@ gdb_test_no_output "macro define va_gnu(args...) varfunc (fixedarg, args)" \
 gdb_test_no_output "macro define va2_gnu(args...) varfunc (fixedarg, ## args)" \
   "define fourth varargs helper"
 
+gdb_test_no_output \
+    "macro define va3_cxx2a(x, ...) varfunc (x __VA_OPT__(,) __VA_ARGS__)" \
+    "define fifth varargs helper"
+
 gdb_test "macro expand va_c99(one, two, three)" \
   "expands to: *varfunc \\(fixedarg, *one, two, three\\)" \
   "c99 varargs expansion"
@@ -644,6 +648,14 @@ gdb_test "macro expand va2_gnu()" \
   "expands to: *varfunc \\(fixedarg\\)" \
   "gnu varargs expansion special splicing without an argument"
 
+gdb_test "macro expand va3_cxx2a(23)" \
+    "expands to: *varfunc \\(23 \\)" \
+    "C++2a __VA_OPT__ handling without variable argument"
+
+gdb_test "macro expand va3_cxx2a(23, 24, 25)" \
+    "expands to: *varfunc \\(23, 24, 25\\)" \
+    "C++2a __VA_OPT__ handling with variable argument"
+
 # Stringification tests.
 
 gdb_test_no_output "macro define str(x) #x" \
-- 
2.9.4


             reply	other threads:[~2017-09-18  2:42 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-18  2:42 Tom Tromey [this message]
2017-09-20 16:43 ` Pedro Alves
2017-09-21  3:42   ` Tom Tromey
2017-09-21  9:01     ` Pedro Alves
2017-09-23  3:03       ` Tom Tromey
2017-09-27 11:32         ` Pedro Alves
2017-09-27 14:19           ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170918024223.5607-1-tom@tromey.com \
    --to=tom@tromey.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox