From: gdb-2.5.2 Date: Wed, 1 Jun 1988 00:00:00 +0000 (+0100) Subject: gdb-2.5.2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6368691e88d78f0bb6a46b74d7ed86118ac84e8b;p=binutils-gdb.git gdb-2.5.2 --- diff --git a/gdb/dbxread.c b/gdb/dbxread.c index c1c4acc5c9c..05326cf5b40 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1744,8 +1744,7 @@ condense_addl_misc_bunches () } /**************************** ADD_FILE_COMMAND() ****************************/ -/* This function allows the addition of incrementally linked object files. - Useful for debugging `sun_kick'. */ +/* This function allows the addition of incrementally linked object files. */ void add_file_command (arg_string) @@ -1762,116 +1761,107 @@ add_file_command (arg_string) char* name; unsigned text_addr; + if (arg_string == 0) + error ("add-file takes a file name and an address"); + for( ; *arg_string == ' '; arg_string++ ); name = arg_string; - for( ; *arg_string != ' ' ; arg_string++ ); + for( ; *arg_string && *arg_string != ' ' ; arg_string++ ); *arg_string++ = (char) 0; - for( ; *arg_string == ' '; arg_string++ ); - text_addr = (unsigned) atoi(arg_string); - printf("filename \"%s\", and text_addr = 0x%x\n", name, text_addr ); + if (name[0] == 0) + error ("add-file takes a file name and an address"); + + text_addr = parse_and_eval_address (arg_string); dont_repeat (); - if (name == 0) + if (query ("add symbol table from filename \"%s\" at text_addr = 0x%x\n", name, text_addr)) { - if (symtab_list && !query ("Discard symbol table? ", 0)) - error ("Not confirmed."); - free_all_symtabs (); - return; - } + desc = open (name, O_RDONLY); + if (desc < 0) + perror_with_name (name); - /* if (symtab_list && !query ("Add new symbols from \"%s\"? ", name)) - error ("Not confirmed."); - */ - { - char *absolute_name; - desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name); - if (desc < 0) - perror_with_name (name); - else - name = absolute_name; - } + old_chain = make_cleanup (close, desc); + make_cleanup (free_current_contents, &name); - old_chain = make_cleanup (close, desc); - make_cleanup (free_current_contents, &name); + val = myread (desc, &hdr, sizeof hdr); + if (val < 0) + perror_with_name (name); - val = myread (desc, &hdr, sizeof hdr); - if (val < 0) - perror_with_name (name); + if (N_BADMAG (hdr)) + error ("File \"%s\" has a bad header.", name); - if (N_BADMAG (hdr)) - error ("File \"%s\" has a bad header.", name); + if (hdr.a_syms == 0) + { + printf ("%s does not have a symbol-table.\n", name); + fflush (stdout); + return; + } - if (hdr.a_syms == 0) - { - printf ("%s does not have a symbol-table.\n", name); + /* Now read the string table, all at once. */ + val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); + if (val < 0) + perror_with_name (name); + val = myread (desc, &buffer, sizeof buffer); + if (val < 0) + perror_with_name (name); + stringtab = (char *) alloca (buffer); + bcopy (&buffer, stringtab, sizeof buffer); + val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); + if (val < 0) + perror_with_name (name); + + /* That puts us at the symsegs. Read them. ########## Also need other + changes if they exist. */ + + /* Position to read the symbol table. Do not read it all at once. */ + val = lseek (desc, N_SYMOFF (hdr), 0); + if (val < 0) + perror_with_name (name); + + printf ("Reading symbol data from %s...", name); fflush (stdout); - return; - } - - /* Now read the string table, all at once. */ - val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); - if (val < 0) - perror_with_name (name); - val = myread (desc, &buffer, sizeof buffer); - if (val < 0) - perror_with_name (name); - stringtab = (char *) alloca (buffer); - bcopy (&buffer, stringtab, sizeof buffer); - val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); - if (val < 0) - perror_with_name (name); - /* That puts us at the symsegs. Read them. ########## Also need other - changes if they exist. */ + init_misc_functions (); + make_cleanup (discard_misc_bunches, 0); + init_header_files (); + make_cleanup (free_header_files, 0); + read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist), + text_addr, hdr.a_text) ; - /* Position to read the symbol table. Do not read it all at once. */ - val = lseek (desc, N_SYMOFF (hdr), 0); - if (val < 0) - perror_with_name (name); + /* Sort symbols alphabetically within each block. */ - printf ("Reading symbol data from %s...", name); - fflush (stdout); + sort_syms (); - init_misc_functions (); - make_cleanup (discard_misc_bunches, 0); - init_header_files (); - make_cleanup (free_header_files, 0); + /* Go over the all misc functions and install them in vector. */ - read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist) - ,text_addr, hdr.a_text) ; + condense_addl_misc_bunches (); - /* Sort symbols alphabetically within each block. */ + /* Don't allow char * to have a typename (else would get caddr_t.) */ - sort_syms (); + TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - /* Go over the all misc functions and install them in vector. */ + /* Make a default for file to list. */ - condense_addl_misc_bunches (); + select_source_symtab (symtab_list); - /* Don't allow char * to have a typename (else would get caddr_t.) */ + do_cleanups (old_chain); - TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - - /* Make a default for file to list. */ - - select_source_symtab (symtab_list); - - do_cleanups (old_chain); + /* Free the symtabs made by read_symsegs, but not their contents, + which have been copied into symtabs on symtab_list. */ + while (symseg_chain) + { + register struct symtab *s = symseg_chain->next; + free (symseg_chain); + symseg_chain = s; + } - /* Free the symtabs made by read_symsegs, but not their contents, - which have been copied into symtabs on symtab_list. */ - while (symseg_chain) - { - register struct symtab *s = symseg_chain->next; - free (symseg_chain); - symseg_chain = s; + printf ("done.\n"); + fflush (stdout); } - - printf ("done.\n"); - fflush (stdout); + else error ("Not confirmed."); } static struct symbol * @@ -2174,15 +2164,15 @@ read_type (pp) { struct type *domain = read_type (pp); char c; - struct type *ptrtype; + struct type *memtype; if (*(*pp)++ != ',') - error ("invalid member pointer data format, at symtab pos %d.", + error ("invalid member type data format, at symtab pos %d.", symnum); - ptrtype = read_type (pp); + memtype = read_type (pp); type = dbx_alloc_type (typenums); - smash_to_member_pointer_type (type, domain, ptrtype); + smash_to_member_type (type, domain, memtype); } break; diff --git a/gdb/expread.tab.c b/gdb/expread.tab.c index e676cf8ef08..8974bd5ce47 100644 --- a/gdb/expread.tab.c +++ b/gdb/expread.tab.c @@ -420,32 +420,40 @@ the terms of Paragraph 1 above, provided that you also do the following: that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more - extensive warranty protection to third parties, at your option). + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 3. You may copy and distribute this program or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, - c) in the case of a recipient of this program in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt @@ -504,7 +512,11 @@ YYSTYPE yylval; /* the semantic value of the */ YYLTYPE yylloc; /* location data for the lookahead */ /* symbol */ +int yynerr; /* number of parse errors so far */ + +#ifdef YYDEBUG int yydebug = 0; /* nonzero means print parse trace */ +#endif #endif /* YYIMPURE */ @@ -523,7 +535,7 @@ int yydebug = 0; /* nonzero means print parse trace */ #endif -#line 87 "bison.simple" +#line 165 "bison.simple" int yyparse() { @@ -551,7 +563,9 @@ yyparse() YYSTYPE yylval; YYLTYPE yylloc; +#ifdef YYDEBUG extern int yydebug; +#endif #endif @@ -562,11 +576,14 @@ yyparse() int yylen; +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Starting parse\n"); +#endif yystate = 0; yyerrstatus = 0; + yynerr = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. @@ -624,15 +641,19 @@ yynewstate: yylsp = yyls + size - 1; yyvsp = yyvs + size - 1; +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Stack size increased to %d\n", yymaxdepth); +#endif if (yyssp >= yyss + yymaxdepth - 1) YYERROR; } +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Entering state %d\n", yystate); +#endif /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ @@ -651,6 +672,10 @@ yyresume: if (yychar == YYEMPTY) { +#ifdef YYDEBUG + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif yychar = YYLEX; } @@ -661,15 +686,19 @@ yyresume: yychar1 = 0; yychar = YYEOF; /* Don't call YYLEX any more */ +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Now at end of input.\n"); +#endif } else { yychar1 = YYTRANSLATE(yychar); +#ifdef YYDEBUG if (yydebug) - fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]); + fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]); +#endif } yyn += yychar1; @@ -700,8 +729,10 @@ yyresume: /* Shift the lookahead token. */ +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) @@ -728,6 +759,7 @@ yyreduce: yylen = yyr2[yyn]; yyval = yyvsp[1-yylen]; /* implement default value of the action */ +#ifdef YYDEBUG if (yydebug) { if (yylen == 1) @@ -737,6 +769,7 @@ yyreduce: fprintf (stderr, "Reducing %d values via line %d, ", yylen, yyrline[yyn]); } +#endif switch (yyn) { @@ -1161,19 +1194,19 @@ case 67: break;} case 68: #line 581 "expread.y" -{ yyval.tval = lookup_member_pointer_type (builtin_type_int, yyvsp[-2].tval); ; +{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ; break;} case 69: #line 583 "expread.y" -{ yyval.tval = lookup_member_pointer_type (yyvsp[-5].tval, yyvsp[-3].tval); ; +{ yyval.tval = lookup_member_type (yyvsp[-5].tval, yyvsp[-3].tval); ; break;} case 70: #line 585 "expread.y" -{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ; +{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ; break;} case 71: #line 587 "expread.y" -{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval); +{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval); free (yyvsp[-1].tvec); ; break;} case 72: @@ -1222,6 +1255,7 @@ case 78: yylsp -= yylen; yyssp -= yylen; +#ifdef YYDEBUG if (yydebug) { short *ssp1 = yyss - 1; @@ -1230,6 +1264,7 @@ case 78: fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } +#endif *++yyvsp = yyval; @@ -1268,11 +1303,8 @@ yyerrlab: /* here on detecting error */ if (! yyerrstatus) /* If not already recovering from an error, report this error. */ { -#ifdef ESKIT - db_yyerror("parse error", yyssp, yychar); -#else + ++yynerr; yyerror("parse error"); -#endif } if (yyerrstatus == 3) @@ -1283,8 +1315,10 @@ yyerrlab: /* here on detecting error */ if (yychar == YYEOF) YYERROR; +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif yychar = YYEMPTY; } @@ -1312,6 +1346,7 @@ yyerrpop: /* pop the current state because it cannot handle the error token */ yylsp--; yystate = *--yyssp; +#ifdef YYDEBUG if (yydebug) { short *ssp1 = yyss - 1; @@ -1320,6 +1355,7 @@ yyerrpop: /* pop the current state because it cannot handle the error token */ fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } +#endif yyerrhandle: @@ -1345,8 +1381,10 @@ yyerrhandle: if (yyn == YYFINAL) YYACCEPT; +#ifdef YYDEBUG if (yydebug) fprintf(stderr, "Shifting error token, "); +#endif *++yyvsp = yylval; *++yylsp = yylloc; diff --git a/gdb/expread.y b/gdb/expread.y index d9a18ead9b4..996ca219fcf 100644 --- a/gdb/expread.y +++ b/gdb/expread.y @@ -578,13 +578,13 @@ type : typebase | type '&' { $$ = lookup_reference_type ($1); } | typebase COLONCOLON '*' - { $$ = lookup_member_pointer_type (builtin_type_int, $1); } + { $$ = lookup_member_type (builtin_type_int, $1); } | type '(' typebase COLONCOLON '*' ')' - { $$ = lookup_member_pointer_type ($1, $3); } + { $$ = lookup_member_type ($1, $3); } | type '(' typebase COLONCOLON '*' ')' '(' ')' - { $$ = lookup_member_pointer_type (lookup_function_type ($1, 0), $3); } + { $$ = lookup_member_type (lookup_function_type ($1, 0), $3); } | type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')' - { $$ = lookup_member_pointer_type (lookup_function_type ($1, $8), $3); + { $$ = lookup_member_type (lookup_function_type ($1, $8), $3); free ($8); } ; diff --git a/gdb/expression.h b/gdb/expression.h index ee3791f253b..0fac7be1d12 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -62,6 +62,8 @@ enum exp_opcode BINOP_EXP, /* Exponentiation */ /* C++. */ + BINOP_MIN, /* ? */ BINOP_SCOPE, /* :: */ /* STRUCTOP_MEMBER is used for pointer-to-member constructs. diff --git a/gdb/gdb+.texinfo b/gdb/gdb+.texinfo index 627f7adf2c7..0591073f959 100644 --- a/gdb/gdb+.texinfo +++ b/gdb/gdb+.texinfo @@ -397,6 +397,13 @@ executable file. @samp{core-file} with no argument specifies that no core file is to be used. +@item add-file @var{filename} @var{address} +When performing incremental linking, the symbol table of an incrementally +linked file may be included in the link step, but GDB+ needs to be told +where that symbol table is in the address space. By issuing this command, +it is possible to symbolically debug programs which make use of incremental +loading in a completely natural fashion. + @item kill @kindex kill Cancel running the program under GDB+. This could be used if you wish diff --git a/gdb/symseg.h b/gdb/symseg.h index f5ad8ea92ed..7b16f8f4a10 100644 --- a/gdb/symseg.h +++ b/gdb/symseg.h @@ -120,7 +120,7 @@ enum type_code TYPE_CODE_PASCAL_ARRAY, /* Array with explicit type of index */ /* C++ */ - TYPE_CODE_MPTR, /* Member pointer type */ + TYPE_CODE_MEMBER, /* Member type */ TYPE_CODE_REF, /* C++ Reference types */ }; diff --git a/gdb/symtab.c b/gdb/symtab.c index 5540954ff9f..ec6f0d69823 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -236,63 +236,54 @@ lookup_reference_type (type) } -/* Given a type TYPE, return a type of pointers to that type. +/* Implement direct support for MEMBER_TYPE in GNU C++. May need to construct such a type if this is the first use. The TYPE is the type of the member. The DOMAIN is the type of the aggregate that the member belongs to. */ struct type * -lookup_member_pointer_type (type, domain) +lookup_member_type (type, domain) struct type *type, *domain; { - register struct type *ptype = TYPE_POINTER_TYPE (type); + register struct type *mtype = TYPE_MAIN_VARIANT (type); struct type *main_type; - if (ptype) - { - ptype = TYPE_MAIN_VARIANT (ptype); - main_type = ptype; - while (ptype) - { - if (TYPE_DOMAIN_TYPE (ptype) == domain) - return ptype; - ptype = TYPE_CHAIN (ptype); - } - } - else + main_type = mtype; + while (mtype) { - main_type = lookup_pointer_type (type); - TYPE_POINTER_TYPE (type) = main_type; + if (TYPE_DOMAIN_TYPE (mtype) == domain) + return mtype; + mtype = TYPE_CHAIN (mtype); } - /* This is the first time anyone wanted a pointer to a TYPE. */ + /* This is the first time anyone wanted this member type. */ if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) - ptype = (struct type *) xmalloc (sizeof (struct type)); + mtype = (struct type *) xmalloc (sizeof (struct type)); else - ptype = (struct type *) obstack_alloc (symbol_obstack, + mtype = (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); - bzero (ptype, sizeof (struct type)); - TYPE_MAIN_VARIANT (ptype) = main_type; - TYPE_TARGET_TYPE (ptype) = type; - TYPE_DOMAIN_TYPE (ptype) = domain; - TYPE_POINTER_TYPE (type) = ptype; + bzero (mtype, sizeof (struct type)); + TYPE_MAIN_VARIANT (mtype) = main_type; + TYPE_TARGET_TYPE (mtype) = type; + TYPE_DOMAIN_TYPE (mtype) = domain; /* New type is permanent if type pointed to is permanent. */ if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) - TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM; - /* We assume the machine has only one representation for pointers! */ - TYPE_LENGTH (ptype) = sizeof (char *); - TYPE_CODE (ptype) = TYPE_CODE_MPTR; + TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM; + + /* In practice, this is never used. */ + TYPE_LENGTH (mtype) = 1; + TYPE_CODE (mtype) = TYPE_CODE_MEMBER; /* Now splice in the new member pointer type. */ if (main_type) { /* This type was not "smashed". */ - TYPE_CHAIN (ptype) = TYPE_CHAIN (main_type); - TYPE_CHAIN (main_type) = ptype; + TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type); + TYPE_CHAIN (main_type) = mtype; } - return ptype; + return mtype; } /* Given a type TYPE, return a type of functions that return that type. @@ -348,31 +339,21 @@ smash_to_pointer_type (type, to_type) } } -/* Smash TYPE to be a type of pointers to TO_TYPE. - If TO_TYPE is not permanent and has no pointer-type yet, - record TYPE as its pointer-type. - - TYPE is the type of the member. DOMAIN is the type of - the aggregate that the member belongs to. */ +/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. */ void -smash_to_member_pointer_type (type, domain, to_type) +smash_to_member_type (type, domain, to_type) struct type *type, *domain, *to_type; { bzero (type, sizeof (struct type)); TYPE_TARGET_TYPE (type) = to_type; TYPE_DOMAIN_TYPE (type) = domain; - /* We assume the machine has only one representation for pointers! */ - TYPE_LENGTH (type) = sizeof (char *); - TYPE_CODE (type) = TYPE_CODE_MPTR; - TYPE_MAIN_VARIANT (type) = lookup_pointer_type (to_type); + /* In practice, this is never needed. */ + TYPE_LENGTH (type) = 1; + TYPE_CODE (type) = TYPE_CODE_MEMBER; - if (TYPE_POINTER_TYPE (to_type) == 0 - && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) - { - TYPE_POINTER_TYPE (to_type) = type; - } + TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type); } /* Smash TYPE to be a type of reference to TO_TYPE. diff --git a/gdb/symtab.h b/gdb/symtab.h index d1847663562..d888dc14b00 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -234,7 +234,7 @@ extern int find_pc_misc_function (); /* C++ stuff. */ extern struct type *lookup_reference_type (); -extern struct type *lookup_member_pointer_type (); +extern struct type *lookup_member_type (); extern struct type *lookup_class (); /* end of C++ stuff. */ diff --git a/gdb/valarith.c b/gdb/valarith.c index 03bc1e1e923..6ce7c6af3ee 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -27,6 +27,8 @@ anyone else from sharing it farther. Help stamp out software hoarding! START_FILE +value value_x_binop (); + value value_add (arg1, arg2) value arg1, arg2; @@ -63,7 +65,7 @@ value_add (arg1, arg2) return val; } - return value_binop (arg1, arg2, BINOP_ADD); + return value_x_binop (arg1, arg2, BINOP_ADD); } value @@ -96,7 +98,7 @@ value_sub (arg1, arg2) return val; } - return value_binop (arg1, arg2, BINOP_SUB); + return value_x_binop (arg1, arg2, BINOP_SUB); } /* Return the value of ARRAY[IDX]. */ @@ -107,7 +109,70 @@ value_subscript (array, idx) { return value_ind (value_add (array, idx)); } + +/* Check to see if either argument is a structure. If so, then + create an argument vector that calls arg1.operator @ (arg1,arg2) + and return that value (where '@' is any binary operator which + is legal for GNU C++). If both args are scalar types then just + return value_binop(). */ + +value +value_x_binop (arg1, arg2, op) + value arg1, arg2; + int op; +{ + value * argvec; + char *ptr; + char tstr[13]; + + COERCE_ENUM (arg1); + COERCE_ENUM (arg2); + + if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT + || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT) + { + /* now we know that what we have to do is construct our + arg vector and find the right function to call it with. */ + + if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT) + error ("friend functions not implemented yet"); + + argvec = (value *) alloca (sizeof (value) * 4); + argvec[1] = value_addr (arg1); + argvec[2] = arg2; + argvec[3] = 0; + /* make the right function name up */ + strcpy(tstr,"operator __"); + ptr = tstr+9; + switch (op) + { + case BINOP_ADD: *ptr++ = '+'; *ptr = '\0'; break; + case BINOP_SUB: *ptr++ = '-'; *ptr = '\0'; break; + case BINOP_MUL: *ptr++ = '*'; *ptr = '\0'; break; + case BINOP_DIV: *ptr++ = '/'; *ptr = '\0'; break; + case BINOP_REM: *ptr++ = '%'; *ptr = '\0';break; + case BINOP_LSH: *ptr++ = '<'; *ptr = '<'; break; + case BINOP_RSH: *ptr++ = '>'; *ptr = '>'; break; + case BINOP_LOGAND: *ptr++ = '&'; *ptr = '\0'; break; + case BINOP_LOGIOR: *ptr++ = '|'; *ptr = '\0'; break; + case BINOP_LOGXOR: *ptr++ = '^'; *ptr = '\0'; break; + case BINOP_AND: *ptr++ = '&'; *ptr = '&'; break; + case BINOP_OR: *ptr++ = '|'; *ptr = '|'; break; + case BINOP_MIN: *ptr++ = '<'; *ptr = '?'; break; + case BINOP_MAX: *ptr++ = '>'; *ptr = '?'; break; + default: + error ("Invalid binary operation specified."); + } + argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure"); + if (argvec[0]) + return call_function (argvec[0], 2, argvec + 1); + else error ("member function %s not found", tstr); + } + + return value_binop(arg1, arg2, op); +} + /* Perform a binary operation on two integers or two floats. Does not support addition and subtraction on pointers; use value_add or value_sub if you want to handle those possibilities. */ @@ -219,6 +284,14 @@ value_binop (arg1, arg2, op) v = v1 || v2; break; + case BINOP_MIN: + v = v1 < v2 ? v1 : v2; + break; + + case BINOP_MAX: + v = v1 > v2 ? v1 : v2; + break; + default: error ("Invalid binary operation on numbers."); } diff --git a/gdb/valops.c b/gdb/valops.c index c9629320d86..8992c0fa73b 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -56,17 +56,11 @@ value_cast (type, arg2) return value_from_long (type, value_as_long (arg2)); else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2))) { - if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR)) - printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n"); - VALUE_TYPE (arg2) = type; return arg2; } else if (VALUE_LVAL (arg2) == lval_memory) { - if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR)) - printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n"); - return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2)); } else @@ -286,8 +280,8 @@ value_ind (arg1) { COERCE_ARRAY (arg1); - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MPTR) - error ("not implemented: member pointers in value_ind"); + if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER) + error ("not implemented: member types in value_ind"); /* Allow * on an integer so we can cast it to whatever we want. */ if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) @@ -425,8 +419,13 @@ call_function (function, nargs, args) register struct type *ftype = VALUE_TYPE (function); register enum type_code code = TYPE_CODE (ftype); - if (code == TYPE_CODE_MPTR) - error ("not implemented: member pointer to call_function"); + /* If it's a member function, just look at the function + part of it. */ + if (code == TYPE_CODE_MEMBER) + { + ftype = TYPE_TARGET_TYPE (ftype); + code = TYPE_CODE (ftype); + } /* Determine address to call. */ if (code == TYPE_CODE_FUNC) @@ -601,8 +600,8 @@ value_struct_elt (arg1, args, name, err) t = VALUE_TYPE (arg1); } - if (TYPE_CODE (t) == TYPE_CODE_MPTR) - error ("not implemented: member pointers in value_struct_elt"); + if (TYPE_CODE (t) == TYPE_CODE_MEMBER) + error ("not implemented: member type in value_struct_elt"); if (TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) @@ -809,8 +808,8 @@ check_field (arg1, name) t = VALUE_TYPE (arg1); } - if (TYPE_CODE (t) == TYPE_CODE_MPTR) - error ("not implemented: member pointers in check_field"); + if (TYPE_CODE (t) == TYPE_CODE_MEMBER) + error ("not implemented: member type in check_field"); if (TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) @@ -886,7 +885,7 @@ value_struct_elt_for_address (domain, intype, name) error ("pointers to bitfield members not allowed"); v = value_from_long (builtin_type_int, TYPE_FIELD_BITPOS (t, i) >> 3); - VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FIELD_TYPE (t, i), baseclass); + VALUE_TYPE (v) = lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass); return v; } } @@ -936,7 +935,7 @@ value_struct_elt_for_address (domain, intype, name) 0, VAR_NAMESPACE); v = locate_var_value (s, 0); } - VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FN_FIELD_TYPE (f, j), baseclass); + VALUE_TYPE (v) = lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), baseclass); return v; } } diff --git a/gdb/valprint.c b/gdb/valprint.c index 619c9704a5a..32601a6382a 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -168,147 +168,151 @@ val_print (type, valaddr, address, stream) /* Array of unspecified length: treat like pointer. */ case TYPE_CODE_PTR: - fprintf (stream, "0x%x", * (int *) valaddr); - /* For a pointer to char or unsigned char, - also print the string pointed to, unless pointer is null. */ - if ((TYPE_TARGET_TYPE (type) == builtin_type_char - || TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char) - && unpack_long (type, valaddr) != 0) + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER) { - fputc (' ', stream); - fputc ('"', stream); - for (i = 0; i < print_max; i++) + struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)); + struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)); + struct fn_field *f; + int j, len2; + char *kind = ""; + + val = unpack_long (builtin_type_int, valaddr); + if (TYPE_CODE (target) == TYPE_CODE_FUNC) { - QUIT; - read_memory (unpack_long (type, valaddr) + i, &c, 1); - if (c == 0) - break; - printchar (c, stream); + if (val < 128) + { + len = TYPE_NFN_FIELDS (domain); + for (i = 0; i < len; i++) + { + f = TYPE_FN_FIELDLIST1 (domain, i); + len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + + for (j = 0; j < len2; j++) + { + QUIT; + if (TYPE_FN_FIELD_VOFFSET (f, j) == val) + { + kind = "virtual"; + goto common; + } + } + } + } + else + { + struct symbol *sym = find_pc_function (val); + if (sym == 0) + error ("invalid pointer to member function"); + len = TYPE_NFN_FIELDS (domain); + for (i = 0; i < len; i++) + { + f = TYPE_FN_FIELDLIST1 (domain, i); + len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + + for (j = 0; j < len2; j++) + { + QUIT; + if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) + goto common; + } + } + } + common: + if (i < len) + { + fprintf (stream, "& "); + type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0); + fprintf (stream, kind); + if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' + && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$') + type_print_method_args + (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", + TYPE_FN_FIELDLIST_NAME (domain, i), stream); + else + type_print_method_args + (TYPE_FN_FIELD_ARGS (f, j), "", + TYPE_FN_FIELDLIST_NAME (domain, i), stream); + break; + } + } + else + { + /* VAL is a byte offset into the structure type DOMAIN. + Find the name of the field for that offset and + print it. */ + int extra = 0; + int bits = 0; + len = TYPE_NFIELDS (domain); + val <<= 3; /* @@ Make VAL into bit offset */ + for (i = 0; i < len; i++) + { + int bitpos = TYPE_FIELD_BITPOS (domain, i); + QUIT; + if (val == bitpos) + break; + if (val < bitpos && i > 0) + { + int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target)); + /* Somehow pointing into a field. */ + i -= 1; + extra = (val - TYPE_FIELD_BITPOS (domain, i)); + if (extra & 0x3) + bits = 1; + else + extra >>= 3; + break; + } + } + if (i < len) + { + fprintf (stream, "& "); + type_print_base (domain, stream, 0, 0); + fprintf (stream, "::"); + fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i)); + if (extra) + fprintf (stream, " + %d bytes", extra); + if (bits) + fprintf (stream, " (offset in bits)"); + break; + } + } + fputc ('(', stream); + type_print (type, "", stream, -1); + fprintf (stream, ") %d", val >> 3); + } + else + { + fprintf (stream, "0x%x", * (int *) valaddr); + /* For a pointer to char or unsigned char, + also print the string pointed to, unless pointer is null. */ + if ((TYPE_TARGET_TYPE (type) == builtin_type_char + || TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char) + && unpack_long (type, valaddr) != 0) + { + fputc (' ', stream); + fputc ('"', stream); + for (i = 0; i < print_max; i++) + { + QUIT; + read_memory (unpack_long (type, valaddr) + i, &c, 1); + if (c == 0) + break; + printchar (c, stream); + } + fputc ('"', stream); + if (i == print_max) + fprintf (stream, "..."); + fflush (stream); + /* Return number of characters printed, plus one for the + terminating null if we have "reached the end". */ + return i + (i != print_max); } - fputc ('"', stream); - if (i == print_max) - fprintf (stream, "..."); - fflush (stream); - /* Return number of characters printed, plus one for the - terminating null if we have "reached the end". */ - return i + (i != print_max); } break; - case TYPE_CODE_MPTR: - { - struct type *domain = TYPE_DOMAIN_TYPE (type); - struct type *target = TYPE_TARGET_TYPE (type); - struct fn_field *f; - int j, len2; - char *kind = ""; - - val = unpack_long (builtin_type_int, valaddr); - if (TYPE_CODE (target) == TYPE_CODE_FUNC) - { - if (val < 128) - { - len = TYPE_NFN_FIELDS (domain); - for (i = 0; i < len; i++) - { - f = TYPE_FN_FIELDLIST1 (domain, i); - len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - QUIT; - if (TYPE_FN_FIELD_VOFFSET (f, j) == val) - { - kind = " virtual"; - goto common; - } - } - } - } - else - { - struct symbol *sym = find_pc_function (val); - if (sym == 0) - error ("invalid pointer to member function"); - len = TYPE_NFN_FIELDS (domain); - for (i = 0; i < len; i++) - { - f = TYPE_FN_FIELDLIST1 (domain, i); - len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - QUIT; - if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) - goto common; - } - } - } - common: - if (i < len) - { - fprintf (stream, "& "); - type_print_base (domain, stream, 0, 0); - fprintf (stream, "::%s", kind); - type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0); - if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' - && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$') - type_print_method_args - (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", - TYPE_FN_FIELDLIST_NAME (domain, i), stream); - else - type_print_method_args - (TYPE_FN_FIELD_ARGS (f, j), "", - TYPE_FN_FIELDLIST_NAME (domain, i), stream); - break; - } - } - else - { - /* VAL is a byte offset into the structure type DOMAIN. - Find the name of the field for that offset and - print it. */ - int extra = 0; - int bits = 0; - len = TYPE_NFIELDS (domain); - val <<= 3; /* @@ Make VAL into bit offset */ - for (i = 0; i < len; i++) - { - int bitpos = TYPE_FIELD_BITPOS (domain, i); - QUIT; - if (val == bitpos) - break; - if (val < bitpos && i > 0) - { - int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target)); - /* Somehow pointing into a field. */ - i -= 1; - extra = (val - TYPE_FIELD_BITPOS (domain, i)); - if (extra & 0x3) - bits = 1; - else - extra >>= 3; - break; - } - } - if (i < len) - { - fprintf (stream, "& "); - type_print_base (domain, stream, 0, 0); - fprintf (stream, "::"); - fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i)); - if (extra) - fprintf (stream, " + %d bytes", extra); - if (bits) - fprintf (stream, " (offset in bits)"); - break; - } - } - fputc ('(', stream); - type_print (type, "", stream, -1); - fprintf (stream, ") %d", val >> 3); - break; - } + case TYPE_CODE_MEMBER: + error ("not implemented: member type in val_print"); + break; case TYPE_CODE_REF: fprintf (stream, "(0x%x &) = ", * (int *) valaddr); @@ -489,7 +493,7 @@ type_print_1 (type, varstring, stream, show, level) && (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC || code == TYPE_CODE_ARRAY - || code == TYPE_CODE_MPTR + || code == TYPE_CODE_MEMBER || code == TYPE_CODE_REF))) fprintf (stream, " "); type_print_varspec_prefix (type, stream, show, 0); @@ -550,12 +554,11 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr) fputc ('*', stream); break; - case TYPE_CODE_MPTR: - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); - if (passed_a_ptr) - fputc ('(', stream); - type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, 1); - fprintf (stream, "::*"); + case TYPE_CODE_MEMBER: + type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); + type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, + passed_a_ptr); + fprintf (stream, "::"); break; case TYPE_CODE_REF: @@ -604,10 +607,12 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr) fprintf (stream, "]"); break; - case TYPE_CODE_MPTR: + case TYPE_CODE_MEMBER: if (passed_a_ptr) fputc (')', stream); - /* Fall through. */ + type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); + break; + case TYPE_CODE_PTR: case TYPE_CODE_REF: type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1); @@ -660,7 +665,7 @@ type_print_base (type, stream, show, level) { case TYPE_CODE_ARRAY: case TYPE_CODE_PTR: - case TYPE_CODE_MPTR: + case TYPE_CODE_MEMBER: case TYPE_CODE_REF: case TYPE_CODE_FUNC: type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); diff --git a/gdb/values.c b/gdb/values.c index 93d94824533..8fa5af9c03a 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -464,8 +464,7 @@ unpack_long (type, valaddr) if (len == sizeof (long)) return * (unsigned long *) valaddr; } - else if (code == TYPE_CODE_INT - || code == TYPE_CODE_MPTR) + else if (code == TYPE_CODE_INT) { if (len == sizeof (char)) return * (char *) valaddr; @@ -485,6 +484,9 @@ unpack_long (type, valaddr) if (len == sizeof (char *)) return (CORE_ADDR) * (char **) valaddr; } + else if (code == TYPE_CODE_MEMBER) + error ("not impelmented: member types in unpack_long"); + error ("Value not integer or pointer."); } diff --git a/gdb/version.c b/gdb/version.c index 244d065a1f6..5e1f9074ae1 100644 --- a/gdb/version.c +++ b/gdb/version.c @@ -1,3 +1,3 @@ /* Define the current version number of GDB. */ -char *version = "2.5.1 (GNU C++ 1.21.0 compatible)"; +char *version = "2.5.2 (GNU C++ 1.22.0 compatible)";