* [PATCH 1/7] gdb: convert QUAL_* macros into an enum_flags
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
@ 2026-10-01 20:29 ` Simon Marchi
2026-10-01 20:30 ` [PATCH 2/7] gdb: convert INT_* " Simon Marchi
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:29 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Replace the QUAL_CONST / QUAL_RESTRICT / QUAL_VOLATILE macros with an
enum plus an enum flags_type. Use it where applicable.
Note that the value stored on the parser's union is the raw enum, not
the enum_flags type. enum_flags has a user-provided default constructor
(to initialize it to 0), which would make the generated YYSTYPE union's
default constructor deleted. The d_qualify helper function accepts the
enum_flags type though.
Change-Id: Ib146f6db66c849ac2f0ee575a98bff7b90d5e17c
---
gdb/cp-name-parser.c | 4 ++--
gdb/cp-name-parser.h | 21 ++++++++++++++-------
gdb/cp-name-parser.y | 11 ++++++-----
3 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/gdb/cp-name-parser.c b/gdb/cp-name-parser.c
index d04ed3594878..569d102213c8 100644
--- a/gdb/cp-name-parser.c
+++ b/gdb/cp-name-parser.c
@@ -110,8 +110,8 @@ cpname_state::make_name (const char *name, int len)
may already be qualified; duplicate qualifiers are not created. */
struct demangle_component *
-cpname_state::d_qualify (struct demangle_component *lhs, int qualifiers,
- int is_method)
+cpname_state::d_qualify (struct demangle_component *lhs,
+ qual_flags qualifiers, int is_method)
{
struct demangle_component **inner_p;
enum demangle_component_type type;
diff --git a/gdb/cp-name-parser.h b/gdb/cp-name-parser.h
index 31b2227227fc..7585379f5be2 100644
--- a/gdb/cp-name-parser.h
+++ b/gdb/cp-name-parser.h
@@ -21,16 +21,11 @@
#define GDB_CP_NAME_PARSER_H
#include "demangle.h"
+#include "gdbsupport/enum-flags.h"
union cp_name_parser_YYSTYPE;
struct demangle_parse_info;
-/* Flags passed to cpname_state::d_qualify. */
-
-#define QUAL_CONST 1
-#define QUAL_RESTRICT 2
-#define QUAL_VOLATILE 4
-
/* Flags passed to cpname_state::d_int_type. */
#define INT_CHAR (1 << 0)
@@ -46,6 +41,18 @@ struct demangle_parse_info;
namespace cp_name_parser {
+/* Type qualifiers, passed to cpname_state::d_qualify. */
+
+enum qual_flag
+{
+ QUAL_NONE = 0,
+ QUAL_CONST = 1,
+ QUAL_RESTRICT = 2,
+ QUAL_VOLATILE = 4,
+};
+
+DEF_ENUM_FLAGS_TYPE (enum qual_flag, qual_flags);
+
/* State of an ongoing parse. */
struct cpname_state
@@ -100,7 +107,7 @@ struct cpname_state
struct demangle_component *make_name (const char *name, int len);
struct demangle_component *d_qualify (struct demangle_component *lhs,
- int qualifiers, int is_method);
+ qual_flags qualifiers, int is_method);
struct demangle_component *d_int_type (int flags);
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 57247f459fab..b41ca6b30a20 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -60,6 +60,7 @@
int fold_flag;
} abstract;
int lval;
+ cp_name_parser::qual_flag qual;
const char *opname;
}
@@ -84,7 +85,7 @@
%type <nested1> nested_name
-%type <lval> qualifier qualifiers qualifiers_opt
+%type <qual> qualifier qualifiers qualifiers_opt
%type <lval> int_part int_seq
@@ -518,16 +519,16 @@ function_arglist: '(' function_args ')' qualifiers_opt %prec NAME
/* Should do something about DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL */
qualifiers_opt : /* epsilon */
- { $$ = 0; }
+ { $$ = cp_name_parser::QUAL_NONE; }
| qualifiers
;
qualifier : RESTRICT
- { $$ = QUAL_RESTRICT; }
+ { $$ = cp_name_parser::QUAL_RESTRICT; }
| VOLATILE_KEYWORD
- { $$ = QUAL_VOLATILE; }
+ { $$ = cp_name_parser::QUAL_VOLATILE; }
| CONST_KEYWORD
- { $$ = QUAL_CONST; }
+ { $$ = cp_name_parser::QUAL_CONST; }
;
qualifiers : qualifier
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 2/7] gdb: convert INT_* macros into an enum_flags
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
2026-10-01 20:29 ` [PATCH 1/7] gdb: convert QUAL_* macros into an enum_flags Simon Marchi
@ 2026-10-01 20:30 ` Simon Marchi
2026-10-01 20:30 ` [PATCH 3/7] gdb: convert d_left and d_right macros into functions Simon Marchi
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Same as the previous patch, but for the INT_* macros passed to
cpname_state::d_int_type. Add an INT_NONE enumerator, since a raw enum
value can't be assigned 0:
CXX cp-name-parser-gen.o
gdb/cp-name-parser.y: In function ‘int cpname_yyparse(cp_name_parser::cpname_state*)’:
gdb/cp-name-parser.y:544:67: error: invalid conversion from ‘int’ to ‘cp_name_parser::int_flag’ [-fpermissive]
544 | { $$ = 0; }
| ^
| |
| int
Change-Id: Ia4e8b576adfd5b3baa3fb4c4beda2517d1d87449
---
gdb/cp-name-parser.c | 4 ++--
gdb/cp-name-parser.h | 27 ++++++++++++++++-----------
gdb/cp-name-parser.y | 19 +++++++++++--------
3 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/gdb/cp-name-parser.c b/gdb/cp-name-parser.c
index 569d102213c8..6615efd6abb1 100644
--- a/gdb/cp-name-parser.c
+++ b/gdb/cp-name-parser.c
@@ -147,7 +147,7 @@ cpname_state::d_qualify (struct demangle_component *lhs,
/* Return a builtin type corresponding to FLAGS. */
struct demangle_component *
-cpname_state::d_int_type (int flags)
+cpname_state::d_int_type (int_flags flags)
{
const char *name;
@@ -162,7 +162,7 @@ cpname_state::d_int_type (int flags)
case INT_UNSIGNED | INT_CHAR:
name = "unsigned char";
break;
- case 0:
+ case INT_NONE:
case INT_SIGNED:
name = "int";
break;
diff --git a/gdb/cp-name-parser.h b/gdb/cp-name-parser.h
index 7585379f5be2..083631f20a67 100644
--- a/gdb/cp-name-parser.h
+++ b/gdb/cp-name-parser.h
@@ -26,16 +26,6 @@
union cp_name_parser_YYSTYPE;
struct demangle_parse_info;
-/* Flags passed to cpname_state::d_int_type. */
-
-#define INT_CHAR (1 << 0)
-#define INT_SHORT (1 << 1)
-#define INT_LONG (1 << 2)
-#define INT_LLONG (1 << 3)
-
-#define INT_SIGNED (1 << 4)
-#define INT_UNSIGNED (1 << 5)
-
#define d_left(dc) (dc)->u.s_binary.left
#define d_right(dc) (dc)->u.s_binary.right
@@ -53,6 +43,21 @@ enum qual_flag
DEF_ENUM_FLAGS_TYPE (enum qual_flag, qual_flags);
+/* Integer type specifiers, passed to cpname_state::d_int_type. */
+
+enum int_flag
+{
+ INT_NONE = 0,
+ INT_CHAR = 1 << 0,
+ INT_SHORT = 1 << 1,
+ INT_LONG = 1 << 2,
+ INT_LLONG = 1 << 3,
+ INT_SIGNED = 1 << 4,
+ INT_UNSIGNED = 1 << 5,
+};
+
+DEF_ENUM_FLAGS_TYPE (enum int_flag, int_flags);
+
/* State of an ongoing parse. */
struct cpname_state
@@ -109,7 +114,7 @@ struct cpname_state
struct demangle_component *d_qualify (struct demangle_component *lhs,
qual_flags qualifiers, int is_method);
- struct demangle_component *d_int_type (int flags);
+ struct demangle_component *d_int_type (int_flags flags);
struct demangle_component *d_unary (const char *name,
struct demangle_component *lhs);
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index b41ca6b30a20..4b4be60f4fba 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -61,6 +61,7 @@
} abstract;
int lval;
cp_name_parser::qual_flag qual;
+ cp_name_parser::int_flag int_type;
const char *opname;
}
@@ -87,7 +88,7 @@
%type <qual> qualifier qualifiers qualifiers_opt
-%type <lval> int_part int_seq
+%type <int_type> int_part int_seq
%token <comp> INT
%token <comp> FLOAT
@@ -540,22 +541,24 @@ qualifiers : qualifier
invalid output for them - an error would be better. */
int_part : INT_KEYWORD
- { $$ = 0; }
+ { $$ = cp_name_parser::INT_NONE; }
| SIGNED_KEYWORD
- { $$ = INT_SIGNED; }
+ { $$ = cp_name_parser::INT_SIGNED; }
| UNSIGNED
- { $$ = INT_UNSIGNED; }
+ { $$ = cp_name_parser::INT_UNSIGNED; }
| CHAR
- { $$ = INT_CHAR; }
+ { $$ = cp_name_parser::INT_CHAR; }
| LONG
- { $$ = INT_LONG; }
+ { $$ = cp_name_parser::INT_LONG; }
| SHORT
- { $$ = INT_SHORT; }
+ { $$ = cp_name_parser::INT_SHORT; }
;
int_seq : int_part
| int_seq int_part
- { $$ = $1 | $2; if ($1 & $2 & INT_LONG) $$ = $1 | INT_LLONG; }
+ { $$ = $1 | $2;
+ if ($1 & $2 & cp_name_parser::INT_LONG)
+ $$ = $1 | cp_name_parser::INT_LLONG; }
;
builtin_type : int_seq
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 3/7] gdb: convert d_left and d_right macros into functions
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
2026-10-01 20:29 ` [PATCH 1/7] gdb: convert QUAL_* macros into an enum_flags Simon Marchi
2026-10-01 20:30 ` [PATCH 2/7] gdb: convert INT_* " Simon Marchi
@ 2026-10-01 20:30 ` Simon Marchi
2026-10-01 20:30 ` [PATCH 4/7] gdb: replace cp-name-parser.c macros with lambdas Simon Marchi
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Replace the d_left and d_right macros with static inline functions.
They need to return a reference, because some callers assign to the
result:
d_right ($1.last) = $2;
and some take the address:
$$.last = &d_right ($$.comp);
Change-Id: I7d8bd71ffde82a0fdfd2e2dcb87461043f82ef4f
---
gdb/cp-name-parser.h | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/gdb/cp-name-parser.h b/gdb/cp-name-parser.h
index 083631f20a67..f9d3a6968f9d 100644
--- a/gdb/cp-name-parser.h
+++ b/gdb/cp-name-parser.h
@@ -26,8 +26,21 @@
union cp_name_parser_YYSTYPE;
struct demangle_parse_info;
-#define d_left(dc) (dc)->u.s_binary.left
-#define d_right(dc) (dc)->u.s_binary.right
+/* Return a reference to the left child of binary component DC. */
+
+static inline struct demangle_component *&
+d_left (struct demangle_component *dc)
+{
+ return dc->u.s_binary.left;
+}
+
+/* Return a reference to the right child of binary component DC. */
+
+static inline struct demangle_component *&
+d_right (struct demangle_component *dc)
+{
+ return dc->u.s_binary.right;
+}
namespace cp_name_parser {
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 4/7] gdb: replace cp-name-parser.c macros with lambdas
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
` (2 preceding siblings ...)
2026-10-01 20:30 ` [PATCH 3/7] gdb: convert d_left and d_right macros into functions Simon Marchi
@ 2026-10-01 20:30 ` Simon Marchi
2026-10-01 20:30 ` [PATCH 5/7] gdb: use std::string for f-exp-parser.c's tempbuf Simon Marchi
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Replace the HANDLE_QUAL, HANDLE_SPECIAL, HANDLE_TOKEN2 and HANDLE_TOKEN3
macros with lambdas.
The lexer macros expanded to a return statement. The lambdas instead
return whether they matched, and the call sites return the token:
if (match_op_token ("-="))
return ASSIGN_MODIFY;
HANDLE_TOKEN2 and HANDLE_TOKEN3 only differed in the number of
characters they compared, so they become a single match_op_token lambda
comparing the whole string.
Change-Id: I1319e2e8bb9650ee253e429912c596df26ccaf6c
---
gdb/cp-name-parser.c | 202 +++++++++++++++++++++++++------------------
1 file changed, 120 insertions(+), 82 deletions(-)
diff --git a/gdb/cp-name-parser.c b/gdb/cp-name-parser.c
index 6615efd6abb1..80779fbc6062 100644
--- a/gdb/cp-name-parser.c
+++ b/gdb/cp-name-parser.c
@@ -113,33 +113,34 @@ struct demangle_component *
cpname_state::d_qualify (struct demangle_component *lhs,
qual_flags qualifiers, int is_method)
{
- struct demangle_component **inner_p;
- enum demangle_component_type type;
+ demangle_component **inner_p = &lhs;
+ demangle_component_type type = (*inner_p)->type;
+
+ auto handle_qual = [&] (demangle_component_type qual_type,
+ demangle_component_type method_qual_type,
+ qual_flag qual)
+ {
+ if ((qualifiers & qual) && type != qual_type && type != method_qual_type)
+ {
+ *inner_p = fill_comp (is_method ? method_qual_type : qual_type,
+ *inner_p, nullptr);
+ inner_p = &d_left (*inner_p);
+ type = (*inner_p)->type;
+ }
+ else if (type == qual_type || type == method_qual_type)
+ {
+ inner_p = &d_left (*inner_p);
+ type = (*inner_p)->type;
+ }
+ };
/* For now the order is CONST (innermost), VOLATILE, RESTRICT. */
-
-#define HANDLE_QUAL(TYPE, MTYPE, QUAL) \
- if ((qualifiers & QUAL) && (type != TYPE) && (type != MTYPE)) \
- { \
- *inner_p = fill_comp (is_method ? MTYPE : TYPE, \
- *inner_p, NULL); \
- inner_p = &d_left (*inner_p); \
- type = (*inner_p)->type; \
- } \
- else if (type == TYPE || type == MTYPE) \
- { \
- inner_p = &d_left (*inner_p); \
- type = (*inner_p)->type; \
- }
-
- inner_p = &lhs;
-
- type = (*inner_p)->type;
-
- HANDLE_QUAL (DEMANGLE_COMPONENT_RESTRICT, DEMANGLE_COMPONENT_RESTRICT_THIS, QUAL_RESTRICT);
- HANDLE_QUAL (DEMANGLE_COMPONENT_VOLATILE, DEMANGLE_COMPONENT_VOLATILE_THIS, QUAL_VOLATILE);
- HANDLE_QUAL (DEMANGLE_COMPONENT_CONST, DEMANGLE_COMPONENT_CONST_THIS, QUAL_CONST);
-#undef HANDLE_QUAL
+ handle_qual (DEMANGLE_COMPONENT_RESTRICT, DEMANGLE_COMPONENT_RESTRICT_THIS,
+ QUAL_RESTRICT);
+ handle_qual (DEMANGLE_COMPONENT_VOLATILE, DEMANGLE_COMPONENT_VOLATILE_THIS,
+ QUAL_VOLATILE);
+ handle_qual (DEMANGLE_COMPONENT_CONST, DEMANGLE_COMPONENT_CONST_THIS,
+ QUAL_CONST);
return lhs;
}
@@ -546,30 +547,6 @@ cp_parse_escape (const char **string_ptr)
}
}
-#define HANDLE_SPECIAL(string, comp) \
- if (startswith (tokstart, string)) \
- { \
- state->lexptr = tokstart + sizeof (string) - 1; \
- lvalp->lval = comp; \
- return DEMANGLER_SPECIAL; \
- }
-
-#define HANDLE_TOKEN2(string, token) \
- if (state->lexptr[1] == string[1]) \
- { \
- state->lexptr += 2; \
- lvalp->opname = string; \
- return token; \
- }
-
-#define HANDLE_TOKEN3(string, token) \
- if (state->lexptr[1] == string[1] && state->lexptr[2] == string[2]) \
- { \
- state->lexptr += 3; \
- lvalp->opname = string; \
- return token; \
- }
-
void
cpname_yyerror (cp_name_parser::cpname_state *state, const char *msg)
{
@@ -591,6 +568,30 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
const char *tokstart;
char *copy;
+ /* If the input starts with OP_STR, consume it, use OP_STR as the
+ token's operator name and return true. Otherwise, return false. */
+ auto match_op_token = [&] (const char *op_str)
+ {
+ if (!startswith (tokstart, op_str))
+ return false;
+
+ state->lexptr = tokstart + strlen (op_str);
+ lvalp->opname = op_str;
+ return true;
+ };
+
+ /* If the input starts with STR, consume it, use COMP as the token
+ value and return true. Otherwise, return false. */
+ auto match_special = [&] (const char *str, demangle_component_type comp)
+ {
+ if (!startswith (tokstart, str))
+ return false;
+
+ state->lexptr = tokstart + strlen (str);
+ lvalp->lval = comp;
+ return true;
+ };
+
retry:
state->prev_lexptr = state->lexptr;
tokstart = state->lexptr;
@@ -667,9 +668,12 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
goto try_number;
case '-':
- HANDLE_TOKEN2 ("-=", ASSIGN_MODIFY);
- HANDLE_TOKEN2 ("--", DECREMENT);
- HANDLE_TOKEN2 ("->", ARROW);
+ if (match_op_token ("-="))
+ return ASSIGN_MODIFY;
+ if (match_op_token ("--"))
+ return DECREMENT;
+ if (match_op_token ("->"))
+ return ARROW;
/* For construction vtables. This is kind of hokey. */
if (startswith (tokstart, "-in-"))
@@ -771,59 +775,79 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
}
case '+':
- HANDLE_TOKEN2 ("+=", ASSIGN_MODIFY);
- HANDLE_TOKEN2 ("++", INCREMENT);
+ if (match_op_token ("+="))
+ return ASSIGN_MODIFY;
+ if (match_op_token ("++"))
+ return INCREMENT;
state->lexptr++;
return c;
case '*':
- HANDLE_TOKEN2 ("*=", ASSIGN_MODIFY);
+ if (match_op_token ("*="))
+ return ASSIGN_MODIFY;
state->lexptr++;
return c;
case '/':
- HANDLE_TOKEN2 ("/=", ASSIGN_MODIFY);
+ if (match_op_token ("/="))
+ return ASSIGN_MODIFY;
state->lexptr++;
return c;
case '%':
- HANDLE_TOKEN2 ("%=", ASSIGN_MODIFY);
+ if (match_op_token ("%="))
+ return ASSIGN_MODIFY;
state->lexptr++;
return c;
case '|':
- HANDLE_TOKEN2 ("|=", ASSIGN_MODIFY);
- HANDLE_TOKEN2 ("||", OROR);
+ if (match_op_token ("|="))
+ return ASSIGN_MODIFY;
+ if (match_op_token ("||"))
+ return OROR;
state->lexptr++;
return c;
case '&':
- HANDLE_TOKEN2 ("&=", ASSIGN_MODIFY);
- HANDLE_TOKEN2 ("&&", ANDAND);
+ if (match_op_token ("&="))
+ return ASSIGN_MODIFY;
+ if (match_op_token ("&&"))
+ return ANDAND;
state->lexptr++;
return c;
case '^':
- HANDLE_TOKEN2 ("^=", ASSIGN_MODIFY);
+ if (match_op_token ("^="))
+ return ASSIGN_MODIFY;
state->lexptr++;
return c;
case '!':
- HANDLE_TOKEN2 ("!=", NOTEQUAL);
+ if (match_op_token ("!="))
+ return NOTEQUAL;
state->lexptr++;
return c;
case '<':
- HANDLE_TOKEN3 ("<<=", ASSIGN_MODIFY);
- HANDLE_TOKEN3 ("<=>", SPACESHIP);
- HANDLE_TOKEN2 ("<=", LEQ);
- HANDLE_TOKEN2 ("<<", LSH);
+ if (match_op_token ("<<="))
+ return ASSIGN_MODIFY;
+ if (match_op_token ("<=>"))
+ return SPACESHIP;
+ if (match_op_token ("<="))
+ return LEQ;
+ if (match_op_token ("<<"))
+ return LSH;
state->lexptr++;
return c;
case '>':
- HANDLE_TOKEN3 (">>=", ASSIGN_MODIFY);
- HANDLE_TOKEN2 (">=", GEQ);
- HANDLE_TOKEN2 (">>", RSH);
+ if (match_op_token (">>="))
+ return ASSIGN_MODIFY;
+ if (match_op_token (">="))
+ return GEQ;
+ if (match_op_token (">>"))
+ return RSH;
state->lexptr++;
return c;
case '=':
- HANDLE_TOKEN2 ("==", EQUAL);
+ if (match_op_token ("=="))
+ return EQUAL;
state->lexptr++;
return c;
case ':':
- HANDLE_TOKEN2 ("::", COLONCOLON);
+ if (match_op_token ("::"))
+ return COLONCOLON;
state->lexptr++;
return c;
@@ -882,13 +906,21 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
return STATIC_CAST;
break;
case 9:
- HANDLE_SPECIAL ("covariant return thunk to ", DEMANGLE_COMPONENT_COVARIANT_THUNK);
- HANDLE_SPECIAL ("reference temporary for ", DEMANGLE_COMPONENT_REFTEMP);
+ if (match_special ("covariant return thunk to ",
+ DEMANGLE_COMPONENT_COVARIANT_THUNK))
+ return DEMANGLER_SPECIAL;
+ if (match_special ("reference temporary for ",
+ DEMANGLE_COMPONENT_REFTEMP))
+ return DEMANGLER_SPECIAL;
break;
case 8:
- HANDLE_SPECIAL ("typeinfo for ", DEMANGLE_COMPONENT_TYPEINFO);
- HANDLE_SPECIAL ("typeinfo fn for ", DEMANGLE_COMPONENT_TYPEINFO_FN);
- HANDLE_SPECIAL ("typeinfo name for ", DEMANGLE_COMPONENT_TYPEINFO_NAME);
+ if (match_special ("typeinfo for ", DEMANGLE_COMPONENT_TYPEINFO))
+ return DEMANGLER_SPECIAL;
+ if (match_special ("typeinfo fn for ", DEMANGLE_COMPONENT_TYPEINFO_FN))
+ return DEMANGLER_SPECIAL;
+ if (match_special ("typeinfo name for ",
+ DEMANGLE_COMPONENT_TYPEINFO_NAME))
+ return DEMANGLER_SPECIAL;
if (startswith (tokstart, "operator"))
return OPERATOR;
if (startswith (tokstart, "restrict"))
@@ -901,7 +933,9 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
return VOLATILE_KEYWORD;
break;
case 7:
- HANDLE_SPECIAL ("virtual thunk to ", DEMANGLE_COMPONENT_VIRTUAL_THUNK);
+ if (match_special ("virtual thunk to ",
+ DEMANGLE_COMPONENT_VIRTUAL_THUNK))
+ return DEMANGLER_SPECIAL;
if (startswith (tokstart, "wchar_t"))
return WCHAR_T;
break;
@@ -929,7 +963,8 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
return DEMANGLER_SPECIAL;
}
- HANDLE_SPECIAL ("vtable for ", DEMANGLE_COMPONENT_VTABLE);
+ if (match_special ("vtable for ", DEMANGLE_COMPONENT_VTABLE))
+ return DEMANGLER_SPECIAL;
if (startswith (tokstart, "delete"))
return DELETE;
if (startswith (tokstart, "struct"))
@@ -942,7 +977,8 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
return DOUBLE_KEYWORD;
break;
case 5:
- HANDLE_SPECIAL ("guard variable for ", DEMANGLE_COMPONENT_GUARD);
+ if (match_special ("guard variable for ", DEMANGLE_COMPONENT_GUARD))
+ return DEMANGLER_SPECIAL;
if (startswith (tokstart, "false"))
return FALSEKEYWORD;
if (startswith (tokstart, "class"))
@@ -971,8 +1007,10 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp,
return TRUEKEYWORD;
break;
case 3:
- HANDLE_SPECIAL ("VTT for ", DEMANGLE_COMPONENT_VTT);
- HANDLE_SPECIAL ("non-virtual thunk to ", DEMANGLE_COMPONENT_THUNK);
+ if (match_special ("VTT for ", DEMANGLE_COMPONENT_VTT))
+ return DEMANGLER_SPECIAL;
+ if (match_special ("non-virtual thunk to ", DEMANGLE_COMPONENT_THUNK))
+ return DEMANGLER_SPECIAL;
if (startswith (tokstart, "new"))
return NEW;
if (startswith (tokstart, "int"))
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 5/7] gdb: use std::string for f-exp-parser.c's tempbuf
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
` (3 preceding siblings ...)
2026-10-01 20:30 ` [PATCH 4/7] gdb: replace cp-name-parser.c macros with lambdas Simon Marchi
@ 2026-10-01 20:30 ` Simon Marchi
2026-10-01 20:30 ` [PATCH 6/7] gdb: remove qsort kludge from ada-exp-parser.y Simon Marchi
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Replace the tempbuf / tempbufsize / tempbufindex trio, the
GROWBY_MIN_SIZE and CHECKBUF macros and the growbuf_by_size function
with a single std::string. match_string_literal is the only user of
that buffer. std::string null-terminates, so the explicit terminator
write goes away.
Change-Id: Ia978b6340d59e99b5c8f4dd0ea904471c66f37f6
---
gdb/f-exp-parser.c | 55 +++++++++++-----------------------------------
1 file changed, 13 insertions(+), 42 deletions(-)
diff --git a/gdb/f-exp-parser.c b/gdb/f-exp-parser.c
index 9e0c7aa6650c..010561d83ba5 100644
--- a/gdb/f-exp-parser.c
+++ b/gdb/f-exp-parser.c
@@ -25,7 +25,7 @@
#include "language.h"
#include "parser-defs.h"
#include "value.h"
-#include <algorithm>
+#include <string>
/* The entry point of the bison/yacc-generated parser, defined in
f-exp-parser-gen.c. Bison produces a declaration for f_yyparse in
@@ -574,40 +574,6 @@ static const f_token f_keywords[] =
{ "precision", PRECISION, OP_NULL, true },
};
-/* Implementation of a dynamically expandable buffer for processing input
- characters acquired through lexptr and building a value to return in
- yylval. Ripped off from ch-exp.y */
-
-static char *tempbuf; /* Current buffer contents */
-static int tempbufsize; /* Size of allocated buffer */
-static int tempbufindex; /* Current index into buffer */
-
-#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */
-
-#define CHECKBUF(size) \
- do { \
- if (tempbufindex + (size) >= tempbufsize) \
- { \
- growbuf_by_size (size); \
- } \
- } while (0);
-
-/* Grow the static temp buffer if necessary, including allocating the
- first one on demand. */
-
-static void
-growbuf_by_size (int count)
-{
- int growby;
-
- growby = std::max (count, GROWBY_MIN_SIZE);
- tempbufsize += growby;
- if (tempbuf == NULL)
- tempbuf = (char *) xmalloc (tempbufsize);
- else
- tempbuf = (char *) xrealloc (tempbuf, tempbufsize);
-}
-
/* Blatantly ripped off from ch-exp.y. This routine recognizes F77
string-literals.
@@ -622,9 +588,13 @@ match_string_literal (void)
{
const char *tokptr = pstate->lexptr;
- for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
+ /* Buffer used to build and hold the string value returned in f_yylval. Its
+ contents are only valid until the next call. */
+ static std::string tempbuf;
+
+ tempbuf.clear ();
+ for (tokptr++; *tokptr != '\0'; tokptr++)
{
- CHECKBUF (1);
if (*tokptr == *pstate->lexptr)
{
if (*(tokptr + 1) == *pstate->lexptr)
@@ -632,16 +602,17 @@ match_string_literal (void)
else
break;
}
- tempbuf[tempbufindex++] = *tokptr;
+
+ tempbuf += *tokptr;
}
+
if (*tokptr == '\0' /* no terminator */
- || tempbufindex == 0) /* no string */
+ || tempbuf.empty ()) /* no string */
return 0;
else
{
- tempbuf[tempbufindex] = '\0';
- f_yylval.sval.ptr = tempbuf;
- f_yylval.sval.length = tempbufindex;
+ f_yylval.sval.ptr = tempbuf.c_str ();
+ f_yylval.sval.length = tempbuf.size ();
pstate->lexptr = ++tokptr;
return STRING_LITERAL;
}
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 6/7] gdb: remove qsort kludge from ada-exp-parser.y
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
` (4 preceding siblings ...)
2026-10-01 20:30 ` [PATCH 5/7] gdb: use std::string for f-exp-parser.c's tempbuf Simon Marchi
@ 2026-10-01 20:30 ` Simon Marchi
2026-10-01 20:30 ` [PATCH 7/7] gdb: make COMPLETE_CHAR a constexpr Simon Marchi
2026-10-14 12:54 ` [PATCH 0/7] Leftovers from parsers cleanup Tom Tromey
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Remove the "#define qsort __qsort__dummy" kludge, which was there to
avoid a conflict between defs.h and non-standard stdlib.h files. This
was introduced in 2002, I am pretty sure this is not needed anymore.
Change-Id: I22d42f13ad4bdd6fc118ac4e1f30abdb79beb659
---
gdb/ada-exp-parser.y | 3 ---
1 file changed, 3 deletions(-)
diff --git a/gdb/ada-exp-parser.y b/gdb/ada-exp-parser.y
index b5b925e8911e..d37ab12c3bcf 100644
--- a/gdb/ada-exp-parser.y
+++ b/gdb/ada-exp-parser.y
@@ -838,7 +838,4 @@ primary : '*' primary %prec '.'
/* yylex defined in ada-lex-gen.c: Reads one token, getting characters */
/* through lexptr. */
-/* The following kludge was found necessary to prevent conflicts between */
-/* defs.h and non-standard stdlib.h files. */
-#define qsort __qsort__dummy
#include "ada-lex-gen.c"
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 7/7] gdb: make COMPLETE_CHAR a constexpr
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
` (5 preceding siblings ...)
2026-10-01 20:30 ` [PATCH 6/7] gdb: remove qsort kludge from ada-exp-parser.y Simon Marchi
@ 2026-10-01 20:30 ` Simon Marchi
2026-10-14 12:54 ` [PATCH 0/7] Leftovers from parsers cleanup Tom Tromey
7 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-01 20:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
In ada-exp-parser.h, make COMPLETE_CHAR a constexpr rather than a
macro.
While at it, fix the comment in ada-lex.l that refers to it. It used
the wrong name (COMPLETION_CHAR), and the constant is no longer
"below", it is now in ada-exp-parser.h. The explanation it points to
is now the comment on ada_parse_state::returned_complete.
Change-Id: I4ecfec782add66ab658bcb1494b1f78cdd432218
---
gdb/ada-exp-parser.h | 2 +-
gdb/ada-lex.l | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gdb/ada-exp-parser.h b/gdb/ada-exp-parser.h
index 0f438647437e..09a716e6636c 100644
--- a/gdb/ada-exp-parser.h
+++ b/gdb/ada-exp-parser.h
@@ -24,7 +24,7 @@
#include "parser-defs.h"
/* The character we use to represent the completion point. */
-#define COMPLETE_CHAR '\001'
+constexpr char COMPLETE_CHAR = '\001';
namespace ada_exp_parser
{
diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l
index 62edcd251966..857176c4d83d 100644
--- a/gdb/ada-lex.l
+++ b/gdb/ada-lex.l
@@ -39,8 +39,8 @@ OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs"
EXP (e[+-]{NUM10})
POSEXP (e"+"?{NUM10})
-/* This must agree with COMPLETION_CHAR below. See the comment there
- for the explanation. */
+/* This must agree with COMPLETE_CHAR in ada-exp-parser.h. See the
+ comment on ada_parse_state::returned_complete for the explanation. */
COMPLETE "\001"
NOT_COMPLETE [^\001]
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/7] Leftovers from parsers cleanup
2026-10-01 20:29 [PATCH 0/7] Leftovers from parsers cleanup Simon Marchi
` (6 preceding siblings ...)
2026-10-01 20:30 ` [PATCH 7/7] gdb: make COMPLETE_CHAR a constexpr Simon Marchi
@ 2026-10-14 12:54 ` Tom Tromey
2026-10-14 13:13 ` Simon Marchi
7 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2026-10-14 12:54 UTC (permalink / raw)
To: Simon Marchi; +Cc: gdb-patches
>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:
Simon> Here are a few random patches that I wrote when doing the parser cleanup
Simon> I just merged. I initially left them out because they were not
Simon> essential and the series was already long enough.
Thanks, this looks good.
Approved-By: Tom Tromey <tom@tromey.com>
Tom
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/7] Leftovers from parsers cleanup
2026-10-14 12:54 ` [PATCH 0/7] Leftovers from parsers cleanup Tom Tromey
@ 2026-10-14 13:13 ` Simon Marchi
0 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-10-14 13:13 UTC (permalink / raw)
To: Tom Tromey, Simon Marchi; +Cc: gdb-patches
On 10/14/26 8:54 AM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:
>
> Simon> Here are a few random patches that I wrote when doing the parser cleanup
> Simon> I just merged. I initially left them out because they were not
> Simon> essential and the series was already long enough.
>
> Thanks, this looks good.
> Approved-By: Tom Tromey <tom@tromey.com>
>
> Tom
Thanks, pushed.
Simon
^ permalink raw reply [flat|nested] 10+ messages in thread