? cl.cpp-operators ? cl.dwarf2_physname Index: c-exp.y =================================================================== RCS file: /cvs/src/src/gdb/c-exp.y,v retrieving revision 1.64 diff -u -p -r1.64 c-exp.y --- c-exp.y 10 Nov 2009 22:17:58 -0000 1.64 +++ c-exp.y 11 Nov 2009 00:49:48 -0000 @@ -157,6 +157,7 @@ void yyerror (char *); %{ /* YYSTYPE gets defined by %union */ static int parse_number (char *, int, int, YYSTYPE *); +static struct stoken operator_stoken (const char *); %} %type exp exp1 type_exp start variable qualified_name lcurly @@ -199,9 +200,12 @@ static int parse_number (char *, int, in %token NAME_OR_INT +%token OPERATOR %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON %token TEMPLATE %token ERROR +%token NEW DELETE +%type operator /* Special type cases, put in to allow the parser to distinguish different legal basetypes. */ @@ -1132,10 +1136,129 @@ const_or_volatile_noopt: const_and_vol { push_type (tp_volatile); } ; +operator: OPERATOR NEW + { $$ = operator_stoken (" new"); } + | OPERATOR DELETE + { $$ = operator_stoken (" delete"); } + | OPERATOR NEW '[' ']' + { $$ = operator_stoken (" new[]"); } + | OPERATOR DELETE '[' ']' + { $$ = operator_stoken (" delete[]"); } + | OPERATOR '+' + { $$ = operator_stoken ("+"); } + | OPERATOR '-' + { $$ = operator_stoken ("-"); } + | OPERATOR '*' + { $$ = operator_stoken ("*"); } + | OPERATOR '/' + { $$ = operator_stoken ("/"); } + | OPERATOR '%' + { $$ = operator_stoken ("%"); } + | OPERATOR '^' + { $$ = operator_stoken ("^"); } + | OPERATOR '&' + { $$ = operator_stoken ("&"); } + | OPERATOR '|' + { $$ = operator_stoken ("|"); } + | OPERATOR '~' + { $$ = operator_stoken ("~"); } + | OPERATOR '!' + { $$ = operator_stoken ("!"); } + | OPERATOR '=' + { $$ = operator_stoken ("="); } + | OPERATOR '<' + { $$ = operator_stoken ("<"); } + | OPERATOR '>' + { $$ = operator_stoken (">"); } + | OPERATOR ASSIGN_MODIFY + { const char *op = "unknown"; + switch ($2) + { + case BINOP_RSH: + op = ">>="; + break; + case BINOP_LSH: + op = "<<="; + break; + case BINOP_ADD: + op = "+="; + break; + case BINOP_SUB: + op = "-="; + break; + case BINOP_MUL: + op = "*="; + break; + case BINOP_DIV: + op = "/="; + break; + case BINOP_REM: + op = "%="; + break; + case BINOP_BITWISE_IOR: + op = "|="; + break; + case BINOP_BITWISE_AND: + op = "&="; + break; + case BINOP_BITWISE_XOR: + op = "^="; + break; + default: + break; + } + + $$ = operator_stoken (op); + } + | OPERATOR LSH + { $$ = operator_stoken ("<<"); } + | OPERATOR RSH + { $$ = operator_stoken (">>"); } + | OPERATOR EQUAL + { $$ = operator_stoken ("=="); } + | OPERATOR NOTEQUAL + { $$ = operator_stoken ("!="); } + | OPERATOR LEQ + { $$ = operator_stoken ("<="); } + | OPERATOR GEQ + { $$ = operator_stoken (">="); } + | OPERATOR ANDAND + { $$ = operator_stoken ("&&"); } + | OPERATOR OROR + { $$ = operator_stoken ("||"); } + | OPERATOR INCREMENT + { $$ = operator_stoken ("++"); } + | OPERATOR DECREMENT + { $$ = operator_stoken ("--"); } + | OPERATOR ',' + { $$ = operator_stoken (","); } + | OPERATOR ARROW_STAR + { $$ = operator_stoken ("->*"); } + | OPERATOR ARROW + { $$ = operator_stoken ("->"); } + | OPERATOR '(' ')' + { $$ = operator_stoken ("()"); } + | OPERATOR '[' ']' + { $$ = operator_stoken ("[]"); } + | OPERATOR ptype + { char *name; + long length; + struct ui_file *buf = mem_fileopen (); + + c_print_type ($2, NULL, buf, -1, 0); + name = ui_file_xstrdup (buf, &length); + ui_file_delete (buf); + $$ = operator_stoken (name); + } + ; + + + name : NAME { $$ = $1.stoken; } | BLOCKNAME { $$ = $1.stoken; } | TYPENAME { $$ = $1.stoken; } | NAME_OR_INT { $$ = $1.stoken; } + | operator { $$ = $1; } ; name_not_typename : NAME @@ -1151,6 +1274,23 @@ name_not_typename : NAME %% +/* Returns a stoken of the operator name given by OP (which does not + include the string "operator"). */ +static struct stoken +operator_stoken (const char *op) +{ + static const char *operator_string = "operator"; + struct stoken st = { NULL, 0 }; + st.length = strlen (operator_string) + strlen (op); + st.ptr = malloc (st.length + 1); + strcpy (st.ptr, operator_string); + strcat (st.ptr, op); + + /* The toplevel (c_parse) will free the memory allocated here. */ + make_cleanup (free, st.ptr); + return st; +}; + /* 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. */ @@ -1729,6 +1869,9 @@ static const struct token ident_tokens[] {"long", LONG, OP_NULL, 0}, {"true", TRUEKEYWORD, OP_NULL, 1}, {"int", INT_KEYWORD, OP_NULL, 0}, + {"new", NEW, OP_NULL, 1}, + {"delete", DELETE, OP_NULL, 1}, + {"operator", OPERATOR, OP_NULL, 1}, {"and", ANDAND, BINOP_END, 1}, {"and_eq", ASSIGN_MODIFY, BINOP_BITWISE_AND, 1}, Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.176 diff -u -p -r1.176 gdbtypes.c --- gdbtypes.c 2 Jul 2009 12:57:14 -0000 1.176 +++ gdbtypes.c 11 Nov 2009 00:49:49 -0000 @@ -2004,7 +2004,8 @@ rank_one_type (struct type *parm, struct switch (TYPE_CODE (arg)) { case TYPE_CODE_PTR: - if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID) + if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID + && TYPE_CODE (TYPE_TARGET_TYPE (arg)) != TYPE_CODE_VOID) return VOID_PTR_CONVERSION_BADNESS; else return rank_one_type (TYPE_TARGET_TYPE (parm), Index: testsuite/gdb.cp/cplusfuncs.cc =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cplusfuncs.cc,v retrieving revision 1.1 diff -u -p -r1.1 cplusfuncs.cc --- testsuite/gdb.cp/cplusfuncs.cc 23 Aug 2003 03:55:59 -0000 1.1 +++ testsuite/gdb.cp/cplusfuncs.cc 11 Nov 2009 00:49:50 -0000 @@ -46,7 +46,9 @@ public: void operator [] (foo&); void operator () (foo&); void* operator new (size_t) throw (); + void* operator new[] (size_t) throw (); void operator delete (void *); + void operator delete[] (void *); /**/ operator int (); /**/ operator char* (); @@ -115,7 +117,9 @@ void foo::operator ->* (foo& afoo) { void foo::operator [] (foo& afoo) { afoo.ifoo = 0; } void foo::operator () (foo& afoo) { afoo.ifoo = 0; } void* foo::operator new (size_t ival) throw () { ival = 0; return 0; } +void* foo::operator new[] (size_t ival) throw () { ival = 0; return 0; } void foo::operator delete (void *ptr) { ptr = 0; } +void foo::operator delete[] (void *ptr) { ptr = 0; } /**/ foo::operator int () { return 0; } /**/ foo::operator char* () { return 0; } Index: testsuite/gdb.cp/cplusfuncs.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cplusfuncs.exp,v retrieving revision 1.8 diff -u -p -r1.8 cplusfuncs.exp --- testsuite/gdb.cp/cplusfuncs.exp 21 Sep 2009 19:46:15 -0000 1.8 +++ testsuite/gdb.cp/cplusfuncs.exp 11 Nov 2009 00:49:50 -0000 @@ -63,7 +63,7 @@ set dm_type_foo_ref "foo&" set dm_type_int_star "int*" set dm_type_long_star "long*" set dm_type_unsigned_int "unsigned" -set dm_type_void "" +set dm_type_void "void" set dm_type_void_star "void*" proc probe_demangler { } { @@ -78,7 +78,7 @@ proc probe_demangler { } { global dm_type_void global dm_type_void_star - send_gdb "print &'foo::operator,(foo&)'\n" + send_gdb "print &foo::operator,(foo&)\n" gdb_expect { -re ".*foo::operator, \\(.*foo.*&.*\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -97,7 +97,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_char_star'\n" + send_gdb "print &dm_type_char_star\n" gdb_expect { -re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -117,7 +117,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_foo_ref'\n" + send_gdb "print &dm_type_foo_ref\n" gdb_expect { -re ".*dm_type_foo_ref\\(foo &\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -136,7 +136,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_int_star'\n" + send_gdb "print &dm_type_int_star\n" gdb_expect { -re ".*dm_type_int_star\\(int \\*\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -155,7 +155,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_long_star'\n" + send_gdb "print &dm_type_long_star\n" gdb_expect { -re ".*dm_type_long_star\\(long \\*\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -174,7 +174,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_unsigned_int'\n" + send_gdb "print &dm_type_unsigned_int\n" gdb_expect { -re ".*dm_type_unsigned_int\\(unsigned int\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -193,7 +193,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_void'\n" + send_gdb "print &dm_type_void\n" gdb_expect { -re ".*dm_type_void\\(void\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -212,7 +212,7 @@ proc probe_demangler { } { } } - send_gdb "print &'dm_type_void_star'\n" + send_gdb "print &dm_type_void_star\n" gdb_expect { -re ".*dm_type_void_star\\(void \\*\\).*\r\n$gdb_prompt $" { # v2 demangler @@ -241,6 +241,7 @@ proc info_func_regexp { name demangled } global gdb_prompt send_gdb "info function $name\n" + set demangled [regsub {\\\(void\\\)} $demangled {\(\)}] gdb_expect { -re ".*File .*:\r\n(class |)$demangled\r\n.*$gdb_prompt $" { pass "info function for \"$name\"" @@ -277,16 +278,16 @@ proc print_addr_2 { name good } { set good_pattern [string_to_regexp $good] - send_gdb "print &'$name'\n" + send_gdb "print &$name\n" gdb_expect { -re ".* = .* $hex <$good_pattern>\r\n$gdb_prompt $" { - pass "print &'$name'" + pass "print &$name" } -re ".*$gdb_prompt $" { - fail "print &'$name'" + fail "print &$name" } timeout { - fail "print &'$name' (timeout)" + fail "print &$name (timeout)" } } } @@ -305,19 +306,19 @@ proc print_addr_2_kfail { name good bad set good_pattern [string_to_regexp $good] set bad_pattern [string_to_regexp $bad] - send_gdb "print &'$name'\n" + send_gdb "print &$name\n" gdb_expect { -re ".* = .* $hex <$good_pattern>\r\n$gdb_prompt $" { - pass "print &'$name'" + pass "print &$name" } -re ".* = .* $hex <$bad_pattern>\r\n$gdb_prompt $" { - kfail $bugid "print &'$name'" + kfail $bugid "print &$name" } -re ".*$gdb_prompt $" { - fail "print &'$name'" + fail "print &$name" } timeout { - fail "print &'$name' (timeout)" + fail "print &$name (timeout)" } } } @@ -327,7 +328,12 @@ proc print_addr_2_kfail { name good bad # proc print_addr { name } { - print_addr_2 "$name" "$name" + set expected [regsub {\(void\)} $name {()}] + if {[string first "::" $name] == -1} { + # C function -- must be qutoed + set name "'$name'" + } + print_addr_2 "$name" $expected } # @@ -460,10 +466,13 @@ proc test_paddr_operator_functions {} { print_addr "foo::operator\[\]($dm_type_foo_ref)" print_addr "foo::operator()($dm_type_foo_ref)" - gdb_test "print &'foo::operator new'" \ + gdb_test "print &foo::operator new" \ " = .* $hex " + gdb_test "print &foo::operator new\[\]" \ + " = .* $hex " if { !$hp_aCC_compiler } { print_addr "foo::operator delete($dm_type_void_star)" + print_addr "foo::operator delete[]($dm_type_void_star)" } else { gdb_test "print &'foo::operator delete($dm_type_void_star) static'" \ " = .*(0x\[0-9a-f\]+|) "