diff options
Diffstat (limited to 'gdb/expread.y')
-rw-r--r-- | gdb/expread.y | 235 |
1 files changed, 213 insertions, 22 deletions
diff --git a/gdb/expread.y b/gdb/expread.y index 468d409..d9a18ea 100644 --- a/gdb/expread.y +++ b/gdb/expread.y @@ -93,10 +93,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 +126,9 @@ struct stoken %token <opcode> ASSIGN_MODIFY +/* C++ */ +%token THIS + %left ',' %left ABOVE_COMMA %right '=' ASSIGN_MODIFY @@ -196,12 +203,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); } ; @@ -390,8 +405,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 +430,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); } + copy_name ($1)); + $$ = SYMBOL_BLOCK_VALUE (tem); + } ; variable: block COLONCOLON name - { struct symbol *sym; - sym = lookup_symbol ($3, copy_name ($1), VAR_NAMESPACE); + { + 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 +522,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 +575,17 @@ variable: NAME type : typebase | type '*' { $$ = lookup_pointer_type ($1); } + | type '&' + { $$ = lookup_reference_type ($1); } + | typebase COLONCOLON '*' + { $$ = lookup_member_pointer_type (builtin_type_int, $1); } + | type '(' typebase COLONCOLON '*' ')' + { $$ = lookup_member_pointer_type ($1, $3); } + | type '(' typebase COLONCOLON '*' ')' '(' ')' + { $$ = lookup_member_pointer_type (lookup_function_type ($1, 0), $3); } + | type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')' + { $$ = lookup_member_pointer_type (lookup_function_type ($1, $8), $3); + free ($8); } ; typebase @@ -490,6 +605,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 ; @@ -598,6 +726,14 @@ static char *lexptr; static char *namecopy; +/* Current depth in parentheses within the expression. */ + +static int paren_depth; + +/* Nonzero means stop parsing on first comma (if not within parentheses). */ + +static int comma_terminates; + /* Take care of parsing a number (anything that starts with a digit). Set yylval and return the token type; update lexptr. LEN is the number of characters in it. */ @@ -753,6 +889,24 @@ yylex () error ("Invalid character constant."); return CHAR; + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + case '+': case '-': case '*': @@ -766,8 +920,6 @@ yylex () case '@': case '<': case '>': - case '(': - case ')': case '[': case ']': case '.': @@ -776,7 +928,6 @@ yylex () case '=': case '{': case '}': - case ',': lexptr++; return c; @@ -881,13 +1032,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)) { @@ -968,10 +1129,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; @@ -1002,7 +1173,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: @@ -1014,6 +1184,11 @@ length_of_subexp (expr, endpos) args = 2; break; + /* C++ */ + case OP_THIS: + oplen = 2; + break; + default: args = 1 + (i < (int) BINOP_END); } @@ -1051,6 +1226,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; @@ -1093,6 +1275,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); } @@ -1136,10 +1323,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg) if BLOCK is zero, use the block of the selected stack frame. Meanwhile, advance *STRINGPTR to point after the expression, at the first nonwhite character that is not part of the expression - (possibly a null character). */ + (possibly a null character). + + If COMMA is nonzero, stop if a comma is reached. */ struct expression * -parse_c_1 (stringptr, block) +parse_c_1 (stringptr, block, comma) char **stringptr; struct block *block; { @@ -1147,6 +1336,8 @@ parse_c_1 (stringptr, block) lexptr = *stringptr; + comma_terminates = comma; + if (lexptr == 0 || *lexptr == 0) error_no_arg ("expression to compute"); @@ -1182,7 +1373,7 @@ parse_c_expression (string) char *string; { register struct expression *exp; - exp = parse_c_1 (&string, 0); + exp = parse_c_1 (&string, 0, 0); if (*string) error ("Junk after end of expression."); return exp; |