From: Jim Kingdon Date: Mon, 18 Oct 1993 01:10:25 +0000 (+0000) Subject: * parse.c, parser-defs.h (follow_types): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f843c95fc3d55bb449ed9e681848808c9f637ee4;p=binutils-gdb.git * parse.c, parser-defs.h (follow_types): New function. * c-exp.y (ptype : typebase abs_decl): Use it. * c-exp.y (ptype): Add support for type qualifiers after the typebase. The typebase rule already has support for them before the typebase. * Makefile.in: Change the expected number of shift/reduce conflicts to 6. This is OK--the 2 new conflicts are basically the same as one of the old ones. --- diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 37a00d2cd6b..0e7d39ac6c2 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -722,48 +722,23 @@ variable: name_not_typename ; +/* shift/reduce conflict: "typebase ." and the token is '('. (Shows up + twice, once where qualified_name is a possibility and once where + it is not). */ +/* shift/reduce conflict: "typebase CONST_KEYWORD ." and the token is '('. */ +/* shift/reduce conflict: "typebase VOLATILE_KEYWORD ." and the token is + '('. */ ptype : typebase + /* "const" and "volatile" are curently ignored. A type qualifier + before the type is currently handled in the typebase rule. */ + | typebase CONST_KEYWORD + | typebase VOLATILE_KEYWORD | typebase abs_decl - { - /* This is where the interesting stuff happens. */ - int done = 0; - int array_size; - struct type *follow_type = $1; - struct type *range_type; - - while (!done) - switch (pop_type ()) - { - case tp_end: - done = 1; - break; - case tp_pointer: - follow_type = lookup_pointer_type (follow_type); - break; - case tp_reference: - follow_type = lookup_reference_type (follow_type); - break; - case tp_array: - array_size = pop_type_int (); - if (array_size != -1) - { - range_type = - create_range_type ((struct type *) NULL, - builtin_type_int, 0, - array_size - 1); - follow_type = - create_array_type ((struct type *) NULL, - follow_type, range_type); - } - else - follow_type = lookup_pointer_type (follow_type); - break; - case tp_function: - follow_type = lookup_function_type (follow_type); - break; - } - $$ = follow_type; - } + { $$ = follow_types ($1); } + | typebase CONST_KEYWORD abs_decl + { $$ = follow_types ($1); } + | typebase VOLATILE_KEYWORD abs_decl + { $$ = follow_types ($1); } ; abs_decl: '*' @@ -790,6 +765,10 @@ direct_abs_decl: '(' abs_decl ')' push_type (tp_array); $$ = 0; } + + /* shift/reduce conflict. "direct_abs_decl . func_mod", and the token + is '('. */ + | direct_abs_decl func_mod { push_type (tp_function); } | func_mod @@ -808,6 +787,8 @@ func_mod: '(' ')' { free ((PTR)$2); $$ = 0; } ; +/* shift/reduce conflict: "type '(' typebase COLONCOLON '*' ')' ." and the + token is '('. */ type : ptype | typebase COLONCOLON '*' { $$ = lookup_member_type (builtin_type_int, $1); } @@ -871,7 +852,9 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = lookup_template_type(copy_name($2), $4, expression_context_block); } - /* "const" and "volatile" are curently ignored. */ + /* "const" and "volatile" are curently ignored. A type qualifier + after the type is handled in the ptype rule. I think these could + be too. */ | CONST_KEYWORD typebase { $$ = $2; } | VOLATILE_KEYWORD typebase { $$ = $2; } ; diff --git a/gdb/parse.c b/gdb/parse.c index 94e467e3d22..08f2b7e6748 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -726,6 +726,9 @@ parse_expression (string) error ("Junk after end of expression."); return exp; } + +/* Stuff for maintaining a stack of types. Currently just used by C, but + probably useful for any language which declares its types "backwards". */ void push_type (tp) @@ -770,6 +773,50 @@ pop_type_int () return 0; } +/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE + as modified by all the stuff on the stack. */ +struct type * +follow_types (follow_type) + struct type *follow_type; +{ + int done = 0; + int array_size; + struct type *range_type; + + while (!done) + switch (pop_type ()) + { + case tp_end: + done = 1; + break; + case tp_pointer: + follow_type = lookup_pointer_type (follow_type); + break; + case tp_reference: + follow_type = lookup_reference_type (follow_type); + break; + case tp_array: + array_size = pop_type_int (); + if (array_size != -1) + { + range_type = + create_range_type ((struct type *) NULL, + builtin_type_int, 0, + array_size - 1); + follow_type = + create_array_type ((struct type *) NULL, + follow_type, range_type); + } + else + follow_type = lookup_pointer_type (follow_type); + break; + case tp_function: + follow_type = lookup_function_type (follow_type); + break; + } + return follow_type; +} + void _initialize_parse () { diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index c57511a2c9f..5c8710e4e6e 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -133,6 +133,8 @@ pop_type PARAMS ((void)); extern int pop_type_int PARAMS ((void)); +extern struct type *follow_types PARAMS ((struct type *)); + /* During parsing of a C expression, the pointer to the next character is in this variable. */