From 3638a098a21ce706ef2b17185f3b165e4f9a5c54 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 1 Apr 2020 14:09:52 -0600 Subject: 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 * 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 * gdb.base/complex-parts.exp: Add type tests. --- gdb/c-exp.y | 81 ++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 30 deletions(-) (limited to 'gdb/c-exp.y') 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 exp exp1 type_exp start variable qualified_name lcurly function_method %type rcurly -%type type typebase +%type type typebase scalar_type %type nonempty_typelist func_mod parameter_typelist /* %type 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 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}, -- cgit v1.1