mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
97e20099d3
PR exp/28359 points out that 'ptype/o' does not work when the current language is "asm". I tracked this down to a hard-coded list of languages in typeprint.c. This patch replaces this list with a method on 'language_defn' instead. If all languages are ever updated to have this feature, the method could be removed; but in the meantime this lets each language control what happens. I looked at having each print_type method simply modify the flags itself, but this doesn't work very well with the feature that disables method-printing by default (but allows it via a flag). Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28359 Approved-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Keith Seitz <keiths@redhat.com>
290 lines
8.5 KiB
C
290 lines
8.5 KiB
C
/* D language support routines for GDB, the GNU debugger.
|
|
|
|
Copyright (C) 2005-2022 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#include "defs.h"
|
|
#include "symtab.h"
|
|
#include "language.h"
|
|
#include "varobj.h"
|
|
#include "d-lang.h"
|
|
#include "c-lang.h"
|
|
#include "demangle.h"
|
|
#include "cp-support.h"
|
|
#include "gdbarch.h"
|
|
#include "parser-defs.h"
|
|
|
|
/* The name of the symbol to use to get the name of the main subprogram. */
|
|
static const char D_MAIN[] = "D main";
|
|
|
|
/* Function returning the special symbol name used by D for the main
|
|
procedure in the main program if it is found in minimal symbol list.
|
|
This function tries to find minimal symbols so that it finds them even
|
|
if the program was compiled without debugging information. */
|
|
|
|
const char *
|
|
d_main_name (void)
|
|
{
|
|
struct bound_minimal_symbol msym;
|
|
|
|
msym = lookup_minimal_symbol (D_MAIN, NULL, NULL);
|
|
if (msym.minsym != NULL)
|
|
return D_MAIN;
|
|
|
|
/* No known entry procedure found, the main program is probably not D. */
|
|
return NULL;
|
|
}
|
|
|
|
/* Implements the la_demangle language_defn routine for language D. */
|
|
|
|
gdb::unique_xmalloc_ptr<char>
|
|
d_demangle (const char *symbol, int options)
|
|
{
|
|
return gdb_demangle (symbol, options | DMGL_DLANG);
|
|
}
|
|
|
|
/* Class representing the D language. */
|
|
|
|
class d_language : public language_defn
|
|
{
|
|
public:
|
|
d_language ()
|
|
: language_defn (language_d)
|
|
{ /* Nothing. */ }
|
|
|
|
/* See language.h. */
|
|
|
|
const char *name () const override
|
|
{ return "d"; }
|
|
|
|
/* See language.h. */
|
|
|
|
const char *natural_name () const override
|
|
{ return "D"; }
|
|
|
|
/* See language.h. */
|
|
|
|
const std::vector<const char *> &filename_extensions () const override
|
|
{
|
|
static const std::vector<const char *> extensions = { ".d" };
|
|
return extensions;
|
|
}
|
|
|
|
/* See language.h. */
|
|
void language_arch_info (struct gdbarch *gdbarch,
|
|
struct language_arch_info *lai) const override
|
|
{
|
|
const struct builtin_d_type *builtin = builtin_d_type (gdbarch);
|
|
|
|
/* Helper function to allow shorter lines below. */
|
|
auto add = [&] (struct type * t)
|
|
{
|
|
lai->add_primitive_type (t);
|
|
};
|
|
|
|
add (builtin->builtin_void);
|
|
add (builtin->builtin_bool);
|
|
add (builtin->builtin_byte);
|
|
add (builtin->builtin_ubyte);
|
|
add (builtin->builtin_short);
|
|
add (builtin->builtin_ushort);
|
|
add (builtin->builtin_int);
|
|
add (builtin->builtin_uint);
|
|
add (builtin->builtin_long);
|
|
add (builtin->builtin_ulong);
|
|
add (builtin->builtin_cent);
|
|
add (builtin->builtin_ucent);
|
|
add (builtin->builtin_float);
|
|
add (builtin->builtin_double);
|
|
add (builtin->builtin_real);
|
|
add (builtin->builtin_ifloat);
|
|
add (builtin->builtin_idouble);
|
|
add (builtin->builtin_ireal);
|
|
add (builtin->builtin_cfloat);
|
|
add (builtin->builtin_cdouble);
|
|
add (builtin->builtin_creal);
|
|
add (builtin->builtin_char);
|
|
add (builtin->builtin_wchar);
|
|
add (builtin->builtin_dchar);
|
|
|
|
lai->set_string_char_type (builtin->builtin_char);
|
|
lai->set_bool_type (builtin->builtin_bool, "bool");
|
|
}
|
|
|
|
/* See language.h. */
|
|
bool sniff_from_mangled_name
|
|
(const char *mangled,
|
|
gdb::unique_xmalloc_ptr<char> *demangled) const override
|
|
{
|
|
*demangled = d_demangle (mangled, 0);
|
|
return *demangled != NULL;
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
gdb::unique_xmalloc_ptr<char> demangle_symbol (const char *mangled,
|
|
int options) const override
|
|
{
|
|
return d_demangle (mangled, options);
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
bool can_print_type_offsets () const override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
void print_type (struct type *type, const char *varstring,
|
|
struct ui_file *stream, int show, int level,
|
|
const struct type_print_options *flags) const override
|
|
{
|
|
c_print_type (type, varstring, stream, show, level, la_language, flags);
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
void value_print_inner
|
|
(struct value *val, struct ui_file *stream, int recurse,
|
|
const struct value_print_options *options) const override
|
|
{
|
|
return d_value_print_inner (val, stream, recurse, options);
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
struct block_symbol lookup_symbol_nonlocal
|
|
(const char *name, const struct block *block,
|
|
const domain_enum domain) const override
|
|
{
|
|
return d_lookup_symbol_nonlocal (this, name, block, domain);
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
int parser (struct parser_state *ps) const override
|
|
{
|
|
return d_parse (ps);
|
|
}
|
|
|
|
/* See language.h. */
|
|
|
|
const char *name_of_this () const override
|
|
{ return "this"; }
|
|
};
|
|
|
|
/* Single instance of the D language class. */
|
|
|
|
static d_language d_language_defn;
|
|
|
|
/* Build all D language types for the specified architecture. */
|
|
|
|
static struct builtin_d_type *
|
|
build_d_types (struct gdbarch *gdbarch)
|
|
{
|
|
struct builtin_d_type *builtin_d_type = new struct builtin_d_type;
|
|
|
|
/* Basic types. */
|
|
builtin_d_type->builtin_void
|
|
= arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
|
|
builtin_d_type->builtin_bool
|
|
= arch_boolean_type (gdbarch, 8, 1, "bool");
|
|
builtin_d_type->builtin_byte
|
|
= arch_integer_type (gdbarch, 8, 0, "byte");
|
|
builtin_d_type->builtin_ubyte
|
|
= arch_integer_type (gdbarch, 8, 1, "ubyte");
|
|
builtin_d_type->builtin_short
|
|
= arch_integer_type (gdbarch, 16, 0, "short");
|
|
builtin_d_type->builtin_ushort
|
|
= arch_integer_type (gdbarch, 16, 1, "ushort");
|
|
builtin_d_type->builtin_int
|
|
= arch_integer_type (gdbarch, 32, 0, "int");
|
|
builtin_d_type->builtin_uint
|
|
= arch_integer_type (gdbarch, 32, 1, "uint");
|
|
builtin_d_type->builtin_long
|
|
= arch_integer_type (gdbarch, 64, 0, "long");
|
|
builtin_d_type->builtin_ulong
|
|
= arch_integer_type (gdbarch, 64, 1, "ulong");
|
|
builtin_d_type->builtin_cent
|
|
= arch_integer_type (gdbarch, 128, 0, "cent");
|
|
builtin_d_type->builtin_ucent
|
|
= arch_integer_type (gdbarch, 128, 1, "ucent");
|
|
builtin_d_type->builtin_float
|
|
= arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
|
|
"float", gdbarch_float_format (gdbarch));
|
|
builtin_d_type->builtin_double
|
|
= arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
|
|
"double", gdbarch_double_format (gdbarch));
|
|
builtin_d_type->builtin_real
|
|
= arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
|
|
"real", gdbarch_long_double_format (gdbarch));
|
|
|
|
builtin_d_type->builtin_byte->set_instance_flags
|
|
(builtin_d_type->builtin_byte->instance_flags ()
|
|
| TYPE_INSTANCE_FLAG_NOTTEXT);
|
|
|
|
builtin_d_type->builtin_ubyte->set_instance_flags
|
|
(builtin_d_type->builtin_ubyte->instance_flags ()
|
|
| TYPE_INSTANCE_FLAG_NOTTEXT);
|
|
|
|
/* Imaginary and complex types. */
|
|
builtin_d_type->builtin_ifloat
|
|
= arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
|
|
"ifloat", gdbarch_float_format (gdbarch));
|
|
builtin_d_type->builtin_idouble
|
|
= arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
|
|
"idouble", gdbarch_double_format (gdbarch));
|
|
builtin_d_type->builtin_ireal
|
|
= arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
|
|
"ireal", gdbarch_long_double_format (gdbarch));
|
|
builtin_d_type->builtin_cfloat
|
|
= init_complex_type ("cfloat", builtin_d_type->builtin_float);
|
|
builtin_d_type->builtin_cdouble
|
|
= init_complex_type ("cdouble", builtin_d_type->builtin_double);
|
|
builtin_d_type->builtin_creal
|
|
= init_complex_type ("creal", builtin_d_type->builtin_real);
|
|
|
|
/* Character types. */
|
|
builtin_d_type->builtin_char
|
|
= arch_character_type (gdbarch, 8, 1, "char");
|
|
builtin_d_type->builtin_wchar
|
|
= arch_character_type (gdbarch, 16, 1, "wchar");
|
|
builtin_d_type->builtin_dchar
|
|
= arch_character_type (gdbarch, 32, 1, "dchar");
|
|
|
|
return builtin_d_type;
|
|
}
|
|
|
|
static const registry<gdbarch>::key<struct builtin_d_type> d_type_data;
|
|
|
|
/* Return the D type table for the specified architecture. */
|
|
|
|
const struct builtin_d_type *
|
|
builtin_d_type (struct gdbarch *gdbarch)
|
|
{
|
|
struct builtin_d_type *result = d_type_data.get (gdbarch);
|
|
if (result == nullptr)
|
|
{
|
|
result = build_d_types (gdbarch);
|
|
d_type_data.set (gdbarch, result);
|
|
}
|
|
|
|
return result;
|
|
}
|