/* Helper routines for C++ support in GDB.
- Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
Contributed by MontaVista Software.
#include "defs.h"
#include "cp-support.h"
-#include <string.h>
#include "demangle.h"
#include "gdbcmd.h"
#include "dictionary.h"
#include "block.h"
#include "complaints.h"
#include "gdbtypes.h"
-#include "exceptions.h"
#include "expression.h"
#include "value.h"
#include "cp-abi.h"
+#include "namespace.h"
#include <signal.h>
-
+#include "gdb_setjmp.h"
#include "safe-ctype.h"
#define d_left(dc) (dc)->u.s_binary.left
const char *oload_name);
static void make_symbol_overload_list_using (const char *func_name,
- const char *namespace);
+ const char *the_namespace);
static void make_symbol_overload_list_qualified (const char *func_name);
long *len)
{
*len = strlen (string);
- return obstack_copy (obstack, string, *len);
+ return (char *) obstack_copy (obstack, string, *len);
}
/* A cleanup wrapper for cp_demangled_name_parse_free. */
int i;
char *name;
struct symbol *sym;
- volatile struct gdb_exception except;
/* Copy the symbol's name from RET_COMP and look it up
in the symbol table. */
}
sym = NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
- }
- if (except.reason >= 0 && sym != NULL)
+ TRY
+ {
+ sym = lookup_symbol (name, 0, VAR_DOMAIN, 0).symbol;
+ }
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ return 0;
+ }
+ END_CATCH
+
+ if (sym != NULL)
{
struct type *otype = SYMBOL_TYPE (sym);
}
buf = mem_fileopen ();
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
type_print (type, "", buf, -1);
}
/* If type_print threw an exception, there is little point
in continuing, so just bow out gracefully. */
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ERROR)
{
ui_file_delete (buf);
return 0;
}
+ END_CATCH
name = ui_file_obsavestring (buf, &info->obstack, &len);
ui_file_delete (buf);
Canonicalize the name again, and store it in the
current node (RET_COMP). */
- char *canon = cp_canonicalize_string_no_typedefs (name);
+ std::string canon = cp_canonicalize_string_no_typedefs (name);
- if (canon != NULL)
+ if (!canon.empty ())
{
- /* Copy the canonicalization into the obstack and
- free CANON. */
- name = copy_string_to_obstack (&info->obstack, canon, &len);
- xfree (canon);
+ /* Copy the canonicalization into the obstack. */
+ name = copy_string_to_obstack (&info->obstack, canon.c_str (), &len);
}
ret_comp->u.s_name.s = name;
{
if (d_left (comp)->type == DEMANGLE_COMPONENT_NAME)
{
- struct demangle_component new;
+ struct demangle_component newobj;
ui_file_write (buf, d_left (comp)->u.s_name.s,
d_left (comp)->u.s_name.len);
name = ui_file_obsavestring (buf, &info->obstack, &len);
- new.type = DEMANGLE_COMPONENT_NAME;
- new.u.s_name.s = name;
- new.u.s_name.len = len;
- if (inspect_type (info, &new, finder, data))
+ newobj.type = DEMANGLE_COMPONENT_NAME;
+ newobj.u.s_name.s = name;
+ newobj.u.s_name.len = len;
+ if (inspect_type (info, &newobj, finder, data))
{
char *n, *s;
long slen;
node. */
ui_file_rewind (buf);
- n = cp_comp_to_string (&new, 100);
+ n = cp_comp_to_string (&newobj, 100);
if (n == NULL)
{
/* If something went astray, abort typedef substitutions. */
if (local_name != NULL)
{
- struct symbol *sym;
- volatile struct gdb_exception except;
+ struct symbol *sym = NULL;
sym = NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
+ {
+ sym = lookup_symbol (local_name, 0, VAR_DOMAIN, 0).symbol;
+ }
+ CATCH (except, RETURN_MASK_ALL)
{
- sym = lookup_symbol (local_name, 0, VAR_DOMAIN, 0);
}
+ END_CATCH
+
xfree (local_name);
- if (except.reason >= 0 && sym != NULL)
+ if (sym != NULL)
{
struct type *otype = SYMBOL_TYPE (sym);
const char *new_name = (*finder) (otype, data);
}
}
-/* Parse STRING and convert it to canonical form, resolving any typedefs.
- If parsing fails, or if STRING is already canonical, return NULL.
- Otherwise return the canonical form. The return value is allocated via
- xmalloc. If FINDER is not NULL, then type components are passed to
- FINDER to be looked up. DATA is passed verbatim to FINDER. */
+/* Parse STRING and convert it to canonical form, resolving any
+ typedefs. If parsing fails, or if STRING is already canonical,
+ return the empty string. Otherwise return the canonical form. If
+ FINDER is not NULL, then type components are passed to FINDER to be
+ looked up. DATA is passed verbatim to FINDER. */
-char *
+std::string
cp_canonicalize_string_full (const char *string,
canonicalization_ftype *finder,
void *data)
{
- char *ret;
+ std::string ret;
unsigned int estimated_len;
struct demangle_parse_info *info;
- ret = NULL;
estimated_len = strlen (string) * 2;
info = cp_demangled_name_to_comp (string, NULL);
if (info != NULL)
/* Convert the tree back into a string. */
ret = cp_comp_to_string (info->tree, estimated_len);
- gdb_assert (ret != NULL);
+ gdb_assert (!ret.empty ());
/* Free the parse information. */
cp_demangled_name_parse_free (info);
/* Finally, compare the original string with the computed
name, returning NULL if they are the same. */
- if (strcmp (string, ret) == 0)
- {
- xfree (ret);
- return NULL;
- }
+ if (ret == string)
+ return std::string ();
}
return ret;
/* Like cp_canonicalize_string_full, but always passes NULL for
FINDER. */
-char *
+std::string
cp_canonicalize_string_no_typedefs (const char *string)
{
return cp_canonicalize_string_full (string, NULL, NULL);
}
/* Parse STRING and convert it to canonical form. If parsing fails,
- or if STRING is already canonical, return NULL. Otherwise return
- the canonical form. The return value is allocated via xmalloc. */
+ or if STRING is already canonical, return the empty string.
+ Otherwise return the canonical form. */
-char *
+std::string
cp_canonicalize_string (const char *string)
{
struct demangle_parse_info *info;
unsigned int estimated_len;
- char *ret;
if (cp_already_canonical (string))
- return NULL;
+ return std::string ();
info = cp_demangled_name_to_comp (string, NULL);
if (info == NULL)
- return NULL;
+ return std::string ();
estimated_len = strlen (string) * 2;
- ret = cp_comp_to_string (info->tree, estimated_len);
+ std::string ret = cp_comp_to_string (info->tree, estimated_len);
cp_demangled_name_parse_free (info);
- if (ret == NULL)
+ if (ret.empty ())
{
warning (_("internal error: string \"%s\" failed to be canonicalized"),
string);
- return NULL;
+ return std::string ();
}
- if (strcmp (string, ret) == 0)
- {
- xfree (ret);
- return NULL;
- }
+ if (ret == string)
+ return std::string ();
return ret;
}
return strlen (name);
}
case '\0':
- case ':':
return index;
+ case ':':
+ /* ':' marks a component iff the next character is also a ':'.
+ Otherwise it is probably malformed input. */
+ if (name[index + 1] == ':')
+ return index;
+ break;
case 'o':
/* Operator names can screw up the recursion. */
if (operator_possible
struct symbol **
make_symbol_overload_list (const char *func_name,
- const char *namespace)
+ const char *the_namespace)
{
struct cleanup *old_cleanups;
const char *name;
sym_return_val_size = 100;
sym_return_val_index = 0;
- sym_return_val = xmalloc ((sym_return_val_size + 1) *
- sizeof (struct symbol *));
+ sym_return_val = XNEWVEC (struct symbol *, sym_return_val_size + 1);
sym_return_val[0] = NULL;
old_cleanups = make_cleanup (xfree, sym_return_val);
- make_symbol_overload_list_using (func_name, namespace);
+ make_symbol_overload_list_using (func_name, the_namespace);
- if (namespace[0] == '\0')
+ if (the_namespace[0] == '\0')
name = func_name;
else
{
char *concatenated_name
- = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
- strcpy (concatenated_name, namespace);
+ = (char *) alloca (strlen (the_namespace) + 2 + strlen (func_name) + 1);
+ strcpy (concatenated_name, the_namespace);
strcat (concatenated_name, "::");
strcat (concatenated_name, func_name);
name = concatenated_name;
struct block_iterator iter;
struct symbol *sym;
- for (sym = block_iter_name_first (block, name, &iter);
- sym != NULL;
- sym = block_iter_name_next (name, &iter))
+ ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
overload_list_add_symbol (sym, name);
}
static void
make_symbol_overload_list_namespace (const char *func_name,
- const char *namespace)
+ const char *the_namespace)
{
const char *name;
const struct block *block = NULL;
- if (namespace[0] == '\0')
+ if (the_namespace[0] == '\0')
name = func_name;
else
{
char *concatenated_name
- = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
+ = (char *) alloca (strlen (the_namespace) + 2 + strlen (func_name) + 1);
- strcpy (concatenated_name, namespace);
+ strcpy (concatenated_name, the_namespace);
strcat (concatenated_name, "::");
strcat (concatenated_name, func_name);
name = concatenated_name;
make_symbol_overload_list_adl_namespace (struct type *type,
const char *func_name)
{
- char *namespace;
+ char *the_namespace;
const char *type_name;
int i, prefix_len;
if (prefix_len != 0)
{
- namespace = alloca (prefix_len + 1);
- strncpy (namespace, type_name, prefix_len);
- namespace[prefix_len] = '\0';
+ the_namespace = (char *) alloca (prefix_len + 1);
+ strncpy (the_namespace, type_name, prefix_len);
+ the_namespace[prefix_len] = '\0';
- make_symbol_overload_list_namespace (func_name, namespace);
+ make_symbol_overload_list_namespace (func_name, the_namespace);
}
/* Check public base type */
- if (TYPE_CODE (type) == TYPE_CODE_CLASS)
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
{
if (BASETYPE_VIA_PUBLIC (type, i))
static void
reset_directive_searched (void *data)
{
- struct using_direct *direct = data;
+ struct using_direct *direct = (struct using_direct *) data;
direct->searched = 0;
}
static void
make_symbol_overload_list_using (const char *func_name,
- const char *namespace)
+ const char *the_namespace)
{
struct using_direct *current;
const struct block *block;
if (current->alias != NULL || current->declaration != NULL)
continue;
- if (strcmp (namespace, current->import_dest) == 0)
+ if (strcmp (the_namespace, current->import_dest) == 0)
{
/* Mark this import as searched so that the recursive call
does not search it again. */
}
/* Now, add names for this namespace. */
- make_symbol_overload_list_namespace (func_name, namespace);
+ make_symbol_overload_list_namespace (func_name, the_namespace);
}
/* This does the bulk of the work of finding overloaded symbols.
static void
make_symbol_overload_list_qualified (const char *func_name)
{
- struct symtab *s;
+ struct compunit_symtab *cust;
struct objfile *objfile;
const struct block *b, *surrounding_static_block = 0;
/* Go through the symtabs and check the externs and statics for
symbols which match. */
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_COMPUNITS (objfile, cust)
{
QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK);
make_symbol_overload_list_block (func_name, b);
}
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_COMPUNITS (objfile, cust)
{
QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK);
/* Don't do this block twice. */
if (b == surrounding_static_block)
continue;
struct symbol * rtti_sym;
struct type * rtti_type;
- rtti_sym = lookup_symbol (name, block, STRUCT_DOMAIN, NULL);
+ /* Use VAR_DOMAIN here as NAME may be a typedef. PR 18141, 18417.
+ Classes "live" in both STRUCT_DOMAIN and VAR_DOMAIN. */
+ rtti_sym = lookup_symbol (name, block, VAR_DOMAIN, NULL).symbol;
if (rtti_sym == NULL)
{
return NULL;
}
- rtti_type = SYMBOL_TYPE (rtti_sym);
+ rtti_type = check_typedef (SYMBOL_TYPE (rtti_sym));
switch (TYPE_CODE (rtti_type))
{
- case TYPE_CODE_CLASS:
+ case TYPE_CODE_STRUCT:
break;
case TYPE_CODE_NAMESPACE:
/* chastain/2003-11-26: the symbol tables often contain fake
static int catch_demangler_crashes = 1;
-/* Wrap set/long jmp so that it's more portable. */
-
-#if defined(HAVE_SIGSETJMP)
-#define SIGJMP_BUF sigjmp_buf
-#define SIGSETJMP(buf) sigsetjmp((buf), 1)
-#define SIGLONGJMP(buf,val) siglongjmp((buf), (val))
-#else
-#define SIGJMP_BUF jmp_buf
-#define SIGSETJMP(buf) setjmp(buf)
-#define SIGLONGJMP(buf,val) longjmp((buf), (val))
-#endif
-
/* Stack context and environment for demangler crash recovery. */
static SIGJMP_BUF gdb_demangle_jmp_buf;
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
struct sigaction sa, old_sa;
#else
- void (*ofunc) ();
+ sighandler_t ofunc;
#endif
static int core_dump_allowed = -1;
#endif
sigaction (SIGSEGV, &sa, &old_sa);
#else
- ofunc = (void (*)()) signal (SIGSEGV, gdb_demangle_signal_handler);
+ ofunc = signal (SIGSEGV, gdb_demangle_signal_handler);
#endif
crash_signal = SIGSETJMP (gdb_demangle_jmp_buf);
"demangler-warning", short_msg);
make_cleanup (xfree, long_msg);
- target_terminal_ours ();
+ make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
begin_line ();
if (core_dump_allowed)
fprintf_unfiltered (gdb_stderr,
return result;
}
+/* See cp-support.h. */
+
+int
+gdb_sniff_from_mangled_name (const char *mangled, char **demangled)
+{
+ *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+ return *demangled != NULL;
+}
+
/* Don't allow just "maintenance cplus". */
static void
return;
len = cp_find_first_component (arg);
- prefix = alloca (len + 1);
+ prefix = (char *) alloca (len + 1);
memcpy (prefix, arg, len);
prefix[len] = '\0';