diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/c-exp.y | 81 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/complex-parts.exp | 5 |
4 files changed, 68 insertions, 30 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8ae8b48..61d3007 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2020-04-01 Tom Tromey <tom@tromey.com> + * c-exp.y (FLOAT_KEYWORD, COMPLEX): New tokens. + (scalar_type): New rule, from typebase. + (typebase): Use scalar_type. Recognize complex types. + (field_name): Handle FLOAT_KEYWORD. + (ident_tokens): Add _Complex and __complex__. + +2020-04-01 Tom Tromey <tom@tromey.com> + PR exp/25299: * valarith.c (promotion_type, complex_binop): New functions. (scalar_binop): Handle complex numbers. Use promotion_type. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index c2531b9..feab51a8 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -175,7 +175,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); %type <voidval> exp exp1 type_exp start variable qualified_name lcurly function_method %type <lval> rcurly -%type <tval> type typebase +%type <tval> type typebase scalar_type %type <tvec> nonempty_typelist func_mod parameter_typelist /* %type <bval> block */ @@ -239,6 +239,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); legal basetypes. */ %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD %token RESTRICT ATOMIC +%token FLOAT_KEYWORD COMPLEX %token <sval> DOLLAR_VARIABLE @@ -1331,20 +1332,11 @@ func_mod: '(' ')' type : ptype ; -/* Implements (approximately): (type-qualifier)* type-specifier. +/* A helper production that recognizes scalar types that can validly + be used with _Complex. */ - When type-specifier is only ever a single word, like 'float' then these - arrive as pre-built TYPENAME tokens thanks to the classify_name - function. However, when a type-specifier can contain multiple words, - for example 'double' can appear as just 'double' or 'long double', and - similarly 'long' can appear as just 'long' or in 'long double', then - these type-specifiers are parsed into their own tokens in the function - lex_one_token and the ident_tokens array. These separate tokens are all - recognised here. */ -typebase - : TYPENAME - { $$ = $1.type; } - | INT_KEYWORD +scalar_type: + INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), "int"); } | LONG @@ -1427,11 +1419,49 @@ typebase "double", NULL, 0); } + | FLOAT_KEYWORD + { $$ = lookup_typename (pstate->language (), + "float", + NULL, + 0); } | LONG DOUBLE_KEYWORD { $$ = lookup_typename (pstate->language (), "long double", NULL, 0); } + | UNSIGNED type_name + { $$ = lookup_unsigned_typename (pstate->language (), + TYPE_NAME($2.type)); } + | UNSIGNED + { $$ = lookup_unsigned_typename (pstate->language (), + "int"); } + | SIGNED_KEYWORD type_name + { $$ = lookup_signed_typename (pstate->language (), + TYPE_NAME($2.type)); } + | SIGNED_KEYWORD + { $$ = lookup_signed_typename (pstate->language (), + "int"); } + ; + +/* Implements (approximately): (type-qualifier)* type-specifier. + + When type-specifier is only ever a single word, like 'float' then these + arrive as pre-built TYPENAME tokens thanks to the classify_name + function. However, when a type-specifier can contain multiple words, + for example 'double' can appear as just 'double' or 'long double', and + similarly 'long' can appear as just 'long' or in 'long double', then + these type-specifiers are parsed into their own tokens in the function + lex_one_token and the ident_tokens array. These separate tokens are all + recognised here. */ +typebase + : TYPENAME + { $$ = $1.type; } + | scalar_type + { $$ = $1; } + | COMPLEX scalar_type + { + $$ = init_complex_type (nullptr, $2); + } | STRUCT name { $$ = lookup_struct (copy_name ($2).c_str (), @@ -1498,18 +1528,6 @@ typebase $2.length); $$ = NULL; } - | UNSIGNED type_name - { $$ = lookup_unsigned_typename (pstate->language (), - TYPE_NAME($2.type)); } - | UNSIGNED - { $$ = lookup_unsigned_typename (pstate->language (), - "int"); } - | SIGNED_KEYWORD type_name - { $$ = lookup_signed_typename (pstate->language (), - TYPE_NAME($2.type)); } - | SIGNED_KEYWORD - { $$ = lookup_signed_typename (pstate->language (), - "int"); } /* It appears that this rule for templates is never reduced; template recognition happens by lookahead in the token processing code in yylex. */ @@ -1735,12 +1753,11 @@ oper: OPERATOR NEW match the 'name' rule to appear as fields within a struct. The example that initially motivated this was the RISC-V target which models the floating point registers as a union with fields called 'float' and - 'double'. The 'float' string becomes a TYPENAME token and can appear - anywhere a 'name' can, however 'double' is its own token, - DOUBLE_KEYWORD, and doesn't match the 'name' rule.*/ + 'double'. */ field_name : name | DOUBLE_KEYWORD { $$ = typename_stoken ("double"); } + | FLOAT_KEYWORD { $$ = typename_stoken ("float"); } | INT_KEYWORD { $$ = typename_stoken ("int"); } | LONG { $$ = typename_stoken ("long"); } | SHORT { $$ = typename_stoken ("short"); } @@ -2472,7 +2489,7 @@ static const struct token tokentab2[] = /* Identifier-like tokens. Only type-specifiers than can appear in multi-word type names (for example 'double' can appear in 'long double') need to be listed here. type-specifiers that are only ever - single word (like 'float') are handled by the classify_name function. */ + single word (like 'char') are handled by the classify_name function. */ static const struct token ident_tokens[] = { {"unsigned", UNSIGNED, OP_NULL, 0}, @@ -2484,6 +2501,7 @@ static const struct token ident_tokens[] = {"_Alignof", ALIGNOF, OP_NULL, 0}, {"alignof", ALIGNOF, OP_NULL, FLAG_CXX}, {"double", DOUBLE_KEYWORD, OP_NULL, 0}, + {"float", FLOAT_KEYWORD, OP_NULL, 0}, {"false", FALSEKEYWORD, OP_NULL, FLAG_CXX}, {"class", CLASS, OP_NULL, FLAG_CXX}, {"union", UNION, OP_NULL, 0}, @@ -2495,6 +2513,9 @@ static const struct token ident_tokens[] = {"_Atomic", ATOMIC, OP_NULL, 0}, {"enum", ENUM, OP_NULL, 0}, {"long", LONG, OP_NULL, 0}, + {"_Complex", COMPLEX, OP_NULL, 0}, + {"__complex__", COMPLEX, OP_NULL, 0}, + {"true", TRUEKEYWORD, OP_NULL, FLAG_CXX}, {"int", INT_KEYWORD, OP_NULL, 0}, {"new", NEW, OP_NULL, FLAG_CXX}, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 05a542b..f885b93 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2020-04-01 Tom Tromey <tom@tromey.com> + * gdb.base/complex-parts.exp: Add type tests. + +2020-04-01 Tom Tromey <tom@tromey.com> + * gdb.base/complex-parts.exp: Add arithmetic tests. 2020-04-01 Tom Tromey <tom@tromey.com> diff --git a/gdb/testsuite/gdb.base/complex-parts.exp b/gdb/testsuite/gdb.base/complex-parts.exp index 0cf4abf..38aad39 100644 --- a/gdb/testsuite/gdb.base/complex-parts.exp +++ b/gdb/testsuite/gdb.base/complex-parts.exp @@ -86,3 +86,8 @@ gdb_test "print (5 + 7i) != (8 + 7i)" " = 1" gdb_test "print (5 + 7i) != (5 + 92i)" " = 1" gdb_test "print (20 - 4i) / (3 + 2i)" " = 4 \\+ -4i" + +gdb_test "print (_Complex int) 4" " = 4 \\+ 0i" +gdb_test "print (_Complex float) 4.5" " = 4.5 \\+ 0i" +gdb_test "ptype __complex__ short" " = _Complex short" +gdb_test "print (_Complex int) (23.75 + 8.88i)" " = 23 \\+ 8i" |