mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Make type_stack pushing a bit safer
This changes type_stack to make pushing elements a bit safer: if an element requires an argument, these are now always pushed at the same time, rather than separately. This patch also adds a few comments to help document a bit better. Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
@@ -1303,15 +1303,13 @@ direct_abs_decl: '(' abs_decl ')'
|
||||
| direct_abs_decl array_mod
|
||||
{
|
||||
cpstate->type_stack.push ($1);
|
||||
cpstate->type_stack.push ($2);
|
||||
cpstate->type_stack.push (tp_array);
|
||||
cpstate->type_stack.push (tp_array, $2);
|
||||
$$ = cpstate->type_stack.create ();
|
||||
cpstate->type_stacks.emplace_back ($$);
|
||||
}
|
||||
| array_mod
|
||||
{
|
||||
cpstate->type_stack.push ($1);
|
||||
cpstate->type_stack.push (tp_array);
|
||||
cpstate->type_stack.push (tp_array, $1);
|
||||
$$ = cpstate->type_stack.create ();
|
||||
cpstate->type_stacks.emplace_back ($$);
|
||||
}
|
||||
|
||||
@@ -613,11 +613,9 @@ BasicType2:
|
||||
| '*' BasicType2
|
||||
{ type_stack->push (tp_pointer); }
|
||||
| '[' INTEGER_LITERAL ']'
|
||||
{ type_stack->push ($2.val);
|
||||
type_stack->push (tp_array); }
|
||||
{ type_stack->push (tp_array, $2.val); }
|
||||
| '[' INTEGER_LITERAL ']' BasicType2
|
||||
{ type_stack->push ($2.val);
|
||||
type_stack->push (tp_array); }
|
||||
{ type_stack->push (tp_array, $2.val); }
|
||||
;
|
||||
|
||||
BasicType:
|
||||
|
||||
@@ -1159,8 +1159,7 @@ push_kind_type (LONGEST val, struct type *type)
|
||||
ival = static_cast <int> (val);
|
||||
}
|
||||
|
||||
type_stack->push (ival);
|
||||
type_stack->push (tp_kind);
|
||||
type_stack->push (tp_kind, ival);
|
||||
}
|
||||
|
||||
/* Helper function for convert_to_kind_type. */
|
||||
|
||||
104
gdb/type-stack.h
104
gdb/type-stack.h
@@ -26,34 +26,49 @@
|
||||
struct type;
|
||||
struct expr_builder;
|
||||
|
||||
/* For parsing of complicated types.
|
||||
An array should be preceded in the list by the size of the array. */
|
||||
/* The kind of element on the stack of types and qualifiers, used for
|
||||
parsing complicated types. */
|
||||
enum type_pieces
|
||||
{
|
||||
tp_end = -1,
|
||||
tp_pointer,
|
||||
tp_reference,
|
||||
tp_rvalue_reference,
|
||||
tp_array,
|
||||
tp_function,
|
||||
tp_function_with_arguments,
|
||||
tp_const,
|
||||
tp_volatile,
|
||||
tp_space_identifier,
|
||||
tp_atomic,
|
||||
tp_restrict,
|
||||
tp_type_stack,
|
||||
tp_kind
|
||||
};
|
||||
{
|
||||
/* This is returned by pop() to indicate that the stack is empty.
|
||||
Note that it may not be pushed by the user. */
|
||||
tp_end = -1,
|
||||
tp_pointer,
|
||||
tp_reference,
|
||||
tp_rvalue_reference,
|
||||
/* An array type, where the dimension is pushed on the stack as
|
||||
well. */
|
||||
tp_array,
|
||||
tp_function,
|
||||
/* A function with argument types; the types are also pushed on the
|
||||
stack. */
|
||||
tp_function_with_arguments,
|
||||
tp_const,
|
||||
tp_volatile,
|
||||
/* An address space identifier. The address space is also pushed on
|
||||
the stack. */
|
||||
tp_space_identifier,
|
||||
tp_atomic,
|
||||
tp_restrict,
|
||||
/* A separate type stack, which is also pushed onto this type
|
||||
stack. */
|
||||
tp_type_stack,
|
||||
/* Fortran-specific, specifies the kind. */
|
||||
tp_kind,
|
||||
};
|
||||
|
||||
/* The stack can contain either an enum type_pieces or an int. */
|
||||
/* Items on the type stack. */
|
||||
union type_stack_elt
|
||||
{
|
||||
enum type_pieces piece;
|
||||
int int_val;
|
||||
struct type_stack *stack_val;
|
||||
std::vector<struct type *> *typelist_val;
|
||||
};
|
||||
{
|
||||
/* An ordinary type qualifier. */
|
||||
enum type_pieces piece;
|
||||
/* An integer value. Currently only used for address spaces. */
|
||||
int int_val;
|
||||
/* Another type stack. */
|
||||
struct type_stack *stack_val;
|
||||
/* A list of types. */
|
||||
std::vector<struct type *> *typelist_val;
|
||||
};
|
||||
|
||||
/* The type stack is an instance of this structure. */
|
||||
|
||||
@@ -80,18 +95,31 @@ public:
|
||||
|
||||
void insert (enum type_pieces tp);
|
||||
|
||||
/* Push an ordinary element on the type stack. This can be used for
|
||||
any element that doesn't require any extra data. */
|
||||
void push (enum type_pieces tp)
|
||||
{
|
||||
/* tp_end can only be returned by this class, not pushed. The
|
||||
others require a payload on the stack and so can only be pushed
|
||||
by the appropriate method. */
|
||||
gdb_assert (tp != tp_end);
|
||||
gdb_assert (!requires_payload (tp));
|
||||
type_stack_elt elt;
|
||||
elt.piece = tp;
|
||||
m_elements.push_back (elt);
|
||||
}
|
||||
|
||||
void push (int n)
|
||||
/* Push an element and an integer value onto the stack. The integer
|
||||
value is pushed first, followed by TP. Only piece kinds that
|
||||
accept an integer argument are allowed. */
|
||||
void push (enum type_pieces tp, int n)
|
||||
{
|
||||
gdb_assert (tp == tp_array || tp == tp_space_identifier || tp == tp_kind);
|
||||
type_stack_elt elt;
|
||||
elt.int_val = n;
|
||||
m_elements.push_back (elt);
|
||||
elt.piece = tp;
|
||||
m_elements.push_back (elt);
|
||||
}
|
||||
|
||||
/* Push the type stack STACK as an element on this type stack. */
|
||||
@@ -101,11 +129,12 @@ public:
|
||||
type_stack_elt elt;
|
||||
elt.stack_val = stack;
|
||||
m_elements.push_back (elt);
|
||||
push (tp_type_stack);
|
||||
elt.piece = tp_type_stack;
|
||||
m_elements.push_back (elt);
|
||||
}
|
||||
|
||||
/* Push a function type with arguments onto the global type stack.
|
||||
LIST holds the argument types. If the final item in LIST is NULL,
|
||||
/* Push a function type with arguments onto this type stack. LIST
|
||||
holds the argument types. If the final item in LIST is NULL,
|
||||
then the function will be varargs. */
|
||||
|
||||
void push (std::vector<struct type *> *list)
|
||||
@@ -113,7 +142,8 @@ public:
|
||||
type_stack_elt elt;
|
||||
elt.typelist_val = list;
|
||||
m_elements.push_back (elt);
|
||||
push (tp_function_with_arguments);
|
||||
elt.piece = tp_function_with_arguments;
|
||||
m_elements.push_back (elt);
|
||||
}
|
||||
|
||||
enum type_pieces pop ()
|
||||
@@ -127,11 +157,7 @@ public:
|
||||
|
||||
int pop_int ()
|
||||
{
|
||||
if (m_elements.empty ())
|
||||
{
|
||||
/* "Can't happen". */
|
||||
return 0;
|
||||
}
|
||||
gdb_assert (!m_elements.empty ());
|
||||
type_stack_elt elt = m_elements.back ();
|
||||
m_elements.pop_back ();
|
||||
return elt.int_val;
|
||||
@@ -198,6 +224,14 @@ private:
|
||||
m_elements.insert (m_elements.begin () + slot, element);
|
||||
}
|
||||
|
||||
/* Return true if TP requires some payload element. */
|
||||
bool requires_payload (type_pieces tp) const
|
||||
{
|
||||
return (tp == tp_array || tp == tp_kind || tp == tp_type_stack
|
||||
|| tp == tp_function_with_arguments
|
||||
|| tp == tp_space_identifier);
|
||||
}
|
||||
|
||||
|
||||
/* Elements on the stack. */
|
||||
std::vector<union type_stack_elt> m_elements;
|
||||
|
||||
Reference in New Issue
Block a user