gdb/NEWS: * D language support. Support for debugging the D programming language has been integrated into GDB. gdb/ChangeLog: D language support. * Makefile.in (SFILES): Add d-lang.c d-valprint.c. (COMMON_OBS): Add d-lang.o d-valprint.o. (HFILES_NO_SRCDIR): Add d-lang.h. * c-lang.c (c_emit_char, exp_descriptor_c): Make public. * c-lang.h (c_emit_char, exp_descriptor_c): Add declaration. * d-lang.c: New file. * d-lang.h: New file. * d-valprint.c: New file. * defs.h (enum language): Add language_d. * dwarf2read.c (set_cu_language): Add DW_LANG_D. * language.c (binop_result_type, integral_type, character_type) (string_type, boolean_type, structured_type): Add language_d. * symfile.c (init_filename_language_table): Add language_d. * symtab.c: Include d-lang.h. (symbol_init_language_specific, symbol_find_demangled_name) (symbol_natural_name, lookup_symbol_in_language) (symbol_demangled_name, symbol_matches_domain): Add language_d. gdb/doc/ChangeLog: * gdb.texinfo: Add mention about D language support. gdb/testsuite/ChangeLog: * gdb.base/default.exp: Fix "set language" test. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index d62dc63..d19c74d 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -658,6 +658,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ charset.c cli-out.c coffread.c coff-pe-read.c \ complaints.c completer.c corefile.c \ cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \ + d-lang.c d-valprint.c \ cp-name-parser.y \ dbxread.c demangle.c dictionary.c disasm.c doublest.c dummy-frame.c \ dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \ @@ -725,7 +726,7 @@ cli-out.h gdb_expat.h breakpoint.h infcall.h obsd-tdep.h \ exec.h m32r-tdep.h osabi.h gdbcore.h solib-som.h \ i386bsd-nat.h xml-support.h xml-tdesc.h alphabsd-tdep.h gdb_obstack.h \ ia64-tdep.h ada-lang.h varobj.h frv-tdep.h nto-tdep.h serial.h \ -c-lang.h frame.h event-loop.h block.h cli/cli-setshow.h \ +c-lang.h d-lang.h frame.h event-loop.h block.h cli/cli-setshow.h \ cli/cli-decode.h cli/cli-cmds.h cli/cli-dump.h \ cli/cli-script.h macrotab.h symtab.h version.h gnulib/wchar.in.h \ gnulib/string.in.h gnulib/str-two-way.h gnulib/extra/link-warning.h \ @@ -830,7 +831,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ dbxread.o coffread.o coff-pe-read.o \ dwarf2read.o mipsread.o stabsread.o corefile.o \ dwarf2expr.o dwarf2loc.o dwarf2-frame.o \ - ada-lang.o c-lang.o f-lang.o objc-lang.o \ + ada-lang.o c-lang.o d-lang.o f-lang.o objc-lang.o \ ada-tasks.o \ ui-out.o cli-out.o \ varobj.o vec.o wrapper.o \ @@ -840,7 +841,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ sentinel-frame.o \ complaints.o typeprint.o \ ada-typeprint.o c-typeprint.o f-typeprint.o m2-typeprint.o \ - ada-valprint.o c-valprint.o cp-valprint.o f-valprint.o m2-valprint.o \ + ada-valprint.o c-valprint.o cp-valprint.o d-valprint.o f-valprint.o \ + m2-valprint.o \ serial.o mdebugread.o top.o utils.o \ ui-file.o \ user-regs.o \ diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 805c572..aa69f94 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -253,8 +253,9 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig, int orig_len, string whose delimiter is QUOTER. Note that that format for printing characters and strings is language specific. */ -static void -c_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) +void +c_emit_char (int c, struct type *type, + struct ui_file *stream, int quoter) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); struct obstack wchar_buf, output; @@ -1135,7 +1136,7 @@ c_language_arch_info (struct gdbarch *gdbarch, lai->bool_type_default = builtin->builtin_int; } -static const struct exp_descriptor exp_descriptor_c = +const struct exp_descriptor exp_descriptor_c = { print_subexp_standard, operator_length_standard, diff --git a/gdb/c-lang.h b/gdb/c-lang.h index 423cee0..c2cdd56 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -87,6 +87,11 @@ extern void c_printstr (struct ui_file * stream, struct type *elttype, extern void c_language_arch_info (struct gdbarch *gdbarch, struct language_arch_info *lai); +extern const struct exp_descriptor exp_descriptor_c; + +extern void c_emit_char (int c, struct type *type, + struct ui_file *stream, int quoter); + /* These are in c-typeprint.c: */ extern void c_type_print_base (struct type *, struct ui_file *, int, int); diff --git a/gdb/d-lang.c b/gdb/d-lang.c new file mode 100644 index 0000000..cf58335 --- /dev/null +++ b/gdb/d-lang.c @@ -0,0 +1,283 @@ +/* D language support routines for GDB, the GNU debugger. + + Copyright (C) 2005, 2006, 2008, 2009, 2010 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 . */ + +#include "defs.h" +#include "symtab.h" +#include "language.h" +#include "d-lang.h" +#include "c-lang.h" +#include "gdb_string.h" +#include "parser-defs.h" +#include "gdb_obstack.h" + +#include + + +static const char *mangled_str; +/* Temporary obstack used for holding strings. */ +static struct obstack tempbuf; + +/* Extract identifiers from MANGLED_STR and append it to TEMPBUF. + Return 1 on success or 0 on failure. */ +static int +extract_identifiers (const char *mangled_str, struct obstack *tempbuf) +{ + long i = 0; + + while (isdigit (*mangled_str)) + { + i = strtol (mangled_str, NULL, 10); + mangled_str++; + if (i <= 0 && strlen (mangled_str) < i) + return 0; + obstack_grow (tempbuf, mangled_str, i); + mangled_str += i; + obstack_grow_str (tempbuf, "."); + } + if (*mangled_str == '\0' || i == 0) + return 0; + obstack_blank (tempbuf, -1); + return 1; +} + +/* Extract and demangle type from MANGLED_STR and append it to TEMPBUF. + Return 1 on success or 0 on failure. */ +static int +extract_type_info (const char *mangled_str, struct obstack *tempbuf) +{ + if (*mangled_str == '\0') + return 0; + switch (*mangled_str++) + { + case 'A': /* dynamic array */ + case 'G': /* static array */ + case 'H': /* associative array */ + if (!extract_type_info (mangled_str, tempbuf)) + return 0; + obstack_grow_str (tempbuf, "[]"); + return 1; + case 'P': /* pointer */ + if (!extract_type_info (mangled_str, tempbuf)) + return 0; + obstack_grow_str (tempbuf, "*"); + return 1; + case 'R': /* reference */ + if (!extract_type_info (mangled_str, tempbuf)) + return 0; + obstack_grow_str (tempbuf, "&"); + return 1; + case 'Z': /* return value */ + return extract_type_info (mangled_str, tempbuf); + case 'J': /* out */ + obstack_grow_str (tempbuf, "out "); + return extract_type_info (mangled_str, tempbuf); + case 'K': /* inout */ + obstack_grow_str (tempbuf, "inout "); + return extract_type_info (mangled_str, tempbuf); + case 'E': /* enum */ + case 'T': /* typedef */ + case 'D': /* delegate */ + case 'C': /* class */ + case 'S': /* struct */ + return extract_identifiers (mangled_str, tempbuf); + + /* basic types: */ + case 'n': obstack_grow_str (tempbuf, "none"); return 1; + case 'v': obstack_grow_str (tempbuf, "void"); return 1; + case 'g': obstack_grow_str (tempbuf, "byte"); return 1; + case 'h': obstack_grow_str (tempbuf, "ubyte"); return 1; + case 's': obstack_grow_str (tempbuf, "short"); return 1; + case 't': obstack_grow_str (tempbuf, "ushort"); return 1; + case 'i': obstack_grow_str (tempbuf, "int"); return 1; + case 'k': obstack_grow_str (tempbuf, "uint"); return 1; + case 'l': obstack_grow_str (tempbuf, "long"); return 1; + case 'm': obstack_grow_str (tempbuf, "ulong"); return 1; + case 'f': obstack_grow_str (tempbuf, "float"); return 1; + case 'd': obstack_grow_str (tempbuf, "double"); return 1; + case 'e': obstack_grow_str (tempbuf, "real"); return 1; + + /* imaginary and complex: */ + case 'o': obstack_grow_str (tempbuf, "ifloat"); return 1; + case 'p': obstack_grow_str (tempbuf, "idouble"); return 1; + case 'j': obstack_grow_str (tempbuf, "ireal"); return 1; + case 'q': obstack_grow_str (tempbuf, "cfloat"); return 1; + case 'r': obstack_grow_str (tempbuf, "cdouble"); return 1; + case 'c': obstack_grow_str (tempbuf, "creal"); return 1; + + /* other types: */ + case 'b': obstack_grow_str (tempbuf, "bit"); return 1; + case 'a': obstack_grow_str (tempbuf, "char"); return 1; + case 'u': obstack_grow_str (tempbuf, "wchar"); return 1; + case 'w': obstack_grow_str (tempbuf, "dchar"); return 1; + + default: + obstack_grow_str (tempbuf, "unknown"); + return 1; + } +} + +/* Implements the la_demangle language_defn routine for language D. */ +char * +d_demangle (const char *symbol, int options) +{ + struct obstack tempbuf; + char *out_str; + unsigned char is_func = 0; + + if (symbol == NULL) + return NULL; + else if (strcmp (symbol, "_Dmain") == 0) + return xstrdup ("D main"); + + obstack_init (&tempbuf); + + if (symbol[0] == '_' && symbol[1] == 'D') + { + symbol += 2; + is_func = 1; + } + else if (strncmp (symbol, "__Class_", 8) == 0) + symbol += 8; + else if (strncmp (symbol, "__init_", 7) == 0) + symbol += 7; + else if (strncmp (symbol, "__vtbl_", 7) == 0) + symbol += 7; + else if (strncmp (symbol, "__modctor_", 10) == 0) + symbol += 10; + else if (strncmp (symbol, "__moddtor_", 10) == 0) + symbol += 10; + else if (strncmp (symbol, "__ModuleInfo_", 13) == 0) + symbol += 13; + else + { + obstack_free (&tempbuf, NULL); + return NULL; + } + + if (!extract_identifiers (symbol, &tempbuf)) + { + obstack_free (&tempbuf, NULL); + return NULL; + } + + obstack_grow_str (&tempbuf, "("); + if (is_func == 1 && *symbol == 'F') + { + symbol++; + while (*symbol != '\0' && *symbol != 'Z') + { + if (is_func == 1) + is_func++; + else + obstack_grow_str (&tempbuf, ", "); + if (!extract_type_info (symbol, &tempbuf)) + { + obstack_free (&tempbuf, NULL); + return NULL; + } + } + } + obstack_grow_str0 (&tempbuf, ")"); + + /* Doesn't display the return type, but wouldn't be too hard to do. */ + + out_str = xstrdup (obstack_finish (&tempbuf)); + obstack_free (&tempbuf, NULL); + return out_str; +} + +/* Table mapping opcodes into strings for printing operators + and precedences of the operators. */ +static const struct op_print d_op_print_tab[] = +{ + {",", BINOP_COMMA, PREC_COMMA, 0}, + {"=", BINOP_ASSIGN, PREC_ASSIGN, 1}, + {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, + {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, + {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, + {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, + {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, + {"==", BINOP_EQUAL, PREC_EQUAL, 0}, + {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, + {"<=", BINOP_LEQ, PREC_ORDER, 0}, + {">=", BINOP_GEQ, PREC_ORDER, 0}, + {">", BINOP_GTR, PREC_ORDER, 0}, + {"<", BINOP_LESS, PREC_ORDER, 0}, + {">>", BINOP_RSH, PREC_SHIFT, 0}, + {"<<", BINOP_LSH, PREC_SHIFT, 0}, + {"+", BINOP_ADD, PREC_ADD, 0}, + {"-", BINOP_SUB, PREC_ADD, 0}, + {"*", BINOP_MUL, PREC_MUL, 0}, + {"/", BINOP_DIV, PREC_MUL, 0}, + {"%", BINOP_REM, PREC_MUL, 0}, + {"@", BINOP_REPEAT, PREC_REPEAT, 0}, + {"-", UNOP_NEG, PREC_PREFIX, 0}, + {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, + {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0}, + {"*", UNOP_IND, PREC_PREFIX, 0}, + {"&", UNOP_ADDR, PREC_PREFIX, 0}, + {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, + {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, + {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, + {NULL, 0, 0, 0} +}; + +static const struct language_defn d_language_defn = +{ + "d", + language_d, + range_check_off, + type_check_off, + case_sensitive_on, + array_row_major, + macro_expansion_c, + &exp_descriptor_c, + c_parse, + c_error, + null_post_parser, + c_printchar, /* Print a character constant. */ + c_printstr, /* Function to print string constant. */ + c_emit_char, /* Print a single char. */ + c_print_type, /* Print a type using appropriate syntax. */ + c_print_typedef, /* Print a typedef using appropriate syntax. */ + d_val_print, /* Print a value using appropriate syntax. */ + c_value_print, /* Print a top-level value. */ + NULL, /* Language specific skip_trampoline. */ + "this", + basic_lookup_symbol_nonlocal, + basic_lookup_transparent_type, + d_demangle, /* Language specific symbol demangler. */ + NULL, /* Language specific class_name_from_physname. */ + d_op_print_tab, /* Expression operators for printing. */ + 1, /* C-style arrays. */ + 0, /* String lower bound. */ + default_word_break_characters, + default_make_symbol_completion_list, + c_language_arch_info, + default_print_array_index, + default_pass_by_reference, + c_get_string, + LANG_MAGIC +}; + +void +_initialize_d_language (void) +{ + add_language (&d_language_defn); +} diff --git a/gdb/d-lang.h b/gdb/d-lang.h new file mode 100644 index 0000000..be27827 --- /dev/null +++ b/gdb/d-lang.h @@ -0,0 +1,32 @@ +/* D language support definitions for GDB, the GNU debugger. + + Copyright (C) 2005, 2006, 2008, 2009, 2010 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 . */ + +#if !defined (D_LANG_H) +#define D_LANG_H 1 + +#include "symtab.h" + +extern char *d_demangle (const char *mangled, int options); + +extern int d_val_print (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int recurse, + const struct value_print_options *options); + +#endif /* !defined (D_LANG_H) */ diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c new file mode 100644 index 0000000..67b32b7 --- /dev/null +++ b/gdb/d-valprint.c @@ -0,0 +1,91 @@ +/* Support for printing D values for GDB, the GNU debugger. + + Copyright (C) 2008, 2009, 2010 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 . */ + +#include "defs.h" +#include "gdbtypes.h" +#include "gdbcore.h" +#include "d-lang.h" +#include "c-lang.h" + +/* Assuming that TYPE is a TYPE_CODE_STRUCT, verify that TYPE is + a dynamic array, and then print its value to STREAM. Return + the number of string characters printed, or -1 if TYPE is not + a dynamic array. */ +static int +dynamic_array_type (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int recurse, + const struct value_print_options *options) +{ + if (TYPE_NFIELDS (type) == 2 + && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_INT + && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0 + && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0) + { + CORE_ADDR addr; + struct type *elttype; + struct type *true_type; + struct type *ptr_type; + struct type *range_type; + const gdb_byte *ptraddr; + struct value *val; + int length; + + length = unpack_field_as_long (type, valaddr + embedded_offset, 0); + + ptr_type = TYPE_FIELD_TYPE (type, 1); + elttype = check_typedef (TYPE_TARGET_TYPE (ptr_type)); + addr = unpack_pointer (ptr_type, + valaddr + TYPE_FIELD_BITPOS (type, 1) / 8 + + embedded_offset); + true_type = check_typedef (elttype); + + true_type = lookup_array_range_type (true_type, 0, length - 1); + val = value_at (true_type, addr); + ptraddr = value_contents (val); + + return d_val_print (true_type, ptraddr, 0, addr, stream, recurse + 1, + options); + } + return -1; +} + +/* Implements the la_val_print routine for language D. */ +int +d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, + CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value_print_options *options) +{ + int ret; + + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + ret = dynamic_array_type (type, valaddr, embedded_offset, address, + stream, recurse, options); + if (ret != -1) + break; + default: + ret = c_val_print (type, valaddr, embedded_offset, address, stream, + recurse, options); + } + + return ret; +} diff --git a/gdb/defs.h b/gdb/defs.h index e8a1dd4..d4a9b19 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -188,6 +188,7 @@ enum language language_auto, /* Placeholder for automatic setting */ language_c, /* C */ language_cplus, /* C++ */ + language_d, /* D */ language_objc, /* Objective-C */ language_java, /* Java */ language_fortran, /* Fortran */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 93a98f3..0f7ea38 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -214,6 +214,10 @@ You can use @value{GDBN} to debug programs written in C and C@t{++}. For more information, see @ref{Supported Languages,,Supported Languages}. For more information, see @ref{C,,C and C++}. +@cindex D +Support for D is partial. For information on D, see +@ref{D,,D}. + @cindex Modula-2 Support for Modula-2 is partial. For information on Modula-2, see @ref{Modula-2,,Modula-2}. @@ -10824,6 +10828,9 @@ C source file @itemx .c++ C@t{++} source file +@item .d +D source file + @item .m Objective-C source file @@ -11101,7 +11108,7 @@ being set automatically by @value{GDBN}. @node Supported Languages @section Supported Languages -@value{GDBN} supports C, C@t{++}, Objective-C, Fortran, Java, Pascal, +@value{GDBN} supports C, C@t{++}, D, Objective-C, Fortran, Java, Pascal, assembly, Modula-2, and Ada. @c This is false ... Some @value{GDBN} features may be used in expressions regardless of the @@ -11120,6 +11127,7 @@ language reference or tutorial. @menu * C:: C and C@t{++} +* D:: D * Objective-C:: Objective-C * Fortran:: Fortran * Pascal:: Pascal @@ -11657,6 +11665,14 @@ In the PowerPC architecture, @value{GDBN} provides a set of pseudo-registers to inspect @code{_Decimal128} values stored in floating point registers. See @ref{PowerPC,,PowerPC} for more details. +@node D +@subsection D + +@cindex D +@value{GDBN} can be used to debug programs written in D and compiled with +GDC, LDC or DMD. Currently @value{GDBN} supports only one D specific +feature - dynamic arrays. + @node Objective-C @subsection Objective-C diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 3096ab7..f4cbc59 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -7619,6 +7619,9 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu) case DW_LANG_C_plus_plus: cu->language = language_cplus; break; + case DW_LANG_D: + cu->language = language_d; + break; case DW_LANG_Fortran77: case DW_LANG_Fortran90: case DW_LANG_Fortran95: diff --git a/gdb/language.c b/gdb/language.c index dcd70b0..aba8a9e 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -486,6 +486,7 @@ binop_result_type (struct value *v1, struct value *v2) { case language_c: case language_cplus: + case language_d: case language_objc: if (TYPE_CODE (t1) == TYPE_CODE_FLT) return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ? @@ -597,6 +598,7 @@ integral_type (struct type *type) { case language_c: case language_cplus: + case language_d: case language_objc: return (TYPE_CODE (type) != TYPE_CODE_INT) && (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1; @@ -637,6 +639,7 @@ character_type (struct type *type) case language_c: case language_cplus: + case language_d: case language_objc: return (TYPE_CODE (type) == TYPE_CODE_INT) && TYPE_LENGTH (type) == sizeof (char) @@ -659,6 +662,7 @@ string_type (struct type *type) case language_c: case language_cplus: + case language_d: case language_objc: /* C does not have distinct string type. */ return (0); @@ -678,6 +682,7 @@ boolean_type (struct type *type) { case language_c: case language_cplus: + case language_d: case language_objc: /* Might be more cleanly handled by having a TYPE_CODE_INT_NOT_BOOL for (the deleted) CHILL and such @@ -717,6 +722,7 @@ structured_type (struct type *type) { case language_c: case language_cplus: + case language_d: case language_objc: return (TYPE_CODE (type) == TYPE_CODE_STRUCT) || (TYPE_CODE (type) == TYPE_CODE_UNION) || diff --git a/gdb/symfile.c b/gdb/symfile.c index eda26cc..cf7b41a 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2618,6 +2618,7 @@ init_filename_language_table (void) filename_language_table = xmalloc (fl_table_size * sizeof (*filename_language_table)); add_filename_language (".c", language_c); + add_filename_language (".d", language_d); add_filename_language (".C", language_cplus); add_filename_language (".cc", language_cplus); add_filename_language (".cp", language_cplus); diff --git a/gdb/symtab.c b/gdb/symtab.c index 1d6b648..67a784b 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -39,6 +39,7 @@ #include "source.h" #include "filenames.h" /* for FILENAME_CMP */ #include "objc-lang.h" +#include "d-lang.h" #include "ada-lang.h" #include "p-lang.h" #include "addrmap.h" @@ -346,6 +347,7 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol, { gsymbol->language = language; if (gsymbol->language == language_cplus + || gsymbol->language == language_d || gsymbol->language == language_java || gsymbol->language == language_objc) { @@ -449,6 +451,16 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, return demangled; } } + if (gsymbol->language == language_d + || gsymbol->language == language_auto) + { + demangled = d_demangle(mangled, 0); + if (demangled != NULL) + { + gsymbol->language = language_d; + return demangled; + } + } return NULL; } @@ -626,6 +638,7 @@ symbol_natural_name (const struct general_symbol_info *gsymbol) switch (gsymbol->language) { case language_cplus: + case language_d: case language_java: case language_objc: if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) @@ -651,6 +664,7 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol) switch (gsymbol->language) { case language_cplus: + case language_d: case language_java: case language_objc: if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) @@ -940,7 +954,7 @@ lookup_symbol_in_language (const char *name, const struct block *block, modified_name = name; - /* If we are using C++ or Java, demangle the name before doing a lookup, so + /* If we are using C++, D, or Java, demangle the name before doing a lookup, so we can always binary search. */ if (lang == language_cplus) { @@ -972,6 +986,15 @@ lookup_symbol_in_language (const char *name, const struct block *block, make_cleanup (xfree, demangled_name); } } + else if (lang == language_d) + { + demangled_name = d_demangle (name, 0); + if (demangled_name) + { + modified_name = demangled_name; + make_cleanup (xfree, demangled_name); + } + } if (case_sensitivity == case_sensitive_off) { @@ -1412,6 +1435,7 @@ symbol_matches_domain (enum language symbol_language, A Java class declaration also defines a typedef for the class. Similarly, any Ada type declaration implicitly defines a typedef. */ if (symbol_language == language_cplus + || symbol_language == language_d || symbol_language == language_java || symbol_language == language_ada) { diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 97d5407..2a13007 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -531,7 +531,7 @@ gdb_test "set history size" "Argument required .integer to set it to.*" "set his #test set history gdb_test "set history" "\"set history\" must be followed by the name of a history subcommand.(\[^\r\n\]*\[\r\n\])+List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set history" #test set language -gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, c, c.., asm, minimal, fortran, objective-c, java, modula-2, pascal, scheme." "set language" +gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, c, c.., asm, minimal, d, fortran, objective-c, java, modula-2, pascal, scheme." "set language" #test set listsize gdb_test "set listsize" "Argument required .integer to set it to.*" "set listsize" #test set print "p" abbreviation