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:
Tom Tromey
2025-08-23 11:39:35 -06:00
parent 1faabbe632
commit 8ea36fc9f3
4 changed files with 74 additions and 45 deletions

View File

@@ -1303,15 +1303,13 @@ direct_abs_decl: '(' abs_decl ')'
| direct_abs_decl array_mod | direct_abs_decl array_mod
{ {
cpstate->type_stack.push ($1); cpstate->type_stack.push ($1);
cpstate->type_stack.push ($2); cpstate->type_stack.push (tp_array, $2);
cpstate->type_stack.push (tp_array);
$$ = cpstate->type_stack.create (); $$ = cpstate->type_stack.create ();
cpstate->type_stacks.emplace_back ($$); cpstate->type_stacks.emplace_back ($$);
} }
| array_mod | array_mod
{ {
cpstate->type_stack.push ($1); cpstate->type_stack.push (tp_array, $1);
cpstate->type_stack.push (tp_array);
$$ = cpstate->type_stack.create (); $$ = cpstate->type_stack.create ();
cpstate->type_stacks.emplace_back ($$); cpstate->type_stacks.emplace_back ($$);
} }

View File

@@ -613,11 +613,9 @@ BasicType2:
| '*' BasicType2 | '*' BasicType2
{ type_stack->push (tp_pointer); } { type_stack->push (tp_pointer); }
| '[' INTEGER_LITERAL ']' | '[' INTEGER_LITERAL ']'
{ type_stack->push ($2.val); { type_stack->push (tp_array, $2.val); }
type_stack->push (tp_array); }
| '[' INTEGER_LITERAL ']' BasicType2 | '[' INTEGER_LITERAL ']' BasicType2
{ type_stack->push ($2.val); { type_stack->push (tp_array, $2.val); }
type_stack->push (tp_array); }
; ;
BasicType: BasicType:

View File

@@ -1159,8 +1159,7 @@ push_kind_type (LONGEST val, struct type *type)
ival = static_cast <int> (val); ival = static_cast <int> (val);
} }
type_stack->push (ival); type_stack->push (tp_kind, ival);
type_stack->push (tp_kind);
} }
/* Helper function for convert_to_kind_type. */ /* Helper function for convert_to_kind_type. */

View File

@@ -26,34 +26,49 @@
struct type; struct type;
struct expr_builder; struct expr_builder;
/* For parsing of complicated types. /* The kind of element on the stack of types and qualifiers, used for
An array should be preceded in the list by the size of the array. */ parsing complicated types. */
enum type_pieces enum type_pieces
{ {
tp_end = -1, /* This is returned by pop() to indicate that the stack is empty.
tp_pointer, Note that it may not be pushed by the user. */
tp_reference, tp_end = -1,
tp_rvalue_reference, tp_pointer,
tp_array, tp_reference,
tp_function, tp_rvalue_reference,
tp_function_with_arguments, /* An array type, where the dimension is pushed on the stack as
tp_const, well. */
tp_volatile, tp_array,
tp_space_identifier, tp_function,
tp_atomic, /* A function with argument types; the types are also pushed on the
tp_restrict, stack. */
tp_type_stack, tp_function_with_arguments,
tp_kind 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 union type_stack_elt
{ {
enum type_pieces piece; /* An ordinary type qualifier. */
int int_val; enum type_pieces piece;
struct type_stack *stack_val; /* An integer value. Currently only used for address spaces. */
std::vector<struct type *> *typelist_val; 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. */ /* The type stack is an instance of this structure. */
@@ -80,18 +95,31 @@ public:
void insert (enum type_pieces tp); 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) 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; type_stack_elt elt;
elt.piece = tp; elt.piece = tp;
m_elements.push_back (elt); 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; type_stack_elt elt;
elt.int_val = n; elt.int_val = n;
m_elements.push_back (elt); 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. */ /* Push the type stack STACK as an element on this type stack. */
@@ -101,11 +129,12 @@ public:
type_stack_elt elt; type_stack_elt elt;
elt.stack_val = stack; elt.stack_val = stack;
m_elements.push_back (elt); 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. /* Push a function type with arguments onto this type stack. LIST
LIST holds the argument types. If the final item in LIST is NULL, holds the argument types. If the final item in LIST is NULL,
then the function will be varargs. */ then the function will be varargs. */
void push (std::vector<struct type *> *list) void push (std::vector<struct type *> *list)
@@ -113,7 +142,8 @@ public:
type_stack_elt elt; type_stack_elt elt;
elt.typelist_val = list; elt.typelist_val = list;
m_elements.push_back (elt); 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 () enum type_pieces pop ()
@@ -127,11 +157,7 @@ public:
int pop_int () int pop_int ()
{ {
if (m_elements.empty ()) gdb_assert (!m_elements.empty ());
{
/* "Can't happen". */
return 0;
}
type_stack_elt elt = m_elements.back (); type_stack_elt elt = m_elements.back ();
m_elements.pop_back (); m_elements.pop_back ();
return elt.int_val; return elt.int_val;
@@ -198,6 +224,14 @@ private:
m_elements.insert (m_elements.begin () + slot, element); 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. */ /* Elements on the stack. */
std::vector<union type_stack_elt> m_elements; std::vector<union type_stack_elt> m_elements;