From 95c391b64aafe6d8868a99dd476e6f110011dd2d Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 19 Jun 2012 19:49:42 +0000 Subject: [PATCH] PR exp/9514: * parser-defs.h (insert_type, insert_type_address_space): Declare. (push_type_address_space): Remove. * parse.c (insert_into_type_stack): New function. (insert_type): Likewise. (insert_type_address_space): Rename from push_type_address_space. Insert tp_space_identifier. * c-exp.y (ptr_operator): New production. (abs_decl): Use ptr_operator. (space_identifier): Call insert_type_address_space. (ptype): Don't use const_or_volatile_or_space_identifier. (const_or_volatile_noopt): Call insert_type. (conversion_type_id, conversion_declarator): New productions. (operator): Use conversion_type_id. testsuite * gdb.base/whatis.exp: Add tests. --- gdb/ChangeLog | 17 ++++++++ gdb/c-exp.y | 50 ++++++++++++++-------- gdb/parse.c | 69 ++++++++++++++++++++++++++++++- gdb/parser-defs.h | 4 +- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.base/whatis.exp | 14 +++++++ 6 files changed, 138 insertions(+), 20 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 37e1272cf5..36a04bae67 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2012-06-19 Tom Tromey + + PR exp/9514: + * parser-defs.h (insert_type, insert_type_address_space): Declare. + (push_type_address_space): Remove. + * parse.c (insert_into_type_stack): New function. + (insert_type): Likewise. + (insert_type_address_space): Rename from push_type_address_space. + Insert tp_space_identifier. + * c-exp.y (ptr_operator): New production. + (abs_decl): Use ptr_operator. + (space_identifier): Call insert_type_address_space. + (ptype): Don't use const_or_volatile_or_space_identifier. + (const_or_volatile_noopt): Call insert_type. + (conversion_type_id, conversion_declarator): New productions. + (operator): Use conversion_type_id. + 2012-06-18 Doug Evans * symtab.h (minimal_symbol): New member created_by_gdb. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index bf53fbcc38..7afce770e2 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -172,9 +172,10 @@ static struct stoken operator_stoken (const char *); /* %type block */ /* Fancy type parsing. */ -%type func_mod direct_abs_decl abs_decl +%type func_mod direct_abs_decl abs_decl ptr_operator %type ptype %type array_mod +%type conversion_type_id %token INT %token FLOAT @@ -931,9 +932,7 @@ variable: name_not_typename ; space_identifier : '@' NAME - { push_type_address_space (copy_name ($2.stoken)); - push_type (tp_space_identifier); - } + { insert_type_address_space (copy_name ($2.stoken)); } ; const_or_volatile: const_or_volatile_noopt @@ -952,14 +951,23 @@ const_or_volatile_or_space_identifier: | ; -abs_decl: '*' - { push_type (tp_pointer); $$ = 0; } - | '*' abs_decl - { push_type (tp_pointer); $$ = $2; } +ptr_operator: + ptr_operator '*' + { insert_type (tp_pointer); } + const_or_volatile_or_space_identifier + { $$ = 0; } + | '*' + { insert_type (tp_pointer); } + const_or_volatile_or_space_identifier + { $$ = 0; } | '&' - { push_type (tp_reference); $$ = 0; } - | '&' abs_decl - { push_type (tp_reference); $$ = $2; } + { insert_type (tp_reference); $$ = 0; } + | '&' ptr_operator + { insert_type (tp_reference); $$ = 0; } + ; + +abs_decl: ptr_operator direct_abs_decl + | ptr_operator | direct_abs_decl ; @@ -1203,22 +1211,30 @@ nonempty_typelist ; ptype : typebase - | ptype const_or_volatile_or_space_identifier abs_decl const_or_volatile_or_space_identifier + | ptype abs_decl { $$ = follow_types ($1); } ; +conversion_type_id: typebase conversion_declarator + { $$ = follow_types ($1); } + ; + +conversion_declarator: /* Nothing. */ + | ptr_operator conversion_declarator + ; + const_and_volatile: CONST_KEYWORD VOLATILE_KEYWORD | VOLATILE_KEYWORD CONST_KEYWORD ; const_or_volatile_noopt: const_and_volatile - { push_type (tp_const); - push_type (tp_volatile); + { insert_type (tp_const); + insert_type (tp_volatile); } | CONST_KEYWORD - { push_type (tp_const); } + { insert_type (tp_const); } | VOLATILE_KEYWORD - { push_type (tp_volatile); } + { insert_type (tp_volatile); } ; operator: OPERATOR NEW @@ -1325,7 +1341,7 @@ operator: OPERATOR NEW { $$ = operator_stoken ("()"); } | OPERATOR '[' ']' { $$ = operator_stoken ("[]"); } - | OPERATOR ptype + | OPERATOR conversion_type_id { char *name; long length; struct ui_file *buf = mem_fileopen (); diff --git a/gdb/parse.c b/gdb/parse.c index f54c6f21e7..0d0467d9ce 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1367,6 +1367,49 @@ check_type_stack_depth (void) } } +/* A helper function for insert_type and insert_type_address_space. + This does work of expanding the type stack and inserting the new + element, ELEMENT, into the stack at location SLOT. */ + +static void +insert_into_type_stack (int slot, union type_stack_elt element) +{ + check_type_stack_depth (); + + if (slot < type_stack_depth) + memmove (&type_stack[slot + 1], &type_stack[slot], + (type_stack_depth - slot) * sizeof (union type_stack_elt)); + type_stack[slot] = element; + ++type_stack_depth; +} + +/* Insert a new type, TP, at the bottom of the type stack. If TP is + tp_pointer or tp_reference, it is inserted at the bottom. If TP is + a qualifier, it is inserted at slot 1 (just above a previous + tp_pointer) if there is anything on the stack, or simply pushed if + the stack is empty. Other values for TP are invalid. */ + +void +insert_type (enum type_pieces tp) +{ + union type_stack_elt element; + int slot; + + gdb_assert (tp == tp_pointer || tp == tp_reference + || tp == tp_const || tp == tp_volatile); + + /* 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 (type_stack_depth && (tp == tp_const || tp == tp_volatile)) + slot = 1; + else + slot = 0; + + element.piece = tp; + insert_into_type_stack (slot, element); +} + void push_type (enum type_pieces tp) { @@ -1381,10 +1424,32 @@ push_type_int (int n) type_stack[type_stack_depth++].int_val = n; } +/* Insert a tp_space_identifier and the corresponding address space + value into the stack. STRING is the name of an address space, as + recognized by address_space_name_to_int. If the stack is empty, + the new elements are simply pushed. If the stack is not empty, + this function assumes that the first item on the stack is a + tp_pointer, and the new values are inserted above the first + item. */ + void -push_type_address_space (char *string) +insert_type_address_space (char *string) { - push_type_int (address_space_name_to_int (parse_gdbarch, string)); + union type_stack_elt element; + int slot; + + /* If there is anything on the stack (we know it will be a + tp_pointer), insert the address space qualifier above it. + Otherwise, simply push this on the top of the stack. */ + if (type_stack_depth) + slot = 1; + else + slot = 0; + + element.piece = tp_space_identifier; + insert_into_type_stack (slot, element); + element.int_val = address_space_name_to_int (parse_gdbarch, string); + insert_into_type_stack (slot, element); } enum type_pieces diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index 72b9e2fa44..aa600a19c4 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -192,11 +192,13 @@ extern int end_arglist (void); extern char *copy_name (struct stoken); +extern void insert_type (enum type_pieces); + extern void push_type (enum type_pieces); extern void push_type_int (int); -extern void push_type_address_space (char *); +extern void insert_type_address_space (char *); extern enum type_pieces pop_type (void); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 26e4ce0f6c..f123984587 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-06-19 Tom Tromey + + * gdb.base/whatis.exp: Add tests. + 2012-06-19 Tom Tromey * gdb.cp/m-static.cc (keepalive): New function. diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp index 9198ef28af..793bf0be01 100644 --- a/gdb/testsuite/gdb.base/whatis.exp +++ b/gdb/testsuite/gdb.base/whatis.exp @@ -465,3 +465,17 @@ gdb_test "whatis char_addr" \ gdb_test "whatis a_char_addr" \ "type = char_addr" \ "whatis applied to variable defined by typedef" + +# Regression tests for PR 9514. + +gdb_test "whatis void (**)()" \ + "type = void \\(\\*\\*\\)\\(\\)" \ + "whatis applied to pointer to pointer to function" + +gdb_test "whatis void (** const)()" \ + "type = void \\(\\*\\* const\\)\\(\\)" \ + "whatis applied to const pointer to pointer to function" + +gdb_test "whatis void (* const *)()" \ + "type = void \\(\\* const \\*\\)\\(\\)" \ + "whatis applied to pointer to const pointer to function"