aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@efficios.com>2024-07-24 15:07:14 -0400
committerSimon Marchi <simon.marchi@efficios.com>2024-07-30 08:52:57 -0400
commit1cb8a69ec2955e736e24340ef476fed5abeb7703 (patch)
tree455e2660fbd9baef25503f966967702810efc008 /gdb
parenta7763df8fbabe0d364d7f1e418683ee460518998 (diff)
downloadbinutils-1cb8a69ec2955e736e24340ef476fed5abeb7703.zip
binutils-1cb8a69ec2955e736e24340ef476fed5abeb7703.tar.gz
binutils-1cb8a69ec2955e736e24340ef476fed5abeb7703.tar.bz2
gdb: use std::string vector for macro definition
Use std::vector<std::string> when defining macros, to avoid the manual memory management. With the use of std::vector, the separate `int argc` parameter is no longer needed, we can use the size of the vector instead. However, for some functions, this parameter had a dual function. For object-like macros, it was interpreted as a `macro_special_kind` enum. For these functions, remove `argc`, but add a new `special_kind` parameter. Change-Id: Ice76a6863dfe598335e3b8d5d077513e50975cc5 Approved-By: Tom de Vries <tdevries@suse.de>
Diffstat (limited to 'gdb')
-rw-r--r--gdb/dwarf2/macro.c28
-rw-r--r--gdb/macrocmd.c93
-rw-r--r--gdb/macrotab.c83
-rw-r--r--gdb/macrotab.h21
4 files changed, 81 insertions, 144 deletions
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index bc781c2..b2bf95d 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -160,9 +160,7 @@ parse_macro_definition (struct macro_source_file *file, int line,
/* It's a function-like macro. */
gdb_assert (*p == '(');
std::string name (body, p - body);
- int argc = 0;
- int argv_size = 1;
- char **argv = XNEWVEC (char *, argv_size);
+ std::vector<std::string> argv;
p++;
@@ -180,16 +178,7 @@ parse_macro_definition (struct macro_source_file *file, int line,
if (! *p || p == arg_start)
dwarf2_macro_malformed_definition_complaint (body);
else
- {
- /* Make sure argv has room for the new argument. */
- if (argc >= argv_size)
- {
- argv_size *= 2;
- argv = XRESIZEVEC (char *, argv, argv_size);
- }
-
- argv[argc++] = savestring (arg_start, p - arg_start);
- }
+ argv.emplace_back (arg_start, p);
p = consume_improper_spaces (p, body);
@@ -208,16 +197,12 @@ parse_macro_definition (struct macro_source_file *file, int line,
if (*p == ' ')
/* Perfectly formed definition, no complaints. */
- macro_define_function (file, line, name.c_str (),
- argc, (const char **) argv,
- p + 1);
+ macro_define_function (file, line, name.c_str (), argv, p + 1);
else if (*p == '\0')
{
/* Complain, but do define it. */
dwarf2_macro_malformed_definition_complaint (body);
- macro_define_function (file, line, name.c_str (),
- argc, (const char **) argv,
- p);
+ macro_define_function (file, line, name.c_str (), argv, p);
}
else
/* Just complain. */
@@ -226,11 +211,6 @@ parse_macro_definition (struct macro_source_file *file, int line,
else
/* Just complain. */
dwarf2_macro_malformed_definition_complaint (body);
-
- for (int i = 0; i < argc; i++)
- xfree (argv[i]);
-
- xfree (argv);
}
/* Skip some bytes from BYTES according to the form given in FORM.
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index 6cf3a0d..2da5a5b 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -271,18 +271,17 @@ skip_ws (const char **expp)
}
/* Try to find the bounds of an identifier. If an identifier is
- found, returns a newly allocated string; otherwise returns NULL.
+ found, return it; otherwise return an empty string.
+
EXPP is a pointer to an input string; it is updated to point to the
text following the identifier. If IS_PARAMETER is true, this
function will also allow "..." forms as used in varargs macro
parameters. */
-static gdb::unique_xmalloc_ptr<char>
+static std::string
extract_identifier (const char **expp, int is_parameter)
{
- char *result;
const char *p = *expp;
- unsigned int len;
if (is_parameter && startswith (p, "..."))
{
@@ -291,67 +290,39 @@ extract_identifier (const char **expp, int is_parameter)
else
{
if (! *p || ! macro_is_identifier_nondigit (*p))
- return NULL;
+ return {};
+
for (++p;
*p && (macro_is_identifier_nondigit (*p) || macro_is_digit (*p));
++p)
;
}
- if (is_parameter && startswith (p, "..."))
+ if (is_parameter && startswith (p, "..."))
p += 3;
- len = p - *expp;
- result = (char *) xmalloc (len + 1);
- memcpy (result, *expp, len);
- result[len] = '\0';
- *expp += len;
- return gdb::unique_xmalloc_ptr<char> (result);
-}
+ std::string result (*expp, p);
+ *expp = p;
-struct temporary_macro_definition : public macro_definition
-{
- temporary_macro_definition ()
- {
- table = nullptr;
- kind = macro_object_like;
- argc = 0;
- argv = nullptr;
- replacement = nullptr;
- }
-
- ~temporary_macro_definition ()
- {
- int i;
-
- for (i = 0; i < argc; ++i)
- xfree ((char *) argv[i]);
- xfree ((char *) argv);
- /* Note that the 'replacement' field is not allocated. */
- }
-};
+ return result;
+}
static void
macro_define_command (const char *exp, int from_tty)
{
- temporary_macro_definition new_macro;
-
if (!exp)
error (_("usage: macro define NAME[(ARGUMENT-LIST)] [REPLACEMENT-LIST]"));
skip_ws (&exp);
- gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0);
- if (name == NULL)
+
+ std::string name = extract_identifier (&exp, 0);
+ if (name.empty ())
error (_("Invalid macro name."));
+
if (*exp == '(')
{
/* Function-like macro. */
- int alloced = 5;
- char **argv = XNEWVEC (char *, alloced);
-
- new_macro.kind = macro_function_like;
- new_macro.argc = 0;
- new_macro.argv = (const char * const *) argv;
+ std::vector<std::string> argv;
/* Skip the '(' and whitespace. */
++exp;
@@ -359,23 +330,13 @@ macro_define_command (const char *exp, int from_tty)
while (*exp != ')')
{
- int i;
-
- if (new_macro.argc == alloced)
- {
- alloced *= 2;
- argv = (char **) xrealloc (argv, alloced * sizeof (char *));
- /* Must update new_macro as well... */
- new_macro.argv = (const char * const *) argv;
- }
- argv[new_macro.argc] = extract_identifier (&exp, 1).release ();
- if (! argv[new_macro.argc])
+ argv.emplace_back (extract_identifier (&exp, 1));
+ if (argv.back ().empty ())
error (_("Macro is missing an argument."));
- ++new_macro.argc;
- for (i = new_macro.argc - 2; i >= 0; --i)
+ for (const auto &other_arg : argv)
{
- if (! strcmp (argv[i], argv[new_macro.argc - 1]))
+ if (&other_arg != &argv.back () && other_arg == argv.back ())
error (_("Two macro arguments with identical names."));
}
@@ -388,18 +349,18 @@ macro_define_command (const char *exp, int from_tty)
else if (*exp != ')')
error (_("',' or ')' expected at end of macro arguments."));
}
+
/* Skip the closing paren. */
++exp;
skip_ws (&exp);
- macro_define_function (macro_main (macro_user_macros), -1, name.get (),
- new_macro.argc, (const char **) new_macro.argv,
- exp);
+ macro_define_function (macro_main (macro_user_macros), -1, name.c_str (),
+ argv, exp);
}
else
{
skip_ws (&exp);
- macro_define_object (macro_main (macro_user_macros), -1, name.get (),
+ macro_define_object (macro_main (macro_user_macros), -1, name.c_str (),
exp);
}
}
@@ -412,10 +373,12 @@ macro_undef_command (const char *exp, int from_tty)
error (_("usage: macro undef NAME"));
skip_ws (&exp);
- gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0);
- if (name == nullptr)
+
+ std::string name = extract_identifier (&exp, 0);
+ if (name.empty ())
error (_("Invalid macro name."));
- macro_undef (macro_main (macro_user_macros), -1, name.get ());
+
+ macro_undef (macro_main (macro_user_macros), -1, name.c_str ());
}
diff --git a/gdb/macrotab.c b/gdb/macrotab.c
index 3a7f792..81fe165 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -545,10 +545,10 @@ macro_lookup_inclusion (struct macro_source_file *source, const char *name)
/* Construct a definition for a macro in table T. Cache all strings,
and the macro_definition structure itself, in T's bcache. */
-static struct macro_definition *
-new_macro_definition (struct macro_table *t,
- enum macro_kind kind,
- int argc, const char **argv,
+static macro_definition *
+new_macro_definition (macro_table *t, macro_kind kind,
+ macro_special_kind special_kind,
+ const std::vector<std::string> &argv,
const char *replacement)
{
struct macro_definition *d
@@ -558,22 +558,24 @@ new_macro_definition (struct macro_table *t,
d->table = t;
d->kind = kind;
d->replacement = macro_bcache_str (t, replacement);
- d->argc = argc;
if (kind == macro_function_like)
{
- int i;
- const char **cached_argv;
- int cached_argv_size = argc * sizeof (*cached_argv);
+ d->argc = argv.size ();
/* Bcache all the arguments. */
- cached_argv = (const char **) alloca (cached_argv_size);
- for (i = 0; i < argc; i++)
- cached_argv[i] = macro_bcache_str (t, argv[i]);
+ int i = 0;
+ int cached_argv_size = argv.size () * sizeof (const char *);
+ const char **cached_argv = (const char **) alloca (cached_argv_size);
+
+ for (const auto &arg : argv)
+ cached_argv[i++] = macro_bcache_str (t, arg.c_str ());
/* Now bcache the array of argument pointers itself. */
d->argv = macro_bcache (t, cached_argv, cached_argv_size);
}
+ else
+ d->argc = special_kind;
/* We don't bcache the entire definition structure because it's got
a pointer to the macro table in it; since each compilation unit
@@ -677,13 +679,12 @@ find_definition (const char *name,
/* If NAME already has a definition in scope at LINE in SOURCE, return
the key. If the old definition is different from the definition
- given by KIND, ARGC, ARGV, and REPLACEMENT, complain, too.
- Otherwise, return zero. (ARGC and ARGV are meaningless unless KIND
+ given by KIND, ARGV, and REPLACEMENT, complain, too.
+ Otherwise, return nullptr. (ARGV is meaningless unless KIND
is `macro_function_like'.) */
-static struct macro_key *
-check_for_redefinition (struct macro_source_file *source, int line,
- const char *name, enum macro_kind kind,
- int argc, const char **argv,
+static macro_key *
+check_for_redefinition (macro_source_file *source, int line, const char *name,
+ macro_kind kind, const std::vector<std::string> &argv,
const char *replacement)
{
splay_tree_node n = find_definition (name, source, line);
@@ -708,14 +709,14 @@ check_for_redefinition (struct macro_source_file *source, int line,
same = 0;
else if (kind == macro_function_like)
{
- if (argc != found_def->argc)
+ if (argv.size () != found_def->argc)
same = 0;
else
{
- int i;
+ int i = 0;
- for (i = 0; i < argc; i++)
- if (strcmp (argv[i], found_def->argv[i]))
+ for (const auto &arg : argv)
+ if (arg != found_def->argv[i++])
same = 0;
}
}
@@ -739,15 +740,18 @@ check_for_redefinition (struct macro_source_file *source, int line,
}
/* A helper function to define a new object-like or function-like macro
- according to KIND. When KIND is macro_object_like,
- the macro_special_kind must be provided as ARGC, and ARGV must be NULL.
- When KIND is macro_function_like, ARGC and ARGV are giving the function
- arguments. */
+ according to KIND.
+
+ When KIND is macro_object_like, the possible special kind is given by
+ SPECIAL_KIND, and ARGV is meaningless.
+
+ When KIND is macro_function_like, ARGV gives the macro argument names, and
+ SPECIAL_KIND is meaningless. */
static void
-macro_define_internal (struct macro_source_file *source, int line,
- const char *name, enum macro_kind kind,
- int argc, const char **argv,
+macro_define_internal (macro_source_file *source, int line, const char *name,
+ macro_kind kind, macro_special_kind special_kind,
+ const std::vector<std::string> &argv,
const char *replacement)
{
struct macro_table *t = source->table;
@@ -755,10 +759,7 @@ macro_define_internal (struct macro_source_file *source, int line,
struct macro_definition *d;
if (! t->redef_ok)
- k = check_for_redefinition (source, line,
- name, kind,
- argc, argv,
- replacement);
+ k = check_for_redefinition (source, line, name, kind, argv, replacement);
/* If we're redefining a symbol, and the existing key would be
identical to our new key, then the splay_tree_insert function
@@ -774,7 +775,7 @@ macro_define_internal (struct macro_source_file *source, int line,
return;
k = new_macro_key (t, name, source, line);
- d = new_macro_definition (t, kind, argc, argv, replacement);
+ d = new_macro_definition (t, kind, special_kind, argv, replacement);
splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
}
@@ -785,10 +786,8 @@ macro_define_object_internal (struct macro_source_file *source, int line,
const char *name, const char *replacement,
enum macro_special_kind special_kind)
{
- macro_define_internal (source, line,
- name, macro_object_like,
- special_kind, NULL,
- replacement);
+ macro_define_internal (source, line, name, macro_object_like, special_kind,
+ {}, replacement);
}
void
@@ -811,14 +810,12 @@ macro_define_special (struct macro_table *table)
}
void
-macro_define_function (struct macro_source_file *source, int line,
- const char *name, int argc, const char **argv,
+macro_define_function (macro_source_file *source, int line, const char *name,
+ const std::vector<std::string> &argv,
const char *replacement)
{
- macro_define_internal (source, line,
- name, macro_function_like,
- argc, argv,
- replacement);
+ macro_define_internal (source, line, name, macro_function_like,
+ macro_ordinary, argv, replacement);
}
void
diff --git a/gdb/macrotab.h b/gdb/macrotab.h
index 789beed..d501595 100644
--- a/gdb/macrotab.h
+++ b/gdb/macrotab.h
@@ -242,26 +242,23 @@ struct macro_source_file *macro_lookup_inclusion
Record in SOURCE's macro table that, at line number LINE in SOURCE,
we #defined a preprocessor symbol named NAME, whose replacement
string is REPLACEMENT. This function makes copies of NAME and
- REPLACEMENT; the caller is responsible for freeing them. */
+ REPLACEMENT. */
void macro_define_object (struct macro_source_file *source, int line,
const char *name, const char *replacement);
-/* Record an function-like #definition (i.e., one with a parameter list).
+/* Record a function-like #definition (i.e., one with a parameter list).
Record in SOURCE's macro table that, at line number LINE in SOURCE,
- we #defined a preprocessor symbol named NAME, with ARGC arguments
- whose names are given in ARGV, whose replacement string is REPLACEMENT. If
- the macro takes a variable number of arguments, then ARGC should be
- one greater than the number of named arguments, and ARGV[ARGC-1]
- should be the string "...". This function makes its own copies of
- NAME, ARGV, and REPLACEMENT; the caller is responsible for freeing
- them. */
-void macro_define_function (struct macro_source_file *source, int line,
- const char *name, int argc, const char **argv,
+ we #defined a preprocessor symbol named NAME, with argument names given by
+ ARGV, whose replacement string is REPLACEMENT. If the macro takes a variable
+ number of arguments, then the last element of ARGV should be the string
+ "...". This function makes copies of NAME, ARGV, and REPLACEMENT. */
+void macro_define_function (macro_source_file *source, int line,
+ const char *name,
+ const std::vector<std::string> &argv,
const char *replacement);
-
/* Record an #undefinition.
Record in SOURCE's macro table that, at line number LINE in SOURCE,
we removed the definition for the preprocessor symbol named NAME. */