From: Keith Seitz Date: Wed, 11 Nov 2009 16:45:46 +0000 (+0000) Subject: * c-expy. (operator_stoken): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=66c53f2b15177549ac9dfea610360140f9e73ba2;p=binutils-gdb.git * c-expy. (operator_stoken): New function. (OPERATOR): New token. (NEW): New token. (DELETE): New token. (operator): New rule. (name): Add operator. (ident_tokens): Add "new", "delete", and "operator". * gdbtypes.c (rank_one_type): Don't complain about void pointer conversion badness if both types are void pointers. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c969bd05eac..2fb73833ff3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2009-11-10 Keith Seitz + + * c-expy. (operator_stoken): New function. + (OPERATOR): New token. + (NEW): New token. + (DELETE): New token. + (operator): New rule. + (name): Add operator. + (ident_tokens): Add "new", "delete", and "operator". + * gdbtypes.c (rank_one_type): Don't complain about + void pointer conversion badness if both types are + void pointers. + 2009-11-11 Jan Kratochvil * symfile.c (separate_debug_file_exists): Change parameter parent_name diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 5dd47fb6da8..8ee323e4b78 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -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, int, YYSTYPE *); %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,130 @@ const_or_volatile_noopt: const_and_volatile { 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); + free (name); + } + ; + + + name : NAME { $$ = $1.stoken; } | BLOCKNAME { $$ = $1.stoken; } | TYPENAME { $$ = $1.stoken; } | NAME_OR_INT { $$ = $1.stoken; } + | operator { $$ = $1; } ; name_not_typename : NAME @@ -1151,6 +1275,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 +1870,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}, diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 2f77dca5bef..299d0c515a2 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2004,7 +2004,8 @@ rank_one_type (struct type *parm, struct type *arg) 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),