#include "cp-abi.h"
#include "namespace.h"
#include <signal.h>
-#include "gdb_setjmp.h"
+#include "gdbsupport/gdb_setjmp.h"
#include "safe-ctype.h"
-#include "selftest.h"
+#include "gdbsupport/selftest.h"
#define d_left(dc) (dc)->u.s_binary.left
#define d_right(dc) (dc)->u.s_binary.right
sym = NULL;
- TRY
+ try
{
sym = lookup_symbol (name, 0, VAR_DOMAIN, 0).symbol;
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
return 0;
}
- END_CATCH
if (sym != NULL)
{
/* Get the real type of the typedef. */
type = check_typedef (otype);
- /* If the symbol is a namespace and its type name is no different
+ /* If the symbol name is the same as the original type name,
+ don't substitute. That would cause infinite recursion in
+ symbol lookups, as the typedef symbol is often the first
+ found symbol in the symbol table.
+
+ However, this can happen in a number of situations, such as:
+
+ If the symbol is a namespace and its type name is no different
than the name we looked up, this symbol is not a namespace
- alias and does not need to be substituted. */
- if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE
+ alias and does not need to be substituted.
+
+ If the symbol is typedef and its type name is the same
+ as the symbol's name, e.g., "typedef struct foo foo;". */
+ if (TYPE_NAME (type) != nullptr
&& strcmp (TYPE_NAME (type), name) == 0)
return 0;
}
string_file buf;
- TRY
+ try
{
type_print (type, "", &buf, -1);
}
/* If type_print threw an exception, there is little point
in continuing, so just bow out gracefully. */
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
return 0;
}
- END_CATCH
len = buf.size ();
- name = (char *) obstack_copy0 (&info->obstack, buf.c_str (), len);
+ name = obstack_strdup (&info->obstack, buf.string ());
/* Turn the result into a new tree. Note that this
tree will contain pointers into NAME, so NAME cannot
buf.write (d_left (comp)->u.s_name.s, d_left (comp)->u.s_name.len);
newobj.type = DEMANGLE_COMPONENT_NAME;
- newobj.u.s_name.s
- = (char *) obstack_copy0 (&info->obstack,
- buf.c_str (), buf.size ());
+ newobj.u.s_name.s = obstack_strdup (&info->obstack, buf.string ());
newobj.u.s_name.len = buf.size ();
if (inspect_type (info, &newobj, finder, data))
{
with a DEMANGLE_COMPONENT_NAME node containing the whole
name. */
ret_comp->type = DEMANGLE_COMPONENT_NAME;
- ret_comp->u.s_name.s
- = (char *) obstack_copy0 (&info->obstack,
- buf.c_str (), buf.size ());
+ ret_comp->u.s_name.s = obstack_strdup (&info->obstack, buf.string ());
ret_comp->u.s_name.len = buf.size ();
inspect_type (info, ret_comp, finder, data);
}
struct symbol *sym = NULL;
sym = NULL;
- TRY
+ try
{
sym = lookup_symbol (local_name.get (), 0,
VAR_DOMAIN, 0).symbol;
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
}
- END_CATCH
if (sym != NULL)
{
we're completing / matching everything, avoid returning NULL
which would make callers interpret the result as an error. */
if (demangled_name[0] == '\0' && completion_mode)
- return gdb::unique_xmalloc_ptr<char> (xstrdup (""));
+ return make_unique_xstrdup ("");
gdb::unique_xmalloc_ptr<char> without_params
= cp_remove_params_1 (demangled_name, false);
add_symbol_overload_list_qualified (const char *func_name,
std::vector<symbol *> *overload_list)
{
- struct compunit_symtab *cust;
const struct block *b, *surrounding_static_block = 0;
/* Look through the partial symtabs for all symbols which begin by
matching FUNC_NAME. Make sure we read that symbol table in. */
- for (objfile *objf : all_objfiles (current_program_space))
+ for (objfile *objf : current_program_space->objfiles ())
{
if (objf->sf)
objf->sf->qf->expand_symtabs_for_function (objf, func_name);
/* Go through the symtabs and check the externs and statics for
symbols which match. */
- struct objfile *objfile;
- ALL_COMPUNITS (objfile, cust)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK);
- add_symbol_overload_list_block (func_name, b, overload_list);
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ for (compunit_symtab *cust : objfile->compunits ())
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK);
+ add_symbol_overload_list_block (func_name, b, overload_list);
+ }
+ }
- ALL_COMPUNITS (objfile, cust)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
- add_symbol_overload_list_block (func_name, b, overload_list);
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ for (compunit_symtab *cust : objfile->compunits ())
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ add_symbol_overload_list_block (func_name, b, overload_list);
+ }
+ }
}
/* Lookup the rtti type for a class name. */
struct type *
-cp_lookup_rtti_type (const char *name, struct block *block)
+cp_lookup_rtti_type (const char *name, const struct block *block)
{
struct symbol * rtti_sym;
struct type * rtti_type;
#ifdef HAVE_WORKING_FORK
-/* If nonzero, attempt to catch crashes in the demangler and print
+/* If true, attempt to catch crashes in the demangler and print
useful debugging information. */
-static int catch_demangler_crashes = 1;
+static bool catch_demangler_crashes = true;
/* Stack context and environment for demangler crash recovery. */
ofunc = signal (SIGSEGV, gdb_demangle_signal_handler);
#endif
- crash_signal = SIGSETJMP (gdb_demangle_jmp_buf);
+ /* The signal handler may keep the signal blocked when we longjmp out
+ of it. If we have sigprocmask, we can use it to unblock the signal
+ afterwards and we can avoid the performance overhead of saving the
+ signal mask just in case the signal gets triggered. Otherwise, just
+ tell sigsetjmp to save the mask. */
+#ifdef HAVE_SIGPROCMASK
+ crash_signal = SIGSETJMP (gdb_demangle_jmp_buf, 0);
+#else
+ crash_signal = SIGSETJMP (gdb_demangle_jmp_buf, 1);
+#endif
}
#endif
{
static int error_reported = 0;
+#ifdef HAVE_SIGPROCMASK
+ /* If we got the signal, SIGSEGV may still be blocked; restore it. */
+ sigset_t segv_sig_set;
+ sigemptyset (&segv_sig_set);
+ sigaddset (&segv_sig_set, SIGSEGV);
+ sigprocmask (SIG_UNBLOCK, &segv_sig_set, NULL);
+#endif
+
if (!error_reported)
{
std::string short_msg