summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/c-exp.y65
-rw-r--r--gdb/parse.c47
-rw-r--r--gdb/parser-defs.h2
3 files changed, 73 insertions, 41 deletions
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. */