From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11160 invoked by alias); 2 May 2002 12:50:20 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 11132 invoked from network); 2 May 2002 12:50:14 -0000 Received: from unknown (HELO cerbere.u-strasbg.fr) (130.79.112.7) by sources.redhat.com with SMTP; 2 May 2002 12:50:14 -0000 Received: from laocoon (laocoon.u-strasbg.fr [130.79.112.72]) by cerbere.u-strasbg.fr (8.9.3/8.8.7) with ESMTP id OAA25603 for ; Thu, 2 May 2002 14:50:13 +0200 Message-Id: <4.2.0.58.20020502144659.02489e38@ics.u-strasbg.fr> X-Sender: muller@ics.u-strasbg.fr Date: Thu, 02 May 2002 05:50:00 -0000 To: gdb-patches@sources.redhat.com From: Pierre Muller Subject: Resend: [RFC] p-exp.y enhancements. Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_10306880==_" X-SW-Source: 2002-05/txt/msg00033.txt.bz2 --=====================_10306880==_ Content-Type: text/plain; charset="us-ascii" Content-length: 1922 (Second posting with the patch attached, this way you should have less problems to apply the patch). This patch has several benefits: 1) it adds support for S[exp] if S is a pascal string. I must admit that this only works for Free Pascal Compiler for now, because GPC uses BITSTRING type for the array containg the chars which confuses GDB. I informed the GPC developper team, but their answer seems to be that they didn't really directly change any code regarding debug information output for pascal... 2) it adds support for case insensitive searches of record (pascal struct) fields. 3) It prepares to a more simple RFC about the enhancement to the completer for structure field that I sent some time ago. See http://sources.redhat.com/ml/gdb-patches/2002-04/msg00774.html The way current_type is treated in my patch is not completely correct, in the sense that current_type is often non NULL when it should be NULL (like for instance after an operator like '+' or '*', but this has no influence on its functionallity, so I did not add all the rules that would reset current_type (which would have made the patch much bigger). If I get no observations about this patch, I will commit it in the next days. 2002-05-02 Pierre Muller * p-exp.y (current_type): New static variable. Carries the type of the expression at the position that is parsed. (push_current_type, pop_current_type): Two new functions. Used to store/restore current_type in expression on specific tokens. (search_filed): New static variable. Set to one after parsing a point as at that point only a FIELDNAME token should be searched. (FIELDNAME): New token. After a point only a token belonging to current_type type definition is allowed. (all over token rules): reset and change current_type according to rules. (exp '[' rule): insert implicit array index field if exp is a pascal string type. --=====================_10306880==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="p-exp.dif" Content-length: 9767 Index: p-exp.y =================================================================== RCS file: /cvs/src/src/gdb/p-exp.y,v retrieving revision 1.10 diff -u -p -r1.10 p-exp.y --- p-exp.y 25 Apr 2002 14:51:29 -0000 1.10 +++ p-exp.y 2 May 2002 12:33:26 -0000 @@ -150,9 +150,15 @@ static char * uptok (char *, int); /* YYSTYPE gets defined by %union */ static int parse_number (char *, int, int, YYSTYPE *); + +static struct type *current_type; + +static void push_current_type (); +static void pop_current_type (); +static int search_field; %} -%type exp exp1 type_exp start variable qualified_name +%type exp exp1 type_exp start normal_start variable qualified_name %type type typebase /* %type block */ @@ -170,7 +176,8 @@ parse_number (char *, int, int, YYSTYPE Contexts where this distinction is not important can use the nonterminal "name", which matches either NAME or TYPENAME. */ -%token STRING +%token STRING +%token FIELDNAME %token NAME /* BLOCKNAME defined below to give it higher precedence. */ %token TYPENAME %type name @@ -219,15 +226,21 @@ parse_number (char *, int, int, YYSTYPE %% -start : exp1 +start : { current_type = NULL; + search_field = 0; + } + normal_start; + +normal_start : + exp1 | type_exp ; type_exp: type { write_exp_elt_opcode(OP_TYPE); write_exp_elt_type($1); - write_exp_elt_opcode(OP_TYPE);} - ; + write_exp_elt_opcode(OP_TYPE); + current_type = $1; } ; /* Expressions, including the comma operator. */ exp1 : exp @@ -237,10 +250,14 @@ exp1 : exp /* Expressions, not including the comma operator. */ exp : exp '^' %prec UNARY - { write_exp_elt_opcode (UNOP_IND); } + { write_exp_elt_opcode (UNOP_IND); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); } exp : '@' exp %prec UNARY - { write_exp_elt_opcode (UNOP_ADDR); } + { write_exp_elt_opcode (UNOP_ADDR); + if (current_type) + current_type = TYPE_POINTER_TYPE (current_type); } exp : '-' exp %prec UNARY { write_exp_elt_opcode (UNOP_NEG); } @@ -258,24 +275,55 @@ exp : DECREMENT '(' exp ')' %prec UNA { write_exp_elt_opcode (UNOP_PREDECREMENT); } ; -exp : exp '.' name +exp : exp '.' { search_field = 1; } + FIELDNAME + /* name */ { write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($3); - write_exp_elt_opcode (STRUCTOP_STRUCT); } - ; - -exp : exp '[' exp1 ']' - { write_exp_elt_opcode (BINOP_SUBSCRIPT); } - ; + write_exp_string ($4); + write_exp_elt_opcode (STRUCTOP_STRUCT); + search_field = 0; + if (current_type) + { while (TYPE_CODE (current_type) == TYPE_CODE_PTR) + current_type = TYPE_TARGET_TYPE (current_type); + current_type = lookup_struct_elt_type ( + current_type, $4.ptr, false); }; + } ; +exp : exp '[' + /* We need to save the current_type value */ + { char *arrayname; + int arrayfieldindex; + arrayfieldindex = is_pascal_string_type ( + current_type, NULL, NULL, + NULL, NULL, &arrayname); + if (arrayfieldindex) + { + struct stoken stringsval; + stringsval.ptr = alloca (strlen (arrayname) + 1); + stringsval.length = strlen (arrayname); + strcpy (stringsval.ptr, arrayname); + current_type = TYPE_FIELD_TYPE (current_type, + arrayfieldindex - 1); + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (stringsval); + write_exp_elt_opcode (STRUCTOP_STRUCT); + } + push_current_type (); } + exp1 ']' + { pop_current_type (); + write_exp_elt_opcode (BINOP_SUBSCRIPT); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); } exp : exp '(' /* This is to save the value of arglist_len being accumulated by an outer function call. */ - { start_arglist (); } + { push_current_type (); + start_arglist (); } arglist ')' %prec ARROW { write_exp_elt_opcode (OP_FUNCALL); write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); } + write_exp_elt_opcode (OP_FUNCALL); + pop_current_type (); } ; arglist : @@ -288,7 +336,8 @@ arglist : exp : type '(' exp ')' %prec UNARY { write_exp_elt_opcode (UNOP_CAST); write_exp_elt_type ($1); - write_exp_elt_opcode (UNOP_CAST); } + write_exp_elt_opcode (UNOP_CAST); + current_type = $1; } ; exp : '(' exp1 ')' @@ -567,9 +616,11 @@ variable: name_not_typename write_exp_elt_block (NULL); write_exp_elt_sym (sym); write_exp_elt_opcode (OP_VAR_VALUE); - } + current_type = sym->type; } else if ($1.is_a_field_of_this) { + struct value * this_val; + struct type * this_type; /* Object pascal: it hangs off of `this'. Must not inadvertently convert from a method call to data ref. */ @@ -581,6 +632,18 @@ variable: name_not_typename write_exp_elt_opcode (STRUCTOP_PTR); write_exp_string ($1.stoken); write_exp_elt_opcode (STRUCTOP_PTR); + /* we need type of this */ + this_val = value_of_this (0); + if (this_val) + this_type = this_val->type; + else + this_type = NULL; + if (this_type) + current_type = lookup_struct_elt_type ( + this_type, + $1.stoken.ptr, false); + else + current_type = NULL; } else { @@ -881,6 +944,36 @@ parse_number (p, len, parsed_float, puti return INT; } + +struct type_push +{ + struct type *stored; + struct type_push *next; +}; + +static struct type_push *tp_top = NULL; + +static void push_current_type () +{ + struct type_push *tpnew; + tpnew = (struct type_push *) malloc (sizeof (struct type_push)); + tpnew->next = tp_top; + tpnew->stored = current_type; + current_type = NULL; + tp_top = tpnew; +} + +static void pop_current_type () +{ + struct type_push *tp = tp_top; + if (tp) + { + current_type = tp->stored; + tp_top = tp->next; + xfree (tp); + } +} + struct token { char *operator; @@ -907,8 +1000,8 @@ static const struct token tokentab2[] = {"<>", NOTEQUAL, BINOP_END}, {"<=", LEQ, BINOP_END}, {">=", GEQ, BINOP_END}, - {":=", ASSIGN, BINOP_END} - }; + {":=", ASSIGN, BINOP_END}, + {"::", COLONCOLON, BINOP_END} }; /* Allocate uppercased var */ /* make an uppercased copy of tokstart */ @@ -1149,6 +1242,7 @@ yylex () { tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); } + switch (*tokptr) { case '\0': @@ -1295,25 +1389,37 @@ yylex () char *tmp = copy_name (yylval.sval); struct symbol *sym; int is_a_field_of_this = 0; + int is_a_field = 0; int hextype; - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, - &is_a_field_of_this, - (struct symtab **) NULL); + + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_NAMESPACE, + &is_a_field_of_this, + (struct symtab **) NULL); /* second chance uppercased (as Free Pascal does). */ - if (!sym && !is_a_field_of_this) + if (!sym && !is_a_field_of_this && !is_a_field) { for (i = 0; i <= namelen; i++) { if ((tmp[i] >= 'a' && tmp[i] <= 'z')) tmp[i] -= ('a'-'A'); } - sym = lookup_symbol (tmp, expression_context_block, + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE, &is_a_field_of_this, (struct symtab **) NULL); - if (sym || is_a_field_of_this) + if (sym || is_a_field_of_this || is_a_field) for (i = 0; i <= namelen; i++) { if ((tokstart[i] >= 'a' && tokstart[i] <= 'z')) @@ -1321,7 +1427,7 @@ yylex () } } /* Third chance Capitalized (as GPC does). */ - if (!sym && !is_a_field_of_this) + if (!sym && !is_a_field_of_this && !is_a_field) { for (i = 0; i <= namelen; i++) { @@ -1334,11 +1440,16 @@ yylex () if ((tmp[i] >= 'A' && tmp[i] <= 'Z')) tmp[i] -= ('A'-'a'); } - sym = lookup_symbol (tmp, expression_context_block, + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE, &is_a_field_of_this, (struct symtab **) NULL); - if (sym || is_a_field_of_this) + if (sym || is_a_field_of_this || is_a_field) for (i = 0; i <= namelen; i++) { if (i == 0) @@ -1351,6 +1462,15 @@ yylex () tokstart[i] -= ('A'-'a'); } } + + if (is_a_field) + { + tempbuf = (char *) realloc (tempbuf, namelen + 1); + strncpy (tempbuf, tokstart, namelen); tempbuf [namelen] = 0; + yylval.sval.ptr = tempbuf; + yylval.sval.length = namelen; + return FIELDNAME; + } /* Call lookup_symtab, not lookup_partial_symtab, in case there are no psymtabs (coff, xcoff, or some future change to blow away the psymtabs once once symbols are read). */ --=====================_10306880==_ Content-Type: text/plain; charset="us-ascii" Content-length: 176 Pierre Muller Institut Charles Sadron 6,rue Boussingault F 67083 STRASBOURG CEDEX (France) mailto:muller@ics.u-strasbg.fr Phone : (33)-3-88-41-40-07 Fax : (33)-3-88-41-40-99 --=====================_10306880==_--