aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog.cplus16
-rw-r--r--gdb/cp-names.y97
2 files changed, 93 insertions, 20 deletions
diff --git a/gdb/ChangeLog.cplus b/gdb/ChangeLog.cplus
index 3772884..c058ff9 100644
--- a/gdb/ChangeLog.cplus
+++ b/gdb/ChangeLog.cplus
@@ -1,5 +1,21 @@
2003-12-19 Daniel Jacobowitz <drow@mvista.com>
+ * cp-names.y (symbol_end): New function.
+ (trim_chars): Use it.
+ (start_opt, function): New non-terminals used to support
+ function-local names.
+ (GLOBAL): New terminal.
+ (start): Use start_opt.
+ (demangler_special): Handle GLOBAL.
+ (array_indicator): Swap arguments to D_COMP_ARRAY_TYPE.
+ (direct_abstract_declarator, direct_declarator)
+ (direct_declarator_1): Likewise.
+ (declarator_1): Use declarator_1 instead of declarator after
+ a ptr_operator. Support function-local names.
+ (yylex): Handle GLOBAL specially.
+
+2003-12-19 Daniel Jacobowitz <drow@mvista.com>
+
* cp-names.y (demangler_special): New non-terminal.
(DEMANGLER_SPECIAL, CONSTRUCTION_VTABLE, CONSTRUCTION_IN): New
terminals.
diff --git a/gdb/cp-names.y b/gdb/cp-names.y
index 1427d77..b5d3247 100644
--- a/gdb/cp-names.y
+++ b/gdb/cp-names.y
@@ -49,6 +49,7 @@ typedef long double DOUBLEST;
#include "safe-ctype.h"
+/* #define CP_DEMANGLE_DEBUG */
#include "../libiberty/cp-demangle.c"
static char *lexptr, *prev_lexptr;
@@ -62,6 +63,8 @@ static struct d_comp *d_op_from_string (const char *opname);
static struct d_comp *d_unary (const char *opname, struct d_comp *);
static struct d_comp *d_binary (const char *opname, struct d_comp *, struct d_comp *);
+static char *symbol_end (char *lexptr);
+
/* Global state, ew. */
struct d_info *di;
static struct d_comp *result;
@@ -195,14 +198,14 @@ void yyerror (char *);
static int parse_number (char *, int, int, YYSTYPE *);
%}
-%type <comp> exp exp1 type start operator colon_name
+%type <comp> exp exp1 type start start_opt operator colon_name
%type <comp> unqualified_name scope_id colon_ext_name
%type <comp> template template_arg
%type <comp> builtin_type
%type <comp> typespec typespec_2 array_indicator
%type <comp> colon_ext_only ext_only_name
-%type <comp> demangler_special
+%type <comp> demangler_special function
%type <nested> abstract_declarator direct_abstract_declarator
%type <nested> declarator direct_declarator function_arglist
@@ -244,6 +247,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
/* Non-C++ things we get from the demangler. */
%token <lval> DEMANGLER_SPECIAL CONSTRUCTION_VTABLE
%token CONSTRUCTION_IN
+%token <typed_val_int> GLOBAL
%{
enum {
@@ -293,21 +297,37 @@ result : start
start : type
{ $$ = $1; }
+ | demangler_special
+
+ | function
+
+ ;
+
+start_opt : /* */
+ { $$ = NULL; }
+ | COLONCOLON start
+ { $$ = $2; }
+ ;
+
+function
/* Function with a return type. declarator_1 is used to prevent
ambiguity with the next rule. */
- | typespec_2 declarator_1
+ : typespec_2 declarator_1
{ $$ = $2.comp;
*$2.last = $1;
}
/* Function without a return type. We need to use typespec_2
- to prevent conflicts from qualifiers_opt. Harmless. */
- | typespec_2 function_arglist
- { $$ = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2.comp); }
- | colon_ext_only function_arglist
- { $$ = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2.comp); }
+ to prevent conflicts from qualifiers_opt - harmless. The
+ start_opt is used to handle "function-local" variables and
+ types. */
+ | typespec_2 function_arglist start_opt
+ { $$ = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2.comp);
+ if ($3) $$ = d_make_comp (di, D_COMP_QUAL_NAME, $$, $3); }
+ | colon_ext_only function_arglist start_opt
+ { $$ = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2.comp);
+ if ($3) $$ = d_make_comp (di, D_COMP_QUAL_NAME, $$, $3); }
- | demangler_special
;
demangler_special
@@ -317,6 +337,10 @@ demangler_special
d_right ($$) = NULL; }
| CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
{ $$ = d_make_comp (di, $1, $2, $4); }
+ | GLOBAL
+ { $$ = d_make_empty (di, $1.val);
+ d_left ($$) = $1.type;
+ d_right ($$) = NULL; }
;
operator : OPERATOR NEW
@@ -385,6 +409,10 @@ operator : OPERATOR NEW
{ $$ = d_op_from_string ("()"); }
| OPERATOR '[' ']'
{ $$ = d_op_from_string ("[]"); }
+
+ /* Conversion operators. We don't try to handle some of
+ the wackier demangler output for function pointers,
+ since it's not clear that it's parseable. */
| OPERATOR typespec_2
{ $$ = d_make_comp (di, D_COMP_CAST, $2, NULL); }
| OPERATOR typespec_2 ptr_operator_seq
@@ -641,7 +669,7 @@ ptr_operator_seq: ptr_operator
array_indicator : '[' ']'
{ $$ = d_make_empty (di, D_COMP_ARRAY_TYPE);
- d_right ($$) = NULL;
+ d_left ($$) = NULL;
}
| '[' INT ']'
{ struct d_comp *i;
@@ -651,7 +679,7 @@ array_indicator : '[' ']'
i = d_make_name (di, buf, strlen (buf));
i = d_make_comp (di, D_COMP_LITERAL, $2.type, i);
$$ = d_make_empty (di, D_COMP_ARRAY_TYPE);
- d_right ($$) = i;
+ d_left ($$) = i;
}
/* Details of this approach inspired by the G++ < 3.4 parser. */
@@ -686,11 +714,11 @@ direct_abstract_declarator
| direct_abstract_declarator array_indicator
{ $$.comp = $1.comp;
*$1.last = $2;
- $$.last = &d_left ($2);
+ $$.last = &d_right ($2);
}
| array_indicator
{ $$.comp = $1;
- $$.last = &d_left ($1);
+ $$.last = &d_right ($1);
}
/* G++ has the following except for () and (type). Then
(type) is handled in regcast_or_absdcl and () is handled
@@ -728,7 +756,7 @@ direct_declarator
| direct_declarator array_indicator
{ $$.comp = $1.comp;
*$1.last = $2;
- $$.last = &d_left ($2);
+ $$.last = &d_right ($2);
}
| colon_ext_name
{ $$.comp = d_make_empty (di, D_COMP_TYPED_NAME);
@@ -743,7 +771,7 @@ direct_declarator
parentheses around the colon_ext_name; any colon_ext_name in parentheses
must be followed by an argument list or an array indicator, or preceded
by a pointer. */
-declarator_1 : ptr_operator declarator
+declarator_1 : ptr_operator declarator_1
{ $$.comp = $2.comp;
$$.last = $1.last;
*$2.last = $1.comp; }
@@ -753,6 +781,17 @@ declarator_1 : ptr_operator declarator
$$.last = &d_right ($$.comp);
}
| direct_declarator_1
+
+ /* Function local variable or type. The typespec to
+ our left is the type of the containing function.
+ This should be OK, because function local types
+ can not be templates, so the return types of their
+ members will not be mangled. */
+ | colon_ext_name function_arglist COLONCOLON start
+ { $$.comp = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2.comp);
+ $$.last = $2.last;
+ $$.comp = d_make_comp (di, D_COMP_QUAL_NAME, $$.comp, $4);
+ }
;
direct_declarator_1
@@ -768,7 +807,7 @@ direct_declarator_1
| direct_declarator_1 array_indicator
{ $$.comp = $1.comp;
*$1.last = $2;
- $$.last = &d_left ($2);
+ $$.last = &d_right ($2);
}
| colon_ext_name function_arglist
{ $$.comp = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2.comp);
@@ -776,7 +815,7 @@ direct_declarator_1
}
| colon_ext_name array_indicator
{ $$.comp = d_make_comp (di, D_COMP_TYPED_NAME, $1, $2);
- $$.last = &d_left ($2);
+ $$.last = &d_right ($2);
}
;
@@ -1862,6 +1901,16 @@ yylex ()
yylval.lval = tokentab_big[i].opcode;
if (yylval.lval == D_COMP_CONSTRUCTION_VTABLE)
return CONSTRUCTION_VTABLE;
+ else if (yylval.lval == GLOBAL_CONSTRUCTORS
+ || yylval.lval == GLOBAL_DESTRUCTORS)
+ {
+ /* Skip the trailing space, find the end of the symbol. */
+ char *p = symbol_end (lexptr + 1);
+ yylval.typed_val_int.val = yylval.lval;
+ yylval.typed_val_int.type = d_make_name (di, lexptr + 1, p - (lexptr + 1));
+ lexptr = p;
+ return GLOBAL;
+ }
return DEMANGLER_SPECIAL;
}
@@ -2004,15 +2053,23 @@ cp_print (struct d_comp *result)
return str3;
}
-static char
-trim_chars (char *lexptr, char **extra_chars)
+static char *
+symbol_end (char *lexptr)
{
char *p = lexptr;
- char c = 0;
while (*p && (ISALNUM (*p) || *p == '_' || *p == '$' || *p == '.'))
p++;
+ return p;
+}
+
+static char
+trim_chars (char *lexptr, char **extra_chars)
+{
+ char *p = symbol_end (lexptr);
+ char c = 0;
+
if (*p)
{
c = *p;