From 3638a098a21ce706ef2b17185f3b165e4f9a5c54 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 1 Apr 2020 14:09:52 -0600 Subject: [PATCH] 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/ChangeLog | 8 +++ gdb/c-exp.y | 81 +++++++++++++++--------- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.base/complex-parts.exp | 5 ++ 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8ae8b484e56..61d30070e37 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +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__. + 2020-04-01 Tom Tromey PR exp/25299: diff --git a/gdb/c-exp.y b/gdb/c-exp.y index c2531b9bffc..feab51a8e2c 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}, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 05a542b6232..f885b93ecd9 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-04-01 Tom Tromey + + * gdb.base/complex-parts.exp: Add type tests. + 2020-04-01 Tom Tromey * gdb.base/complex-parts.exp: Add arithmetic tests. diff --git a/gdb/testsuite/gdb.base/complex-parts.exp b/gdb/testsuite/gdb.base/complex-parts.exp index 0cf4abf56ec..38aad395ad2 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" -- 2.39.2