aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-06-19 19:49:42 +0000
committerTom Tromey <tromey@redhat.com>2012-06-19 19:49:42 +0000
commit95c391b64aafe6d8868a99dd476e6f110011dd2d (patch)
tree10fb350b0855dab2a352174353005d4775911086 /gdb
parente910f0b61f40b0fcbbba3607dbe3e153f45e00d4 (diff)
downloadgdb-95c391b64aafe6d8868a99dd476e6f110011dd2d.zip
gdb-95c391b64aafe6d8868a99dd476e6f110011dd2d.tar.gz
gdb-95c391b64aafe6d8868a99dd476e6f110011dd2d.tar.bz2
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.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/c-exp.y50
-rw-r--r--gdb/parse.c69
-rw-r--r--gdb/parser-defs.h4
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.base/whatis.exp14
6 files changed, 138 insertions, 20 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 37e1272..36a04ba 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2012-06-19 Tom Tromey <tromey@redhat.com>
+
+ 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 <dje@google.com>
* symtab.h (minimal_symbol): New member created_by_gdb.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index bf53fbc..7afce77 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -172,9 +172,10 @@ static struct stoken operator_stoken (const char *);
/* %type <bval> block */
/* Fancy type parsing. */
-%type <voidval> func_mod direct_abs_decl abs_decl
+%type <voidval> func_mod direct_abs_decl abs_decl ptr_operator
%type <tval> ptype
%type <lval> array_mod
+%type <tval> conversion_type_id
%token <typed_val_int> INT
%token <typed_val_float> 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 f54c6f2..0d0467d 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 72b9e2f..aa600a1 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 26e4ce0..f123984 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2012-06-19 Tom Tromey <tromey@redhat.com>
+ * gdb.base/whatis.exp: Add tests.
+
+2012-06-19 Tom Tromey <tromey@redhat.com>
+
* gdb.cp/m-static.cc (keepalive): New function.
(gnu_obj_1::method): Use it.
diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp
index 9198ef2..793bf0b 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"