diff options
author | gdb-2.8.1 <gdb@fsf.org> | 1988-12-16 00:00:00 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-06-03 15:36:31 +0100 |
commit | bb7592f01006b09c846831a9fb9c306307ba34f6 (patch) | |
tree | 83e99233f937d7a06eee7c627543288feb125929 /gdb/expread.y | |
parent | 3bf57d210832b28e9361990830eb722a619f031b (diff) | |
download | gdb-bb7592f01006b09c846831a9fb9c306307ba34f6.zip gdb-bb7592f01006b09c846831a9fb9c306307ba34f6.tar.gz gdb-bb7592f01006b09c846831a9fb9c306307ba34f6.tar.bz2 |
gdb-2.8.1
Diffstat (limited to 'gdb/expread.y')
-rw-r--r-- | gdb/expread.y | 223 |
1 files changed, 206 insertions, 17 deletions
diff --git a/gdb/expread.y b/gdb/expread.y index b112cbc..97628ef 100644 --- a/gdb/expread.y +++ b/gdb/expread.y @@ -43,6 +43,7 @@ static int expout_ptr; static int yylex (); static yyerror (); static void write_exp_elt (); +static void write_exp_elt2 (); static void write_exp_string (); static void start_arglist (); static int end_arglist (); @@ -93,10 +94,14 @@ struct stoken struct block *bval; enum exp_opcode opcode; struct internalvar *ivar; + + struct type **tvec; + int *ivec; } %type <voidval> exp exp1 start variable %type <tval> type typebase +%type <tvec> nonempty_typelist %type <bval> block %token <lval> INT CHAR @@ -122,6 +127,9 @@ struct stoken %token <opcode> ASSIGN_MODIFY +/* C++ */ +%token THIS + %left ',' %left ABOVE_COMMA %right '=' ASSIGN_MODIFY @@ -196,12 +204,20 @@ exp : exp ARROW name write_exp_elt (STRUCTOP_PTR); } ; +exp : exp ARROW '*' exp + { write_exp_elt (STRUCTOP_MPTR); } + ; + exp : exp '.' name { write_exp_elt (STRUCTOP_STRUCT); write_exp_string ($3); write_exp_elt (STRUCTOP_STRUCT); } ; +exp : exp '.' '*' exp + { write_exp_elt (STRUCTOP_MEMBER); } + ; + exp : exp '[' exp1 ']' { write_exp_elt (BINOP_SUBSCRIPT); } ; @@ -352,7 +368,7 @@ exp : CHAR exp : FLOAT { write_exp_elt (OP_DOUBLE); write_exp_elt (builtin_type_double); - write_exp_elt ($1); + write_exp_elt2 ($1); write_exp_elt (OP_DOUBLE); } ; @@ -390,8 +406,17 @@ exp : STRING write_exp_elt (OP_STRING); } ; +/* C++. */ +exp : THIS + { write_exp_elt (OP_THIS); + write_exp_elt (OP_THIS); } + ; + +/* end of C++. */ + block : name - { struct symtab *tem = lookup_symtab (copy_name ($1)); + { + struct symtab *tem = lookup_symtab (copy_name ($1)); struct symbol *sym; if (tem) @@ -406,34 +431,88 @@ block : name else error ("No file or function \"%s\".", copy_name ($1)); - }} + } + } ; block : block COLONCOLON name - { struct symbol *tem + { + struct symbol *tem = lookup_symbol (copy_name ($3), $1, VAR_NAMESPACE); if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error ("No function \"%s\" in specified context.", copy_name ($3)); - $$ = SYMBOL_BLOCK_VALUE (tem); } + $$ = SYMBOL_BLOCK_VALUE (tem); + } ; variable: block COLONCOLON name - { struct symbol *sym; + { + struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, VAR_NAMESPACE); if (sym == 0) error ("No symbol \"%s\" in specified context.", copy_name ($3)); write_exp_elt (OP_VAR_VALUE); write_exp_elt (sym); - write_exp_elt (OP_VAR_VALUE); } + write_exp_elt (OP_VAR_VALUE); + } + ; + +variable: typebase COLONCOLON name + { + struct type *type = $1; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt (OP_SCOPE); + write_exp_elt (type); + write_exp_string ($3); + write_exp_elt (OP_SCOPE); + } + | COLONCOLON name + { + char *name = copy_name ($2); + struct symbol *sym; + int i; + + sym = lookup_symbol_2 (name, 0, VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + break; + } + for (i = 0; i < misc_function_count; i++) + if (!strcmp (misc_function_vector[i].name, name)) + break; + + if (i < misc_function_count) + { + write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_int); + write_exp_elt (misc_function_vector[i].address); + write_exp_elt (OP_LONG); + write_exp_elt (UNOP_MEMVAL); + write_exp_elt (builtin_type_char); + write_exp_elt (UNOP_MEMVAL); + } + else + if (symtab_list == 0) + error ("No symbol table is loaded. Use the \"symbol-file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + } ; variable: NAME { struct symbol *sym; - sym = lookup_symbol (copy_name ($1), - expression_context_block, - VAR_NAMESPACE); + sym = lookup_symbol_1 (copy_name ($1), + expression_context_block, + VAR_NAMESPACE); if (sym) { write_exp_elt (OP_VAR_VALUE); @@ -444,6 +523,32 @@ variable: NAME { register char *arg = copy_name ($1); register int i; + int v, val; + /* C++: see if it hangs off of `this'. Must + not inadvertently convert from a method call + to data ref. */ + v = (int)value_of_this (0); + if (v) + { + val = check_field (v, arg); + if (val) + { + write_exp_elt (OP_THIS); + write_exp_elt (OP_THIS); + write_exp_elt (STRUCTOP_PTR); + write_exp_string ($1); + write_exp_elt (STRUCTOP_PTR); + break; + } + } + sym = lookup_symbol_2 (arg, 0, VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + break; /* YACC-dependent */ + } for (i = 0; i < misc_function_count; i++) if (!strcmp (misc_function_vector[i].name, arg)) break; @@ -471,6 +576,17 @@ variable: NAME type : typebase | type '*' { $$ = lookup_pointer_type ($1); } + | type '&' + { $$ = lookup_reference_type ($1); } + | typebase COLONCOLON '*' + { $$ = lookup_member_type (builtin_type_int, $1); } + | type '(' typebase COLONCOLON '*' ')' + { $$ = lookup_member_type ($1, $3); } + | type '(' typebase COLONCOLON '*' ')' '(' ')' + { $$ = lookup_member_type (lookup_function_type ($1, 0), $3); } + | type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')' + { $$ = lookup_member_type (lookup_function_type ($1, $8), $3); + free ($8); } ; typebase @@ -490,6 +606,19 @@ typebase { $$ = lookup_unsigned_typename (copy_name ($2)); } ; +nonempty_typelist + : type + { $$ = (struct type **)xmalloc (sizeof (struct type *) * 2); + $$[0] = (struct type *)0; + $$[1] = $1; + } + | nonempty_typelist ',' type + { int len = sizeof (struct type *) * ++($<ivec>1[0]); + $$ = (struct type **)xrealloc ($1, len); + $$[$<ivec>$[0]] = $3; + } + ; + name : NAME | TYPENAME ; @@ -543,10 +672,16 @@ free_funcalls () /* Add one element to the end of the expression. */ +/* To avoid a bug in the Sun 4 compiler, we pass only things that + can fit into a single register through here. */ static void write_exp_elt (expelt) - union exp_element expelt; + /* union exp_element expelt; */ + long expelt; { + union exp_element temp; + temp.longconst = expelt; + if (expout_ptr >= expout_size) { expout_size *= 2; @@ -554,7 +689,25 @@ write_exp_elt (expelt) sizeof (struct expression) + expout_size * sizeof (union exp_element)); } - expout->elts[expout_ptr++] = expelt; + expout->elts[expout_ptr++] = /* expelt */ temp; +} + +/* Things that take more space must come through here. */ +static void +write_exp_elt2 (expelt) + double expelt; +{ + union exp_element temp; + temp.doubleconst = expelt; + + if (expout_ptr >= expout_size) + { + expout_size *= 2; + expout = (struct expression *) xrealloc (expout, + sizeof (struct expression) + + expout_size * sizeof (union exp_element)); + } + expout->elts[expout_ptr++] = temp; } /* Add a string constant to the end of the expression. @@ -904,13 +1057,23 @@ yylex () { return STRUCT; } - if (namelen == 5 && !strncmp (tokstart, "union", 5)) + if (namelen == 5) { - return UNION; + if (!strncmp (tokstart, "union", 5)) + { + return UNION; + } } - if (namelen == 4 && !strncmp (tokstart, "enum", 4)) + if (namelen == 4) { - return ENUM; + if (!strncmp (tokstart, "enum", 4)) + { + return ENUM; + } + if (!strncmp (tokstart, "this", 4)) + { + return THIS; + } } if (namelen == 6 && !strncmp (tokstart, "sizeof", 6)) { @@ -991,10 +1154,20 @@ length_of_subexp (expr, endpos) register int args = 0; register int i; + if (endpos < 0) + error ("?error in length_of_subexp"); + i = (int) expr->elts[endpos - 1].opcode; switch (i) { + /* C++ */ + case OP_SCOPE: + oplen = 4 + ((expr->elts[endpos - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + case OP_LONG: case OP_DOUBLE: oplen = 4; @@ -1025,7 +1198,6 @@ length_of_subexp (expr, endpos) oplen = 3 + ((expr->elts[endpos - 2].longconst + sizeof (union exp_element)) / sizeof (union exp_element)); - break; case TERNOP_COND: @@ -1037,6 +1209,11 @@ length_of_subexp (expr, endpos) args = 2; break; + /* C++ */ + case OP_THIS: + oplen = 2; + break; + default: args = 1 + (i < (int) BINOP_END); } @@ -1074,6 +1251,13 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg) opcode = inexpr->elts[inend - 1].opcode; switch (opcode) { + /* C++ */ + case OP_SCOPE: + oplen = 4 + ((inexpr->elts[inend - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + case OP_LONG: case OP_DOUBLE: oplen = 4; @@ -1116,6 +1300,11 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg) args = 2; break; + /* C++ */ + case OP_THIS: + oplen = 2; + break; + default: args = 1 + ((int) opcode < (int) BINOP_END); } |