diff options
author | Per Bothner <per@bothner.com> | 1992-09-04 07:37:18 +0000 |
---|---|---|
committer | Per Bothner <per@bothner.com> | 1992-09-04 07:37:18 +0000 |
commit | 35fcebce93a949c589d0569e2b1111c1eb26bc2f (patch) | |
tree | 4bf217c00c7022660422bac10180344a14020b9d /gdb/c-exp.y | |
parent | d73812a1d62890a28f3be4054614e16690a1b029 (diff) | |
download | gdb-35fcebce93a949c589d0569e2b1111c1eb26bc2f.zip gdb-35fcebce93a949c589d0569e2b1111c1eb26bc2f.tar.gz gdb-35fcebce93a949c589d0569e2b1111c1eb26bc2f.tar.bz2 |
A ton of changes to improve C++ debugging. See ChangeLog.
Diffstat (limited to 'gdb/c-exp.y')
-rw-r--r-- | gdb/c-exp.y | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/gdb/c-exp.y b/gdb/c-exp.y index fa8ebb9..c49ad89 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -42,6 +42,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symfile.h" #include "objfiles.h" +/* If current_type is non-NULL, it is a signal to the lexer that we have + just parsed: 'TYPE ::' and so if an identifier is seen, the lexer must + search for it in TYPE. This lex-time search is needed to parse + C++ nested types, as in: 'TYPE :: NESTED_TYPE', since this must + parse as a type, not a (non-type) identifier. */ + +static struct type *current_type = NULL; + /* These MUST be included in any grammar file!!!! Please choose unique names! Note that this are a combined list of variables that can be produced by any one of bison, byacc, or yacc. */ @@ -120,7 +128,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *)); %} %type <voidval> exp exp1 type_exp start variable qualified_name -%type <tval> type typebase +%type <tval> type typebase typebase_coloncolon qualified_type %type <tvec> nonempty_typelist /* %type <bval> block */ @@ -144,6 +152,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *)); %token <sval> STRING %token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */ %token <tsym> TYPENAME +%token <tval> NESTED_TYPE %type <sval> name %type <ssym> name_not_typename %type <tsym> typename @@ -265,16 +274,16 @@ exp : SIZEOF exp %prec UNARY exp : exp ARROW name { write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_elt_type (NULL); write_exp_string ($3); write_exp_elt_opcode (STRUCTOP_PTR); } ; -exp : exp ARROW qualified_name - { /* exp->type::name becomes exp->*(&type::name) */ - /* Note: this doesn't work if name is a - static member! FIXME */ - write_exp_elt_opcode (UNOP_ADDR); - write_exp_elt_opcode (STRUCTOP_MPTR); } +exp : exp ARROW typebase_coloncolon name + { write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_elt_type ($3); + write_exp_string ($4); + write_exp_elt_opcode (STRUCTOP_PTR); } ; exp : exp ARROW '*' exp { write_exp_elt_opcode (STRUCTOP_MPTR); } @@ -282,16 +291,16 @@ exp : exp ARROW '*' exp exp : exp '.' name { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_elt_type (NULL); write_exp_string ($3); write_exp_elt_opcode (STRUCTOP_STRUCT); } ; -exp : exp '.' qualified_name - { /* exp.type::name becomes exp.*(&type::name) */ - /* Note: this doesn't work if name is a - static member! FIXME */ - write_exp_elt_opcode (UNOP_ADDR); - write_exp_elt_opcode (STRUCTOP_MEMBER); } +exp : exp '.' typebase_coloncolon name + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_elt_type ($3); + write_exp_string ($4); + write_exp_elt_opcode (STRUCTOP_STRUCT); } ; exp : exp '.' '*' exp @@ -576,7 +585,9 @@ variable: block COLONCOLON name write_exp_elt_opcode (OP_VAR_VALUE); } ; -qualified_name: typebase COLONCOLON name +typebase_coloncolon : typebase COLONCOLON { current_type = $1; $$ = $1; } + +qualified_name: typebase_coloncolon name { struct type *type = $1; if (TYPE_CODE (type) != TYPE_CODE_STRUCT @@ -586,10 +597,11 @@ qualified_name: typebase COLONCOLON name write_exp_elt_opcode (OP_SCOPE); write_exp_elt_type (type); - write_exp_string ($3); + write_exp_string ($2); write_exp_elt_opcode (OP_SCOPE); + current_type = NULL; } - | typebase COLONCOLON '~' name + | typebase_coloncolon '~' name { struct type *type = $1; struct stoken tmp_token; @@ -598,19 +610,20 @@ qualified_name: typebase COLONCOLON name error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); - if (strcmp (type_name_no_tag (type), $4.ptr)) + if (strcmp (type_name_no_tag (type), $3.ptr)) error ("invalid destructor `%s::~%s'", - type_name_no_tag (type), $4.ptr); + type_name_no_tag (type), $3.ptr); - tmp_token.ptr = (char*) alloca ($4.length + 2); - tmp_token.length = $4.length + 1; + tmp_token.ptr = (char*) alloca ($3.length + 2); + tmp_token.length = $3.length + 1; tmp_token.ptr[0] = '~'; - memcpy (tmp_token.ptr+1, $4.ptr, $4.length); + memcpy (tmp_token.ptr+1, $3.ptr, $3.length); tmp_token.ptr[tmp_token.length] = 0; write_exp_elt_opcode (OP_SCOPE); write_exp_elt_type (type); write_exp_string (tmp_token); write_exp_elt_opcode (OP_SCOPE); + current_type = NULL; } ; @@ -822,9 +835,15 @@ func_mod: '(' ')' { free ((PTR)$2); $$ = 0; } ; +qualified_type: typebase_coloncolon NESTED_TYPE + { $$ = $2; current_type = NULL; } + ; + type : ptype - | typebase COLONCOLON '*' - { $$ = lookup_member_type (builtin_type_int, $1); } + | qualified_type + | typebase_coloncolon '*' + { $$ = lookup_member_type (builtin_type_int, $1); + current_type = NULL; } | type '(' typebase COLONCOLON '*' ')' { $$ = lookup_member_type ($1, $3); } | type '(' typebase COLONCOLON '*' ')' '(' ')' @@ -876,6 +895,10 @@ typebase | ENUM name { $$ = lookup_enum (copy_name ($2), expression_context_block); } + | STRUCT qualified_type { $$ = check_struct ($2); } + | CLASS qualified_type { $$ = check_struct ($2); } + | UNION qualified_type { $$ = check_union ($2); } + | ENUM qualified_type { $$ = check_enum ($2); } | UNSIGNED typename { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); } | UNSIGNED @@ -1419,6 +1442,17 @@ yylex () return VARIABLE; } + if (current_type) + { + struct type *t = + find_nested_type (current_type, copy_name (yylval.sval)); + if (t) + { + yylval.tval = t; + return NESTED_TYPE; + } + } + /* Use token-type BLOCKNAME for symbols that happen to be defined as functions or symtabs. If this is not so, then ... Use token-type TYPENAME for symbols that happen to be defined |