Add _Complex type support to C parser
This changes the C parser to add support for complex types in casts. gdb/ChangeLog 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__. gdb/testsuite/ChangeLog 2020-04-01 Tom Tromey <tom@tromey.com> * gdb.base/complex-parts.exp: Add type tests.
This commit is contained in:
parent
c34e871466
commit
3638a098a2
|
@ -1,3 +1,11 @@
|
|||
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:
|
||||
|
|
81
gdb/c-exp.y
81
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},
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
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.
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue