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:
Tom Tromey 2020-04-01 14:09:52 -06:00 committed by Tom Tromey
parent c34e871466
commit 3638a098a2
4 changed files with 68 additions and 30 deletions

View File

@ -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:

View File

@ -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},

View File

@ -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.

View File

@ -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"