public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add C parser support for "restrict" and "_Atomic"
@ 2020-03-01  3:01 Tom Tromey
  2020-03-01 16:16 ` Ruslan Kabatsayev
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2020-03-01  3:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

A user noticed that "watch -location" would fail with a "restrict"
pointer.  The issue here is that if the DWARF mentions "restrict", gdb
will put this into the type name -- but then the C parser will not be
able to parse this type.

This patch adds support for "restrict" and "_Atomic" to the C parser.
It is done only for C and Objective C, not C++.

I wasn't sure if "restrict" should be marked FLAG_SHADOW to support
older dialects of C, where this was not a keyword.

gdb/ChangeLog
2020-02-29  Tom Tromey  <tom@tromey.com>

	* type-stack.h (enum type_pieces) <tp_atomic, tp_restrict>: New
	constants.
	* type-stack.c (type_stack::insert): Handle tp_atomic and
	tp_restrict.
	(type_stack::follow_type_instance_flags): Likewise.
	(type_stack::follow_types): Likewise.  Merge type-following code.
	* c-exp.y (RESTRICT, ATOMIC): New tokens.
	(space_identifier, cv_with_space_id)
	(const_or_volatile_or_space_identifier_noopt)
	(const_or_volatile_or_space_identifier): Remove.
	(single_qualifier, qualifier_seq_noopt, qualifier_seq): New
	rules.
	(ptr_operator, typebase): Update.
	(enum token_flag) <FLAG_C>: New constant.
	(ident_tokens): Add "restrict" and "_Atomic".
	(lex_one_token): Handle FLAG_C.

gdb/testsuite/ChangeLog
2020-02-29  Tom Tromey  <tom@tromey.com>

	* gdb.base/cvexpr.exp: Add test for _Atomic and restrict.
---
 gdb/ChangeLog                     | 19 ++++++++
 gdb/c-exp.y                       | 52 ++++++++++++++-------
 gdb/testsuite/ChangeLog           |  4 ++
 gdb/testsuite/gdb.base/cvexpr.exp |  4 ++
 gdb/type-stack.c                  | 76 +++++++++++++++----------------
 gdb/type-stack.h                  |  2 +
 6 files changed, 101 insertions(+), 56 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 3403a857a83..1b35ef2e60a 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -237,6 +237,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
 %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
+%token RESTRICT ATOMIC
 
 %token <sval> DOLLAR_VARIABLE
 
@@ -1169,36 +1170,43 @@ variable:	name_not_typename
 			}
 	;
 
-space_identifier : '@' NAME
-		{
-		  cpstate->type_stack.insert (pstate,
-					      copy_name ($2.stoken).c_str ());
-		}
-	;
-
 const_or_volatile: const_or_volatile_noopt
 	|
 	;
 
-cv_with_space_id : const_or_volatile space_identifier const_or_volatile
+single_qualifier:
+		CONST_KEYWORD
+			{ cpstate->type_stack.insert (tp_const); }
+	| 	VOLATILE_KEYWORD
+			{ cpstate->type_stack.insert (tp_volatile); }
+	| 	ATOMIC
+			{ cpstate->type_stack.insert (tp_atomic); }
+	| 	RESTRICT
+			{ cpstate->type_stack.insert (tp_restrict); }
+	|	'@' NAME
+		{
+		  cpstate->type_stack.insert (pstate,
+					      copy_name ($2.stoken).c_str ());
+		}
 	;
 
-const_or_volatile_or_space_identifier_noopt: cv_with_space_id
-	| const_or_volatile_noopt
+qualifier_seq_noopt:
+		single_qualifier
+	| 	qualifier_seq single_qualifier
 	;
 
-const_or_volatile_or_space_identifier:
-		const_or_volatile_or_space_identifier_noopt
+qualifier_seq:
+		qualifier_seq_noopt
 	|
 	;
 
 ptr_operator:
 		ptr_operator '*'
 			{ cpstate->type_stack.insert (tp_pointer); }
-		const_or_volatile_or_space_identifier
+		qualifier_seq
 	|	'*'
 			{ cpstate->type_stack.insert (tp_pointer); }
-		const_or_volatile_or_space_identifier
+		qualifier_seq
 	|	'&'
 			{ cpstate->type_stack.insert (tp_reference); }
 	|	'&' ptr_operator
@@ -1472,9 +1480,9 @@ typebase
 			    (copy_name($2).c_str (), $4,
 			     pstate->expression_context_block);
 			}
-	| const_or_volatile_or_space_identifier_noopt typebase
+	|	qualifier_seq_noopt typebase
 			{ $$ = cpstate->type_stack.follow_types ($2); }
-	| typebase const_or_volatile_or_space_identifier_noopt
+	|	typebase qualifier_seq_noopt
 			{ $$ = cpstate->type_stack.follow_types ($1); }
 	;
 
@@ -2345,6 +2353,10 @@ enum token_flag
 
   FLAG_CXX = 1,
 
+  /* If this bit is set, the token is C-only.  */
+
+  FLAG_C = 1,
+
   /* If this bit is set, the token is conditional: if there is a
      symbol of the same name, then the token is a symbol; otherwise,
      the token is a keyword.  */
@@ -2416,6 +2428,8 @@ static const struct token ident_tokens[] =
     {"union", UNION, OP_NULL, 0},
     {"short", SHORT, OP_NULL, 0},
     {"const", CONST_KEYWORD, OP_NULL, 0},
+    {"restrict", RESTRICT, OP_NULL, 0},
+    {"_Atomic", ATOMIC, OP_NULL, 0},
     {"enum", ENUM, OP_NULL, 0},
     {"long", LONG, OP_NULL, 0},
     {"true", TRUEKEYWORD, OP_NULL, FLAG_CXX},
@@ -2550,6 +2564,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 	if ((tokentab3[i].flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
+	gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
 
 	pstate->lexptr += 3;
 	yylval.opcode = tokentab3[i].opcode;
@@ -2563,6 +2578,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 	if ((tokentab2[i].flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
+	gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
 
 	pstate->lexptr += 2;
 	yylval.opcode = tokentab2[i].opcode;
@@ -2857,6 +2873,10 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 	if ((ident_tokens[i].flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
+	if ((ident_tokens[i].flags & FLAG_C) != 0
+	    && par_state->language ()->la_language != language_c
+	    && par_state->language ()->la_language != language_objc)
+	  break;
 
 	if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
 	  {
diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp
index 92a073a774e..cf5d2c4a553 100644
--- a/gdb/testsuite/gdb.base/cvexpr.exp
+++ b/gdb/testsuite/gdb.base/cvexpr.exp
@@ -509,3 +509,7 @@ foreach testspec $specs {
 	do_test $prefix $opts
     }
 }
+
+# These tests don't rely on the debug format.
+gdb_test "ptype _Atomic int" "type = _Atomic int"
+gdb_test "ptype int * restrict" "type = int \\* restrict"
diff --git a/gdb/type-stack.c b/gdb/type-stack.c
index ab7e0261cad..73b7d5a8dfc 100644
--- a/gdb/type-stack.c
+++ b/gdb/type-stack.c
@@ -33,12 +33,14 @@ type_stack::insert (enum type_pieces tp)
 
   gdb_assert (tp == tp_pointer || tp == tp_reference
 	      || tp == tp_rvalue_reference || tp == tp_const
-	      || tp == tp_volatile);
+	      || tp == tp_volatile || tp == tp_restrict
+	      || tp == tp_atomic);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
      push this on the top of the stack.  */
-  if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile))
+  if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile
+			       || tp == tp_restrict))
     slot = 1;
   else
     slot = 0;
@@ -88,6 +90,12 @@ type_stack::follow_type_instance_flags ()
       case tp_volatile:
 	flags |= TYPE_INSTANCE_FLAG_VOLATILE;
 	break;
+      case tp_atomic:
+	flags |= TYPE_INSTANCE_FLAG_ATOMIC;
+	break;
+      case tp_restrict:
+	flags |= TYPE_INSTANCE_FLAG_RESTRICT;
+	break;
       default:
 	gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
       }
@@ -102,6 +110,8 @@ type_stack::follow_types (struct type *follow_type)
   int make_const = 0;
   int make_volatile = 0;
   int make_addr_space = 0;
+  bool make_restrict = false;
+  bool make_atomic = false;
   int array_size;
 
   while (!done)
@@ -109,19 +119,7 @@ type_stack::follow_types (struct type *follow_type)
       {
       case tp_end:
 	done = 1;
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
-	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	goto process_qualifiers;
 	break;
       case tp_const:
 	make_const = 1;
@@ -132,41 +130,39 @@ type_stack::follow_types (struct type *follow_type)
       case tp_space_identifier:
 	make_addr_space = pop_int ();
 	break;
+      case tp_atomic:
+	make_atomic = true;
+	break;
+      case tp_restrict:
+	make_restrict = true;
+	break;
       case tp_pointer:
 	follow_type = lookup_pointer_type (follow_type);
+	goto process_qualifiers;
+      case tp_reference:
+	follow_type = lookup_lvalue_reference_type (follow_type);
+	goto process_qualifiers;
+      case tp_rvalue_reference:
+	follow_type = lookup_rvalue_reference_type (follow_type);
+      process_qualifiers:
 	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
+	  follow_type = make_cv_type (make_const,
+				      TYPE_VOLATILE (follow_type),
 				      follow_type, 0);
 	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
+	  follow_type = make_cv_type (TYPE_CONST (follow_type),
+				      make_volatile,
 				      follow_type, 0);
 	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
+	  follow_type = make_type_with_address_space (follow_type,
 						      make_addr_space);
+	if (make_restrict)
+	  follow_type = make_restrict_type (follow_type);
+	if (make_atomic)
+	  follow_type = make_atomic_type (follow_type);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
-	break;
-      case tp_reference:
-	 follow_type = lookup_lvalue_reference_type (follow_type);
-	 goto process_reference;
-	case tp_rvalue_reference:
-	 follow_type = lookup_rvalue_reference_type (follow_type);
-	process_reference:
-	 if (make_const)
-	   follow_type = make_cv_type (make_const,
-				       TYPE_VOLATILE (follow_type),
-				       follow_type, 0);
-	 if (make_volatile)
-	   follow_type = make_cv_type (TYPE_CONST (follow_type),
-				       make_volatile,
-				       follow_type, 0);
-	 if (make_addr_space)
-	   follow_type = make_type_with_address_space (follow_type,
-						       make_addr_space);
-	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	make_restrict = make_atomic = false;
 	break;
       case tp_array:
 	array_size = pop_int ();
diff --git a/gdb/type-stack.h b/gdb/type-stack.h
index ee004d1be8d..8060f2fea78 100644
--- a/gdb/type-stack.h
+++ b/gdb/type-stack.h
@@ -40,6 +40,8 @@ enum type_pieces
     tp_const, 
     tp_volatile, 
     tp_space_identifier,
+    tp_atomic,
+    tp_restrict,
     tp_type_stack,
     tp_kind
   };
-- 
2.17.2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Add C parser support for "restrict" and "_Atomic"
  2020-03-01  3:01 [PATCH] Add C parser support for "restrict" and "_Atomic" Tom Tromey
@ 2020-03-01 16:16 ` Ruslan Kabatsayev
  2020-03-04  0:39   ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Ruslan Kabatsayev @ 2020-03-01 16:16 UTC (permalink / raw)
  To: Tom Tromey; +Cc: GDB Patches

On Sun, 1 Mar 2020 at 06:01, Tom Tromey <tom@tromey.com> wrote:
>
> A user noticed that "watch -location" would fail with a "restrict"
> pointer.  The issue here is that if the DWARF mentions "restrict", gdb
> will put this into the type name -- but then the C parser will not be
> able to parse this type.
>
> This patch adds support for "restrict" and "_Atomic" to the C parser.
> It is done only for C and Objective C, not C++.

GCC has the keywords __restrict__ and __restrict that work in C++ too.
These are also affected, including the use in C++.

>
> I wasn't sure if "restrict" should be marked FLAG_SHADOW to support
> older dialects of C, where this was not a keyword.
>
> gdb/ChangeLog
> 2020-02-29  Tom Tromey  <tom@tromey.com>
>
>         * type-stack.h (enum type_pieces) <tp_atomic, tp_restrict>: New
>         constants.
>         * type-stack.c (type_stack::insert): Handle tp_atomic and
>         tp_restrict.
>         (type_stack::follow_type_instance_flags): Likewise.
>         (type_stack::follow_types): Likewise.  Merge type-following code.
>         * c-exp.y (RESTRICT, ATOMIC): New tokens.
>         (space_identifier, cv_with_space_id)
>         (const_or_volatile_or_space_identifier_noopt)
>         (const_or_volatile_or_space_identifier): Remove.
>         (single_qualifier, qualifier_seq_noopt, qualifier_seq): New
>         rules.
>         (ptr_operator, typebase): Update.
>         (enum token_flag) <FLAG_C>: New constant.
>         (ident_tokens): Add "restrict" and "_Atomic".
>         (lex_one_token): Handle FLAG_C.
>
> gdb/testsuite/ChangeLog
> 2020-02-29  Tom Tromey  <tom@tromey.com>
>
>         * gdb.base/cvexpr.exp: Add test for _Atomic and restrict.
> ---
>  gdb/ChangeLog                     | 19 ++++++++
>  gdb/c-exp.y                       | 52 ++++++++++++++-------
>  gdb/testsuite/ChangeLog           |  4 ++
>  gdb/testsuite/gdb.base/cvexpr.exp |  4 ++
>  gdb/type-stack.c                  | 76 +++++++++++++++----------------
>  gdb/type-stack.h                  |  2 +
>  6 files changed, 101 insertions(+), 56 deletions(-)
>
> diff --git a/gdb/c-exp.y b/gdb/c-exp.y
> index 3403a857a83..1b35ef2e60a 100644
> --- a/gdb/c-exp.y
> +++ b/gdb/c-exp.y
> @@ -237,6 +237,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
>  /* Special type cases, put in to allow the parser to distinguish different
>     legal basetypes.  */
>  %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
> +%token RESTRICT ATOMIC
>
>  %token <sval> DOLLAR_VARIABLE
>
> @@ -1169,36 +1170,43 @@ variable:       name_not_typename
>                         }
>         ;
>
> -space_identifier : '@' NAME
> -               {
> -                 cpstate->type_stack.insert (pstate,
> -                                             copy_name ($2.stoken).c_str ());
> -               }
> -       ;
> -
>  const_or_volatile: const_or_volatile_noopt
>         |
>         ;
>
> -cv_with_space_id : const_or_volatile space_identifier const_or_volatile
> +single_qualifier:
> +               CONST_KEYWORD
> +                       { cpstate->type_stack.insert (tp_const); }
> +       |       VOLATILE_KEYWORD
> +                       { cpstate->type_stack.insert (tp_volatile); }
> +       |       ATOMIC
> +                       { cpstate->type_stack.insert (tp_atomic); }
> +       |       RESTRICT
> +                       { cpstate->type_stack.insert (tp_restrict); }
> +       |       '@' NAME
> +               {
> +                 cpstate->type_stack.insert (pstate,
> +                                             copy_name ($2.stoken).c_str ());
> +               }
>         ;
>
> -const_or_volatile_or_space_identifier_noopt: cv_with_space_id
> -       | const_or_volatile_noopt
> +qualifier_seq_noopt:
> +               single_qualifier
> +       |       qualifier_seq single_qualifier
>         ;
>
> -const_or_volatile_or_space_identifier:
> -               const_or_volatile_or_space_identifier_noopt
> +qualifier_seq:
> +               qualifier_seq_noopt
>         |
>         ;
>
>  ptr_operator:
>                 ptr_operator '*'
>                         { cpstate->type_stack.insert (tp_pointer); }
> -               const_or_volatile_or_space_identifier
> +               qualifier_seq
>         |       '*'
>                         { cpstate->type_stack.insert (tp_pointer); }
> -               const_or_volatile_or_space_identifier
> +               qualifier_seq
>         |       '&'
>                         { cpstate->type_stack.insert (tp_reference); }
>         |       '&' ptr_operator
> @@ -1472,9 +1480,9 @@ typebase
>                             (copy_name($2).c_str (), $4,
>                              pstate->expression_context_block);
>                         }
> -       | const_or_volatile_or_space_identifier_noopt typebase
> +       |       qualifier_seq_noopt typebase
>                         { $$ = cpstate->type_stack.follow_types ($2); }
> -       | typebase const_or_volatile_or_space_identifier_noopt
> +       |       typebase qualifier_seq_noopt
>                         { $$ = cpstate->type_stack.follow_types ($1); }
>         ;
>
> @@ -2345,6 +2353,10 @@ enum token_flag
>
>    FLAG_CXX = 1,
>
> +  /* If this bit is set, the token is C-only.  */
> +
> +  FLAG_C = 1,
> +
>    /* If this bit is set, the token is conditional: if there is a
>       symbol of the same name, then the token is a symbol; otherwise,
>       the token is a keyword.  */
> @@ -2416,6 +2428,8 @@ static const struct token ident_tokens[] =
>      {"union", UNION, OP_NULL, 0},
>      {"short", SHORT, OP_NULL, 0},
>      {"const", CONST_KEYWORD, OP_NULL, 0},
> +    {"restrict", RESTRICT, OP_NULL, 0},
> +    {"_Atomic", ATOMIC, OP_NULL, 0},
>      {"enum", ENUM, OP_NULL, 0},
>      {"long", LONG, OP_NULL, 0},
>      {"true", TRUEKEYWORD, OP_NULL, FLAG_CXX},
> @@ -2550,6 +2564,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
>         if ((tokentab3[i].flags & FLAG_CXX) != 0
>             && par_state->language ()->la_language != language_cplus)
>           break;
> +       gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
>
>         pstate->lexptr += 3;
>         yylval.opcode = tokentab3[i].opcode;
> @@ -2563,6 +2578,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
>         if ((tokentab2[i].flags & FLAG_CXX) != 0
>             && par_state->language ()->la_language != language_cplus)
>           break;
> +       gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
>
>         pstate->lexptr += 2;
>         yylval.opcode = tokentab2[i].opcode;
> @@ -2857,6 +2873,10 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
>         if ((ident_tokens[i].flags & FLAG_CXX) != 0
>             && par_state->language ()->la_language != language_cplus)
>           break;
> +       if ((ident_tokens[i].flags & FLAG_C) != 0
> +           && par_state->language ()->la_language != language_c
> +           && par_state->language ()->la_language != language_objc)
> +         break;
>
>         if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
>           {
> diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp
> index 92a073a774e..cf5d2c4a553 100644
> --- a/gdb/testsuite/gdb.base/cvexpr.exp
> +++ b/gdb/testsuite/gdb.base/cvexpr.exp
> @@ -509,3 +509,7 @@ foreach testspec $specs {
>         do_test $prefix $opts
>      }
>  }
> +
> +# These tests don't rely on the debug format.
> +gdb_test "ptype _Atomic int" "type = _Atomic int"
> +gdb_test "ptype int * restrict" "type = int \\* restrict"
> diff --git a/gdb/type-stack.c b/gdb/type-stack.c
> index ab7e0261cad..73b7d5a8dfc 100644
> --- a/gdb/type-stack.c
> +++ b/gdb/type-stack.c
> @@ -33,12 +33,14 @@ type_stack::insert (enum type_pieces tp)
>
>    gdb_assert (tp == tp_pointer || tp == tp_reference
>               || tp == tp_rvalue_reference || tp == tp_const
> -             || tp == tp_volatile);
> +             || tp == tp_volatile || tp == tp_restrict
> +             || tp == tp_atomic);
>
>    /* If there is anything on the stack (we know it will be a
>       tp_pointer), insert the qualifier above it.  Otherwise, simply
>       push this on the top of the stack.  */
> -  if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile))
> +  if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile
> +                              || tp == tp_restrict))
>      slot = 1;
>    else
>      slot = 0;
> @@ -88,6 +90,12 @@ type_stack::follow_type_instance_flags ()
>        case tp_volatile:
>         flags |= TYPE_INSTANCE_FLAG_VOLATILE;
>         break;
> +      case tp_atomic:
> +       flags |= TYPE_INSTANCE_FLAG_ATOMIC;
> +       break;
> +      case tp_restrict:
> +       flags |= TYPE_INSTANCE_FLAG_RESTRICT;
> +       break;
>        default:
>         gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
>        }
> @@ -102,6 +110,8 @@ type_stack::follow_types (struct type *follow_type)
>    int make_const = 0;
>    int make_volatile = 0;
>    int make_addr_space = 0;
> +  bool make_restrict = false;
> +  bool make_atomic = false;
>    int array_size;
>
>    while (!done)
> @@ -109,19 +119,7 @@ type_stack::follow_types (struct type *follow_type)
>        {
>        case tp_end:
>         done = 1;
> -       if (make_const)
> -         follow_type = make_cv_type (make_const,
> -                                     TYPE_VOLATILE (follow_type),
> -                                     follow_type, 0);
> -       if (make_volatile)
> -         follow_type = make_cv_type (TYPE_CONST (follow_type),
> -                                     make_volatile,
> -                                     follow_type, 0);
> -       if (make_addr_space)
> -         follow_type = make_type_with_address_space (follow_type,
> -                                                     make_addr_space);
> -       make_const = make_volatile = 0;
> -       make_addr_space = 0;
> +       goto process_qualifiers;
>         break;
>        case tp_const:
>         make_const = 1;
> @@ -132,41 +130,39 @@ type_stack::follow_types (struct type *follow_type)
>        case tp_space_identifier:
>         make_addr_space = pop_int ();
>         break;
> +      case tp_atomic:
> +       make_atomic = true;
> +       break;
> +      case tp_restrict:
> +       make_restrict = true;
> +       break;
>        case tp_pointer:
>         follow_type = lookup_pointer_type (follow_type);
> +       goto process_qualifiers;
> +      case tp_reference:
> +       follow_type = lookup_lvalue_reference_type (follow_type);
> +       goto process_qualifiers;
> +      case tp_rvalue_reference:
> +       follow_type = lookup_rvalue_reference_type (follow_type);
> +      process_qualifiers:
>         if (make_const)
> -         follow_type = make_cv_type (make_const,
> -                                     TYPE_VOLATILE (follow_type),
> +         follow_type = make_cv_type (make_const,
> +                                     TYPE_VOLATILE (follow_type),
>                                       follow_type, 0);
>         if (make_volatile)
> -         follow_type = make_cv_type (TYPE_CONST (follow_type),
> -                                     make_volatile,
> +         follow_type = make_cv_type (TYPE_CONST (follow_type),
> +                                     make_volatile,
>                                       follow_type, 0);
>         if (make_addr_space)
> -         follow_type = make_type_with_address_space (follow_type,
> +         follow_type = make_type_with_address_space (follow_type,
>                                                       make_addr_space);
> +       if (make_restrict)
> +         follow_type = make_restrict_type (follow_type);
> +       if (make_atomic)
> +         follow_type = make_atomic_type (follow_type);
>         make_const = make_volatile = 0;
>         make_addr_space = 0;
> -       break;
> -      case tp_reference:
> -        follow_type = lookup_lvalue_reference_type (follow_type);
> -        goto process_reference;
> -       case tp_rvalue_reference:
> -        follow_type = lookup_rvalue_reference_type (follow_type);
> -       process_reference:
> -        if (make_const)
> -          follow_type = make_cv_type (make_const,
> -                                      TYPE_VOLATILE (follow_type),
> -                                      follow_type, 0);
> -        if (make_volatile)
> -          follow_type = make_cv_type (TYPE_CONST (follow_type),
> -                                      make_volatile,
> -                                      follow_type, 0);
> -        if (make_addr_space)
> -          follow_type = make_type_with_address_space (follow_type,
> -                                                      make_addr_space);
> -       make_const = make_volatile = 0;
> -       make_addr_space = 0;
> +       make_restrict = make_atomic = false;
>         break;
>        case tp_array:
>         array_size = pop_int ();
> diff --git a/gdb/type-stack.h b/gdb/type-stack.h
> index ee004d1be8d..8060f2fea78 100644
> --- a/gdb/type-stack.h
> +++ b/gdb/type-stack.h
> @@ -40,6 +40,8 @@ enum type_pieces
>      tp_const,
>      tp_volatile,
>      tp_space_identifier,
> +    tp_atomic,
> +    tp_restrict,
>      tp_type_stack,
>      tp_kind
>    };
> --
> 2.17.2
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Add C parser support for "restrict" and "_Atomic"
  2020-03-01 16:16 ` Ruslan Kabatsayev
@ 2020-03-04  0:39   ` Tom Tromey
  2020-03-14 18:30     ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2020-03-04  0:39 UTC (permalink / raw)
  To: Ruslan Kabatsayev; +Cc: Tom Tromey, GDB Patches

>>>>> "Ruslan" == Ruslan Kabatsayev <b7.10110111@gmail.com> writes:

Ruslan> On Sun, 1 Mar 2020 at 06:01, Tom Tromey <tom@tromey.com> wrote:
>> 
>> A user noticed that "watch -location" would fail with a "restrict"
>> pointer.  The issue here is that if the DWARF mentions "restrict", gdb
>> will put this into the type name -- but then the C parser will not be
>> able to parse this type.
>> 
>> This patch adds support for "restrict" and "_Atomic" to the C parser.
>> It is done only for C and Objective C, not C++.

Ruslan> GCC has the keywords __restrict__ and __restrict that work in C++ too.
Ruslan> These are also affected, including the use in C++.

Thanks, I'll add those.

>> I wasn't sure if "restrict" should be marked FLAG_SHADOW to support
>> older dialects of C, where this was not a keyword.

I'll have to check how C++ prints a restrict type.
Maybe gdb will need another tweak here.

>> +    {"restrict", RESTRICT, OP_NULL, 0},

I forgot to actually use FLAG_C here, oops.

Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Add C parser support for "restrict" and "_Atomic"
  2020-03-04  0:39   ` Tom Tromey
@ 2020-03-14 18:30     ` Tom Tromey
  0 siblings, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2020-03-14 18:30 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Ruslan Kabatsayev, GDB Patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

Ruslan> GCC has the keywords __restrict__ and __restrict that work in C++ too.
Ruslan> These are also affected, including the use in C++.

Tom> Thanks, I'll add those.

>>> I wasn't sure if "restrict" should be marked FLAG_SHADOW to support
>>> older dialects of C, where this was not a keyword.

Tom> I'll have to check how C++ prints a restrict type.
Tom> Maybe gdb will need another tweak here.

>>> +    {"restrict", RESTRICT, OP_NULL, 0},

Tom> I forgot to actually use FLAG_C here, oops.

Here's an updated patch.
I'm checking this in.

Tom

commit fd7fda86e41744cd6b052ab63d0496f6208413a1
Author: Tom Tromey <tom@tromey.com>
Date:   Sat Mar 14 12:11:42 2020 -0600

    Add C parser support for "restrict" and "_Atomic"
    
    A user noticed that "watch -location" would fail with a "restrict"
    pointer.  The issue here is that if the DWARF mentions "restrict", gdb
    will put this into the type name -- but then the C parser will not be
    able to parse this type.
    
    This patch adds support for "restrict" and "_Atomic" to the C parser.
    C++ doesn't have "restrict", but does have some GCC extensions.  The
    type printer is changed to handle this difference as well, so that
    watch expressions will work properly.
    
    gdb/ChangeLog
    2020-03-14  Tom Tromey  <tom@tromey.com>
    
            * c-typeprint.c (cp_type_print_method_args): Print "__restrict__"
            for C++.
            (c_type_print_modifier): Likewise.  Add "language" parameter.
            (c_type_print_varspec_prefix, c_type_print_base_struct_union)
            (c_type_print_base_1): Update.
            * type-stack.h (enum type_pieces) <tp_atomic, tp_restrict>: New
            constants.
            * type-stack.c (type_stack::insert): Handle tp_atomic and
            tp_restrict.
            (type_stack::follow_type_instance_flags): Likewise.
            (type_stack::follow_types): Likewise.  Merge type-following code.
            * c-exp.y (RESTRICT, ATOMIC): New tokens.
            (space_identifier, cv_with_space_id)
            (const_or_volatile_or_space_identifier_noopt)
            (const_or_volatile_or_space_identifier): Remove.
            (single_qualifier, qualifier_seq_noopt, qualifier_seq): New
            rules.
            (ptr_operator, typebase): Update.
            (enum token_flag) <FLAG_C>: New constant.
            (ident_tokens): Add "restrict", "__restrict__", "__restrict", and
            "_Atomic".
            (lex_one_token): Handle FLAG_C.
    
    gdb/testsuite/ChangeLog
    2020-03-14  Tom Tromey  <tom@tromey.com>
    
            * gdb.base/cvexpr.exp: Add test for _Atomic and restrict.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a4ed9944407..4869693a341 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,28 @@
+2020-03-14  Tom Tromey  <tom@tromey.com>
+
+	* c-typeprint.c (cp_type_print_method_args): Print "__restrict__"
+	for C++.
+	(c_type_print_modifier): Likewise.  Add "language" parameter.
+	(c_type_print_varspec_prefix, c_type_print_base_struct_union)
+	(c_type_print_base_1): Update.
+	* type-stack.h (enum type_pieces) <tp_atomic, tp_restrict>: New
+	constants.
+	* type-stack.c (type_stack::insert): Handle tp_atomic and
+	tp_restrict.
+	(type_stack::follow_type_instance_flags): Likewise.
+	(type_stack::follow_types): Likewise.  Merge type-following code.
+	* c-exp.y (RESTRICT, ATOMIC): New tokens.
+	(space_identifier, cv_with_space_id)
+	(const_or_volatile_or_space_identifier_noopt)
+	(const_or_volatile_or_space_identifier): Remove.
+	(single_qualifier, qualifier_seq_noopt, qualifier_seq): New
+	rules.
+	(ptr_operator, typebase): Update.
+	(enum token_flag) <FLAG_C>: New constant.
+	(ident_tokens): Add "restrict", "__restrict__", "__restrict", and
+	"_Atomic".
+	(lex_one_token): Handle FLAG_C.
+
 2020-03-13  Tom Tromey  <tom@tromey.com>
 
 	* value.h (val_print): Don't declare.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 3403a857a83..50a2eef98b5 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -237,6 +237,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
 %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
+%token RESTRICT ATOMIC
 
 %token <sval> DOLLAR_VARIABLE
 
@@ -1169,36 +1170,43 @@ variable:	name_not_typename
 			}
 	;
 
-space_identifier : '@' NAME
-		{
-		  cpstate->type_stack.insert (pstate,
-					      copy_name ($2.stoken).c_str ());
-		}
-	;
-
 const_or_volatile: const_or_volatile_noopt
 	|
 	;
 
-cv_with_space_id : const_or_volatile space_identifier const_or_volatile
+single_qualifier:
+		CONST_KEYWORD
+			{ cpstate->type_stack.insert (tp_const); }
+	| 	VOLATILE_KEYWORD
+			{ cpstate->type_stack.insert (tp_volatile); }
+	| 	ATOMIC
+			{ cpstate->type_stack.insert (tp_atomic); }
+	| 	RESTRICT
+			{ cpstate->type_stack.insert (tp_restrict); }
+	|	'@' NAME
+		{
+		  cpstate->type_stack.insert (pstate,
+					      copy_name ($2.stoken).c_str ());
+		}
 	;
 
-const_or_volatile_or_space_identifier_noopt: cv_with_space_id
-	| const_or_volatile_noopt
+qualifier_seq_noopt:
+		single_qualifier
+	| 	qualifier_seq single_qualifier
 	;
 
-const_or_volatile_or_space_identifier:
-		const_or_volatile_or_space_identifier_noopt
+qualifier_seq:
+		qualifier_seq_noopt
 	|
 	;
 
 ptr_operator:
 		ptr_operator '*'
 			{ cpstate->type_stack.insert (tp_pointer); }
-		const_or_volatile_or_space_identifier
+		qualifier_seq
 	|	'*'
 			{ cpstate->type_stack.insert (tp_pointer); }
-		const_or_volatile_or_space_identifier
+		qualifier_seq
 	|	'&'
 			{ cpstate->type_stack.insert (tp_reference); }
 	|	'&' ptr_operator
@@ -1472,9 +1480,9 @@ typebase
 			    (copy_name($2).c_str (), $4,
 			     pstate->expression_context_block);
 			}
-	| const_or_volatile_or_space_identifier_noopt typebase
+	|	qualifier_seq_noopt typebase
 			{ $$ = cpstate->type_stack.follow_types ($2); }
-	| typebase const_or_volatile_or_space_identifier_noopt
+	|	typebase qualifier_seq_noopt
 			{ $$ = cpstate->type_stack.follow_types ($1); }
 	;
 
@@ -2345,11 +2353,15 @@ enum token_flag
 
   FLAG_CXX = 1,
 
+  /* If this bit is set, the token is C-only.  */
+
+  FLAG_C = 2,
+
   /* If this bit is set, the token is conditional: if there is a
      symbol of the same name, then the token is a symbol; otherwise,
      the token is a keyword.  */
 
-  FLAG_SHADOW = 2
+  FLAG_SHADOW = 4
 };
 DEF_ENUM_FLAGS_TYPE (enum token_flag, token_flags);
 
@@ -2416,6 +2428,10 @@ static const struct token ident_tokens[] =
     {"union", UNION, OP_NULL, 0},
     {"short", SHORT, OP_NULL, 0},
     {"const", CONST_KEYWORD, OP_NULL, 0},
+    {"restrict", RESTRICT, OP_NULL, FLAG_C | FLAG_SHADOW},
+    {"__restrict__", RESTRICT, OP_NULL, 0},
+    {"__restrict", RESTRICT, OP_NULL, 0},
+    {"_Atomic", ATOMIC, OP_NULL, 0},
     {"enum", ENUM, OP_NULL, 0},
     {"long", LONG, OP_NULL, 0},
     {"true", TRUEKEYWORD, OP_NULL, FLAG_CXX},
@@ -2550,6 +2566,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 	if ((tokentab3[i].flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
+	gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
 
 	pstate->lexptr += 3;
 	yylval.opcode = tokentab3[i].opcode;
@@ -2563,6 +2580,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 	if ((tokentab2[i].flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
+	gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
 
 	pstate->lexptr += 2;
 	yylval.opcode = tokentab2[i].opcode;
@@ -2857,6 +2875,10 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 	if ((ident_tokens[i].flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
+	if ((ident_tokens[i].flags & FLAG_C) != 0
+	    && par_state->language ()->la_language != language_c
+	    && par_state->language ()->la_language != language_objc)
+	  break;
 
 	if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
 	  {
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 1f27b566467..50d0eaa2dde 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -58,7 +58,7 @@ static void c_type_print_varspec_prefix (struct type *,
 /* Print "const", "volatile", or address space modifiers.  */
 static void c_type_print_modifier (struct type *,
 				   struct ui_file *,
-				   int, int);
+				   int, int, enum language);
 
 static void c_type_print_base_1 (struct type *type, struct ui_file *stream,
 				 int show, int level, enum language language,
@@ -337,7 +337,9 @@ cp_type_print_method_args (struct type *mtype, const char *prefix,
 	fprintf_filtered (stream, " volatile");
 
       if (TYPE_RESTRICT (domain))
-	fprintf_filtered (stream, " restrict");
+	fprintf_filtered (stream, (language == language_cplus
+				   ? " __restrict__"
+				   : " restrict"));
 
       if (TYPE_ATOMIC (domain))
 	fprintf_filtered (stream, " _Atomic");
@@ -383,7 +385,7 @@ c_type_print_varspec_prefix (struct type *type,
 				   stream, show, 1, 1, language, flags,
 				   podata);
       fprintf_filtered (stream, "*");
-      c_type_print_modifier (type, stream, 1, need_post_space);
+      c_type_print_modifier (type, stream, 1, need_post_space, language);
       break;
 
     case TYPE_CODE_MEMBERPTR:
@@ -420,7 +422,7 @@ c_type_print_varspec_prefix (struct type *type,
 				   stream, show, 1, 0, language, flags,
 				   podata);
       fprintf_filtered (stream, TYPE_CODE(type) == TYPE_CODE_REF ? "&" : "&&");
-      c_type_print_modifier (type, stream, 1, need_post_space);
+      c_type_print_modifier (type, stream, 1, need_post_space, language);
       break;
 
     case TYPE_CODE_METHOD:
@@ -481,7 +483,8 @@ c_type_print_varspec_prefix (struct type *type,
 
 static void
 c_type_print_modifier (struct type *type, struct ui_file *stream,
-		       int need_pre_space, int need_post_space)
+		       int need_pre_space, int need_post_space,
+		       enum language language)
 {
   int did_print_modifier = 0;
   const char *address_space_id;
@@ -509,7 +512,9 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
     {
       if (did_print_modifier || need_pre_space)
 	fprintf_filtered (stream, " ");
-      fprintf_filtered (stream, "restrict");
+      fprintf_filtered (stream, (language == language_cplus
+				 ? "__restrict__"
+				 : "restrict"));
       did_print_modifier = 1;
     }
 
@@ -1050,7 +1055,7 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream,
       hash_holder.reset (local_flags.local_typedefs);
     }
 
-  c_type_print_modifier (type, stream, 0, 1);
+  c_type_print_modifier (type, stream, 0, 1, language);
   if (TYPE_CODE (type) == TYPE_CODE_UNION)
     fprintf_filtered (stream, "union ");
   else if (TYPE_DECLARED_CLASS (type))
@@ -1477,7 +1482,7 @@ c_type_print_base_1 (struct type *type, struct ui_file *stream,
   if (show <= 0
       && TYPE_NAME (type) != NULL)
     {
-      c_type_print_modifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1, language);
 
       /* If we have "typedef struct foo {. . .} bar;" do we want to
 	 print it as "struct foo" or as "bar"?  Pick the latter for
@@ -1542,7 +1547,7 @@ c_type_print_base_1 (struct type *type, struct ui_file *stream,
       break;
 
     case TYPE_CODE_ENUM:
-      c_type_print_modifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1, language);
       fprintf_filtered (stream, "enum ");
       if (TYPE_DECLARED_CLASS (type))
 	fprintf_filtered (stream, "class ");
@@ -1615,7 +1620,7 @@ c_type_print_base_1 (struct type *type, struct ui_file *stream,
 
 	local_flags.local_typedefs = NULL;
 
-	c_type_print_modifier (type, stream, 0, 1);
+	c_type_print_modifier (type, stream, 0, 1, language);
 	fprintf_filtered (stream, "flag ");
 	print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
 	if (show > 0)
@@ -1689,7 +1694,7 @@ c_type_print_base_1 (struct type *type, struct ui_file *stream,
          type name, then complain.  */
       if (TYPE_NAME (type) != NULL)
 	{
-	  c_type_print_modifier (type, stream, 0, 1);
+	  c_type_print_modifier (type, stream, 0, 1, language);
 	  print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
 	}
       else
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ec22de89d57..1f16e344563 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-03-14  Tom Tromey  <tom@tromey.com>
+
+	* gdb.base/cvexpr.exp: Add test for _Atomic and restrict.
+
 2020-03-13  Tom Tromey  <tom@tromey.com>
 
 	* gdb.base/printcmds.exp (test_print_strings): Add regression
diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp
index 92a073a774e..d905198a72c 100644
--- a/gdb/testsuite/gdb.base/cvexpr.exp
+++ b/gdb/testsuite/gdb.base/cvexpr.exp
@@ -509,3 +509,14 @@ foreach testspec $specs {
 	do_test $prefix $opts
     }
 }
+
+# These tests don't rely on the debug format.
+gdb_test "ptype _Atomic int" "type = _Atomic int"
+gdb_test "ptype int * restrict" "type = int \\* restrict"
+
+# C++ does not have "restrict".
+gdb_test_no_output "set lang c++"
+gdb_test "ptype int * restrict" "A syntax error in expression.*"
+
+# There is a GCC extension for __restrict__, though.
+gdb_test "ptype int * __restrict__" "type = int \\* __restrict__"
diff --git a/gdb/type-stack.c b/gdb/type-stack.c
index ab7e0261cad..73b7d5a8dfc 100644
--- a/gdb/type-stack.c
+++ b/gdb/type-stack.c
@@ -33,12 +33,14 @@ type_stack::insert (enum type_pieces tp)
 
   gdb_assert (tp == tp_pointer || tp == tp_reference
 	      || tp == tp_rvalue_reference || tp == tp_const
-	      || tp == tp_volatile);
+	      || tp == tp_volatile || tp == tp_restrict
+	      || tp == tp_atomic);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
      push this on the top of the stack.  */
-  if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile))
+  if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile
+			       || tp == tp_restrict))
     slot = 1;
   else
     slot = 0;
@@ -88,6 +90,12 @@ type_stack::follow_type_instance_flags ()
       case tp_volatile:
 	flags |= TYPE_INSTANCE_FLAG_VOLATILE;
 	break;
+      case tp_atomic:
+	flags |= TYPE_INSTANCE_FLAG_ATOMIC;
+	break;
+      case tp_restrict:
+	flags |= TYPE_INSTANCE_FLAG_RESTRICT;
+	break;
       default:
 	gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
       }
@@ -102,6 +110,8 @@ type_stack::follow_types (struct type *follow_type)
   int make_const = 0;
   int make_volatile = 0;
   int make_addr_space = 0;
+  bool make_restrict = false;
+  bool make_atomic = false;
   int array_size;
 
   while (!done)
@@ -109,19 +119,7 @@ type_stack::follow_types (struct type *follow_type)
       {
       case tp_end:
 	done = 1;
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
-	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	goto process_qualifiers;
 	break;
       case tp_const:
 	make_const = 1;
@@ -132,41 +130,39 @@ type_stack::follow_types (struct type *follow_type)
       case tp_space_identifier:
 	make_addr_space = pop_int ();
 	break;
+      case tp_atomic:
+	make_atomic = true;
+	break;
+      case tp_restrict:
+	make_restrict = true;
+	break;
       case tp_pointer:
 	follow_type = lookup_pointer_type (follow_type);
+	goto process_qualifiers;
+      case tp_reference:
+	follow_type = lookup_lvalue_reference_type (follow_type);
+	goto process_qualifiers;
+      case tp_rvalue_reference:
+	follow_type = lookup_rvalue_reference_type (follow_type);
+      process_qualifiers:
 	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
+	  follow_type = make_cv_type (make_const,
+				      TYPE_VOLATILE (follow_type),
 				      follow_type, 0);
 	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
+	  follow_type = make_cv_type (TYPE_CONST (follow_type),
+				      make_volatile,
 				      follow_type, 0);
 	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
+	  follow_type = make_type_with_address_space (follow_type,
 						      make_addr_space);
+	if (make_restrict)
+	  follow_type = make_restrict_type (follow_type);
+	if (make_atomic)
+	  follow_type = make_atomic_type (follow_type);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
-	break;
-      case tp_reference:
-	 follow_type = lookup_lvalue_reference_type (follow_type);
-	 goto process_reference;
-	case tp_rvalue_reference:
-	 follow_type = lookup_rvalue_reference_type (follow_type);
-	process_reference:
-	 if (make_const)
-	   follow_type = make_cv_type (make_const,
-				       TYPE_VOLATILE (follow_type),
-				       follow_type, 0);
-	 if (make_volatile)
-	   follow_type = make_cv_type (TYPE_CONST (follow_type),
-				       make_volatile,
-				       follow_type, 0);
-	 if (make_addr_space)
-	   follow_type = make_type_with_address_space (follow_type,
-						       make_addr_space);
-	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	make_restrict = make_atomic = false;
 	break;
       case tp_array:
 	array_size = pop_int ();
diff --git a/gdb/type-stack.h b/gdb/type-stack.h
index ee004d1be8d..8060f2fea78 100644
--- a/gdb/type-stack.h
+++ b/gdb/type-stack.h
@@ -40,6 +40,8 @@ enum type_pieces
     tp_const, 
     tp_volatile, 
     tp_space_identifier,
+    tp_atomic,
+    tp_restrict,
     tp_type_stack,
     tp_kind
   };

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-03-14 18:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-01  3:01 [PATCH] Add C parser support for "restrict" and "_Atomic" Tom Tromey
2020-03-01 16:16 ` Ruslan Kabatsayev
2020-03-04  0:39   ` Tom Tromey
2020-03-14 18:30     ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).