diff options
author | Simon Marchi <simon.marchi@efficios.com> | 2024-07-24 15:07:14 -0400 |
---|---|---|
committer | Simon Marchi <simon.marchi@efficios.com> | 2024-07-30 08:52:57 -0400 |
commit | 1cb8a69ec2955e736e24340ef476fed5abeb7703 (patch) | |
tree | 455e2660fbd9baef25503f966967702810efc008 /gdb | |
parent | a7763df8fbabe0d364d7f1e418683ee460518998 (diff) | |
download | binutils-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.c | 28 | ||||
-rw-r--r-- | gdb/macrocmd.c | 93 | ||||
-rw-r--r-- | gdb/macrotab.c | 83 | ||||
-rw-r--r-- | gdb/macrotab.h | 21 |
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. */ |