D Symbol Demangling

Thomas Kuehne
2006-04-19T11:18:18Z

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

Attached is a patch against GDB-6.4 that enables demangling of symbols
generated by DMD[1] and GDC[2].

The infrastructure part (c-lang.c, defs.h, d-lang.h, dwarf2read.c,
language.c, Makefile.in, symfile, syntab.c, dwarf2.h) is based on John
Demme's work[3][4].

The pluggable demangler (gdb/demangle_d/*) was written completely form
scratch and isn't based on John's work and supports templates and - to a
certain extend - nested functions and types.

Thomas

[1] http://digitalmars.com/d/dcompiler.html
[2] http://home.earthlink.net/~dvdfrdmn/d/
[3] http://www.dsource.org/forums/viewforum.php?f=58
[4] http://sourceware.org/ml/gdb-patches/2005-04/msg00039.html

[-- Attachment #2: gdb-6.4-demangle_d.diff --]
[-- Type: text/plain, Size: 40717 bytes --]

diff -urN gdb-6.4/gdb/c-lang.c gdb-6.4-demangle_d/gdb/c-lang.c
--- gdb-6.4/gdb/c-lang.c 2005-10-03 23:21:20.000000000 +0200
+++ gdb-6.4-demangle_d/gdb/c-lang.c 2006-04-17 21:29:25.000000000 +0200
@@ -27,6 +27,7 @@
#include "parser-defs.h"
#include "language.h"
#include "c-lang.h"
+#include "d-lang.h"
#include "valprint.h"
#include "macroscope.h"
#include "gdb_assert.h"
@@ -735,10 +736,48 @@
LANG_MAGIC
};

+const struct language_defn d_language_defn =
+{
+ "d", /* Language name */
+ language_d,
+ NULL,
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ array_row_major,
+ &exp_descriptor_standard,
+ c_preprocess_and_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_create_fundamental_type, /* Create fundamental type in this language */
+ c_print_type, /* Print a type using appropriate syntax */
+ c_val_print, /* Print a value using appropriate syntax */
+ c_value_print, /* Print a top-level value */
+ NULL, /* Language specific skip_trampoline */
+ NULL, /* value_of_this */
+ basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
+ basic_lookup_transparent_type,/* lookup_transparent_type */
+ d_demangle, /* Language specific symbol demangler */
+ NULL, /* Language specific class_name_from_physname */
+ c_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ NULL,
+ default_word_break_characters,
+ c_language_arch_info,
+ default_print_array_index,
+ LANG_MAGIC
+};
+
+
void
_initialize_c_language (void)
{
add_language (&c_language_defn);
+ add_language (&d_language_defn);
add_language (&cplus_language_defn);
add_language (&asm_language_defn);
add_language (&minimal_language_defn);
diff -urN gdb-6.4/gdb/defs.h gdb-6.4-demangle_d/gdb/defs.h
--- gdb-6.4/gdb/defs.h 2005-08-05 23:08:54.000000000 +0200
+++ gdb-6.4-demangle_d/gdb/defs.h 2006-04-17 21:27:21.000000000 +0200
@@ -190,6 +190,7 @@
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 -urN gdb-6.4/gdb/demangle_d/demangle_d.c gdb-6.4-demangle_d/gdb/demangle_d/demangle_d.c
--- gdb-6.4/gdb/demangle_d/demangle_d.c 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/demangle_d/demangle_d.c 2006-04-19 14:08:46.000000000 +0200
@@ -0,0 +1,844 @@
+/*
+ * demangle_d.c - pluggable D de-mangler
+ *
+ * Copyright 2006 Thomas Kuehne <thomas@kuehne.cn>
+ *
+ *
+ * Eiffel Forum License, version 1
+ *
+ * Permission is hereby granted to use, copy, modify and/or distribute this
+ * package, provided that:
+ *
+ * - copyright notices are retained unchanged
+ *
+ * - any distribution of this package, whether modified or not, includes
+ * this file
+ *
+ * Permission is hereby also granted to distribute binary programs which
+ * depend on this package, provided that:
+ *
+ * - if the binary program depends on a modified version of this package,
+ * you must publicly release the modified version of this package
+ *
+ * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS PACKAGE.
+ *
+ * 2006-04-19
+ * added GDB support
+ *
+ * 2006-04-17
+ * added Valgrind support
+ *
+ * 2006-04-16
+ * inital public release
+ *
+ */
+
+#include "demangle_d_conf.h"
+#include "demangle_d_internal.h"
+
+/* copy len first bytes into a newly allocated buffer */
+char*
+DD_(strndup)(const char* source, size_t len)
+{
+ char* dest;
+ dest = xmalloc(len+1);
+ xmemcpy(dest, source, len);
+ dest[len] = '\x00';
+ return dest;
+}
+
+#if (DEMANGLE_D_REQUIRE_strtol_10)
+/* convert a string to a long integer using base 10 */
+long int
+xstrtol_10(char* src, char** endptr)
+{
+ long int value;
+ int sign;
+
+ if(src[0] == '-'){
+ sign = -1;
+ src++;
+ }else if(src[0] == '+'){
+ sign = 1;
+ src++;
+ }else{
+ sign = 1;
+ }
+
+ value = 0;
+
+ while(xisdigit(src[0])){
+ value = (value * 10) + (src[0] - '0');
+ src++;
+ }
+
+ if(endptr){
+ *endptr = src;
+ }
+
+ return sign * value;
+}
+#endif
+
+#if (DEMANGLE_D_REQUIRE_malloc)
+void*
+DD_(malloc)(size_t len)
+{
+ void* ptr;
+ ptr = malloc(len);
+ if(!ptr){
+ perror("DD_(malloc)");
+ xabort();
+ }
+ return ptr;
+}
+#endif
+
+#if (DEMANGLE_D_REQUIRE_realloc)
+void*
+DD_(realloc)(void* ptr, size_t len)
+{
+ ptr = realloc(ptr, len);
+ if(!ptr){
+ perror("DD_(realloc)");
+ xabort();
+ }
+ return ptr;
+}
+#endif
+
+DD_(string_t)*
+DD_(new_string)(void)
+{
+ DD_(string_t)* str = xmalloc(sizeof(DD_(string_t)));
+ str->used = 0;
+ str->len = 128;
+ str->str = xmalloc(str->len);
+ str->str[0] = '\x00';
+ return str;
+}
+
+void
+DD_(append_n)(DD_(string_t)* dest, const char* source, size_t len)
+{
+ size_t new_len = dest->used + len + 1;
+ if(new_len > dest->len){
+ dest->len = (size_t)(new_len * 1.5);
+ dest->str = xrealloc(dest->str, dest->len);
+ }
+ xmemcpy(dest->str + dest->used, source, len);
+ dest->used += len;
+ dest->str[dest->used] = '\x00';
+}
+
+void
+DD_(append_c)(DD_(string_t)* dest, char source)
+{
+ size_t new_len = dest->used + 2;
+ if(new_len > dest->len){
+ dest->len = (size_t)(new_len * 1.5);
+ dest->str = xrealloc(dest->str, dest->len);
+ }
+ dest->str[dest->used++] = source;
+ dest->str[dest->used] = '\x00';
+}
+
+void
+DD_(append)(DD_(string_t)* dest, const char* source)
+{
+ DD_(append_n)(dest, source, xstrlen(source));
+}
+
+void
+DD_(prepend_n)(DD_(string_t)* dest, const char* source, size_t len)
+{
+ size_t new_len = dest->used + len + 1;
+ if(new_len > dest->len){
+ dest->len = (size_t)(new_len * 1.5);
+ dest->str = xrealloc(dest->str, dest->len);
+ }
+ if(dest->used){
+ xmemmove(dest->str + len, dest->str, dest->used);
+ }
+ xmemcpy(dest->str, source, len);
+ dest->used += len;
+ dest->str[dest->used] = '\x00';
+}
+
+void
+DD_(prepend)(DD_(string_t)* dest, const char* source)
+{
+ DD_(prepend_n)(dest, source, xstrlen(source));
+}
+
+void
+DD_(nestpend_n)(DD_(string_t)* dest, const char* source, size_t len,
+ int is_nested)
+{
+ if(is_nested){
+ DD_(append_n)(dest, source, len);
+ }else{
+ DD_(prepend)(dest, " ");
+ DD_(prepend_n)(dest, source, len);
+ }
+}
+
+void
+DD_(nestpend)(DD_(string_t)* dest, const char* source, int is_nested)
+{
+ DD_(nestpend_n)(dest, source, xstrlen(source), is_nested);
+}
+
+/* parse until the end of the next type */
+char*
+DD_(nextType)(DD_(string_t)* dest, char* source, int is_nested)
+{
+ if(!source || !source[0]){
+ return NULL;
+ }
+
+ if((source[0] == '_') && (source[1] == 'D')
+ && xisdigit(source[2])
+ && (source[2] != '0'))
+ {
+ DD_(string_t)* tmp;
+ tmp = DD_(new_string)();
+ source = DD_(nextType)(tmp, source + 2, 0);
+ if(dest->used && (dest->str[dest->used] != '.')){
+ DD_(append_c)(dest, '.');
+ }
+ DD_(append_n)(dest, tmp->str, tmp->used);
+ xfree(tmp->str);
+ xfree(tmp);
+ return source;
+ }
+
+ switch(source[0]){
+ case 'v':
+ DD_(nestpend)(dest, "void", is_nested);
+ source += 1;
+ break;
+ case 'b': /* deprecated since DMD-0.148 (2006-02-25) */
+ DD_(nestpend)(dest, "bit", is_nested);
+ source += 1;
+ break;
+ case 'x':
+ DD_(nestpend)(dest, "bool", is_nested);
+ source += 1;
+ break;
+ case 'g':
+ DD_(nestpend)(dest, "byte", is_nested);
+ source += 1;
+ break;
+ case 'h':
+ DD_(nestpend)(dest, "ubyte", is_nested);
+ source += 1;
+ break;
+ case 's':
+ DD_(nestpend)(dest, "short", is_nested);
+ source += 1;
+ break;
+ case 't':
+ DD_(nestpend)(dest, "ushort", is_nested);
+ source += 1;
+ break;
+ case 'i':
+ DD_(nestpend)(dest, "int", is_nested);
+ source += 1;
+ break;
+ case 'k':
+ DD_(nestpend)(dest, "uint", is_nested);
+ source += 1;
+ break;
+ case 'l':
+ DD_(nestpend)(dest, "long", is_nested);
+ source += 1;
+ break;
+ case 'm':
+ DD_(nestpend)(dest, "ulong", is_nested);
+ source += 1;
+ break;
+ case 'f':
+ DD_(nestpend)(dest, "float", is_nested);
+ source += 1;
+ break;
+ case 'd':
+ DD_(nestpend)(dest, "double", is_nested);
+ source += 1;
+ break;
+ case 'e':
+ DD_(nestpend)(dest, "real", is_nested);
+ source += 1;
+ break;
+ case 'o':
+ DD_(nestpend)(dest, "ifloat", is_nested);
+ source += 1;
+ break;
+ case 'p':
+ DD_(nestpend)(dest, "idouble", is_nested);
+ source += 1;
+ break;
+ case 'j':
+ DD_(nestpend)(dest, "ireal", is_nested);
+ source += 1;
+ break;
+ case 'q':
+ DD_(nestpend)(dest, "cfloat", is_nested);
+ source += 1;
+ break;
+ case 'r':
+ DD_(nestpend)(dest, "cdouble", is_nested);
+ source += 1;
+ break;
+ case 'c':
+ DD_(nestpend)(dest, "creal", is_nested);
+ source += 1;
+ break;
+ case 'a':
+ DD_(nestpend)(dest, "char", is_nested);
+ source += 1;
+ break;
+ case 'u':
+ DD_(nestpend)(dest, "wchar", is_nested);
+ source += 1;
+ break;
+ case 'w':
+ DD_(nestpend)(dest, "dchar", is_nested);
+ source += 1;
+ break;
+
+ case 'A': /* dynamic array */
+ if(!is_nested){
+ DD_(prepend)(dest, "[] ");
+ }
+ source = DD_(nextType)(dest, source+1, is_nested);
+ if(is_nested){
+ DD_(append)(dest, "[]");
+ }
+ break;
+
+ case 'G': { /* static array */
+ char* start = ++source;
+ char* end = start;
+ while(xisdigit(*end)){
+ end++;
+ }
+ if(!is_nested){
+ DD_(prepend)(dest, "] ");
+ DD_(prepend_n)(dest, start, end-start);
+ DD_(prepend)(dest, "[");
+ }
+ source = DD_(nextType)(dest, end, is_nested);
+ if(is_nested){
+ DD_(append)(dest, "[");
+ DD_(append_n)(dest, start, end-start);
+ DD_(append)(dest, "]");
+ }
+ break;
+ }
+
+ case 'H': { /* associative array */
+ DD_(string_t)* aa;
+ aa = DD_(new_string)();
+ source = DD_(nextType)(aa, source+1, 1);
+ DD_(prepend)(aa, "[");
+ DD_(append)(aa, "]");
+ source = DD_(nextType)(aa, source, 0);
+
+ DD_(nestpend)(dest, aa->str, is_nested);
+ xfree(aa->str);
+ xfree(aa);
+ break;
+ }
+
+ case 'D': { /* delegate */
+ DD_(string_t)* sig;
+ sig = DD_(new_string)();
+ source = DD_(parseFunction)(sig, source+1, NULL, 0);
+ DD_(nestpend_n)(dest, sig->str, sig->used, is_nested);
+ xfree(sig->str);
+ xfree(sig);
+ break;
+ }
+
+ case 'P': /* pointer */
+ if((source[1] == 'F') || (source[1]=='U')
+ || (source[1]=='W') || (source[1]=='V')
+ || (source[1]=='R'))
+ {
+ /* function */
+ DD_(string_t)* sig;
+ sig = DD_(new_string)();
+ source = DD_(parseFunction)(sig, source+1,
+ "", 0);
+ DD_(nestpend_n)(dest, sig->str, sig->used,
+ is_nested);
+ xfree(sig->str);
+ xfree(sig);
+ }else{
+ /* 'normal' type */
+ if(!is_nested){
+ DD_(prepend)(dest, "* ");
+ }
+ source = DD_(nextType)(dest, source+1,
+ is_nested);
+ if(is_nested){
+ DD_(append)(dest, " *");
+ }
+ }
+ break;
+
+ case 'J': /* out */
+ DD_(append)(dest, "out ");
+ source = DD_(nextType)(dest, source+1, 1);
+ break;
+
+ case 'K': /* inout */
+ DD_(append)(dest, "inout ");
+ source = DD_(nextType)(dest, source+1, 1);
+ break;
+
+ case 'C': /* class */
+ case 'S': /* struct */
+ case 'E': /* enum */
+ case 'T': /* typedef */
+ {
+#if (DEMANGLE_D_VERBOSE)
+ char tmp = source[0];
+#endif /* DEMANGLE_D_VERBOSE */
+ if(!is_nested){
+ DD_(string_t)* sig;
+ sig = DD_(new_string)();
+ source = DD_(nextType)(sig, source+1, 0);
+ DD_(append)(sig, " ");
+#if (DEMANGLE_D_VERBOSE)
+ switch(tmp){
+ case 'C':
+ DD_(prepend)(sig, "class ");
+ break;
+ case 'S':
+ DD_(prepend)(sig, "struct ");
+ break;
+ case 'E':
+ DD_(prepend)(sig, "enum ");
+ break;
+ case 'T':
+ DD_(prepend)(sig, "typedef ");
+ break;
+ }
+#endif /* DEMANGLE_D_VERBOSE */
+ DD_(prepend_n)(dest, sig->str, sig->used);
+ xfree(sig->str);
+ xfree(sig);
+ }else{
+#if (DEMANGLE_D_VERBOSE)
+ switch(tmp){
+ case 'C':
+ DD_(append)(dest, "class ");
+ break;
+ case 'S':
+ DD_(append)(dest, "struct ");
+ break;
+ case 'E':
+ DD_(append)(dest, "enum ");
+ break;
+ case 'T':
+ DD_(append)(dest, "typedef ");
+ break;
+ }
+#endif /* DEMANGLE_D_VERBOSE */
+ source = DD_(nextType)(dest, source+1, 1);
+ }
+ break;
+ }
+
+ case '1': /* qualified name */
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ long int len;
+ len = xstrtol_10(source, &source);
+ if(len >= 5 && (source[0] == '_') && (source[1] == '_')
+ && (source[2] == 'T')
+ && xisdigit(source[3])
+ && (source[3] != '0'))
+ {
+ /* template */
+ char* template = DD_(strndup)(source + 3, len-3);
+ DD_(interpreteTemplate)(dest, template);
+ xfree(template);
+ }else{
+ DD_(append_n)(dest, source, len);
+ }
+ source += len;
+ while(source && xisdigit(source[0])
+ && (source[0] != '0'))
+ {
+ len = xstrtol_10(source, &source);
+ DD_(append_c)(dest, '.');
+ if(len >= 5 && (source[0] == '_')
+ && (source[1] == '_')
+ && (source[2] == 'T')
+ && xisdigit(source[3])
+ && (source[3] != '0'))
+ {
+ /* template */
+ char* template = DD_(strndup)(source + 3, len-3);
+ DD_(interpreteTemplate)(dest, template);
+ xfree(template);
+ }else if((len == 5) && (xstrncmp(source, "_ctor", len) == 0)){
+ DD_(append)(dest, "this");
+ }else if((len == 5) && (xstrncmp(source, "_dtor", len) == 0)){
+ DD_(append)(dest, "~this");
+ }else if((len == 11) && (xstrncmp(source, "_staticCtorFZv", len + 3) == 0)){
+ DD_(prepend)(dest, "static void ");
+ DD_(append)(dest, "this()");
+ source = source + 11 + 3;
+ break;
+ }else if((len == 11) && (xstrncmp(source, "_staticDtorFZv", len + 3) == 0)){
+ DD_(prepend)(dest, "static void ");
+ DD_(append)(dest, "~this()");
+ source = source + 11 + 3;
+ break;
+ }else{
+ DD_(append_n)(dest, source, len);
+ }
+ source += len;
+ }
+ if(!is_nested){
+ source = DD_(nextType)(dest, source, 0);
+ }
+ break;
+ }
+
+ case 'F': /* D function */
+ case 'U': /* C function */
+ case 'W': /* Windows function */
+ case 'V': /* Pascal function */
+ case 'R': /* C++ function */
+ if(!is_nested){
+ DD_(string_t)* id;
+ id = DD_(new_string)();
+ DD_(append_n)(id, dest->str, dest->used);
+ dest->used = 0;
+ dest->str[0] = '\x00';
+ source = DD_(parseFunction)(dest, source, id->str, 0);
+ xfree(id->str);
+ xfree(id);
+ }else{
+ source = DD_(parseFunction)(dest, source, "", 1);
+ }
+ break;
+
+ default:
+ DD_(append)(dest, " @bug@[2]{");
+ DD_(append)(dest, source);
+ DD_(append)(dest, "}");
+ source = NULL;
+ break;
+ }
+
+ return source;
+}
+
+/* parse a "real" template parameter */
+char*
+DD_(parseReal)(DD_(string_t)* dest, char* source)
+{
+ /* @BUG@ architecture dependent */
+ long double f;
+ size_t i;
+ int tmp;
+ unsigned char* c = (unsigned char*) &f;
+ char* buffer;
+
+ for(i = 0; i < 10; i++){
+ if(!xisxdigit(source[i * 2]) || !xisxdigit(source[i * 2 + 1])){
+format_error:
+ DD_(append)(dest, "0x");
+ DD_(append_n)(dest, source, 20);
+ return source + 20;
+ }
+ c[i] = (xasci2hex(source[i * 2]) << 4);
+ c[i] |= xasci2hex(source[i * 2 + 1]);
+ }
+
+ buffer = xmalloc(64);
+ tmp = xsnprintf(buffer, 64, "%Lf", f);
+ if(tmp < 1){
+ xfree(buffer);
+ goto format_error;
+ }
+ DD_(append_n)(dest, buffer, tmp);
+ xfree(buffer);
+ return source + 20;
+}
+
+/* parse a function (including arguments and return type) */
+char*
+DD_(parseFunction)(DD_(string_t)* dest, char* source, char* name,
+ int is_nested)
+{
+ DD_(string_t)* fn_return;
+ DD_(string_t)* fn_param;
+
+ fn_return = DD_(new_string)();
+ fn_param = DD_(new_string)();
+
+ source++;
+
+ /* params */
+ if(source[0] != 'Z'){
+ if(source[0] == 'Y'){
+ DD_(append)(fn_param, "...");
+ goto var_arg_param;
+ }
+ source = DD_(nextType)(fn_param, source, 1);
+ while(source && source[0] && source[0]!='Z'){
+ if(source[0] == 'Y'){
+ DD_(append)(fn_param, ", ...");
+ goto var_arg_param;
+ }else if(source[0] == 'X'){
+ DD_(append)(fn_param, " ...");
+ goto var_arg_param;
+ }
+ DD_(append)(fn_param, ", ");
+ source = DD_(nextType)(fn_param, source, 1);
+ }
+ }
+
+ /* return type */
+ if(source && source[0] == 'Z'){
+var_arg_param:
+ source = DD_(nextType)(fn_return, source + 1, 1);
+ }
+
+ /* output */
+ if(name && name[0]){
+ if(! is_nested){
+ DD_(prepend)(dest, " ");
+ DD_(prepend_n)(dest, fn_return->str, fn_return->used);
+ DD_(append)(dest, name);
+ }else{
+ DD_(append_n)(dest, fn_return->str, fn_return->used);
+ DD_(append)(dest, " ");
+ DD_(append)(dest, name);
+ }
+ }else if(name){
+ DD_(append_n)(dest, fn_return->str, fn_return->used);
+ DD_(append)(dest, " function");
+ }else{
+ DD_(append_n)(dest, fn_return->str, fn_return->used);
+ DD_(append)(dest, " delegate");
+ }
+
+ if(fn_param->used){
+ DD_(append)(dest, "(");
+ DD_(append_n)(dest, fn_param->str, fn_param->used);
+ DD_(append)(dest, ")");
+ }else{
+ DD_(append)(dest, "()");
+ }
+
+ xfree(fn_return->str);
+ xfree(fn_return);
+ xfree(fn_param->str);
+ xfree(fn_param);
+
+ return source;
+}
+
+/* interprete a NULL terminated template symbol */
+void
+DD_(interpreteTemplate)(DD_(string_t)* dest, char* raw)
+{
+ char* tmp;
+ int first_arg = 1;
+ long int dataLen;
+
+ /* id */
+ while(xisdigit(raw[0]) && (raw[0] != '0')){
+ long int len;
+ len = xstrtol_10(raw, &raw);
+ DD_(append_n)(dest, raw, len);
+ raw += len;
+ }
+ DD_(append)(dest, "!(");
+
+ /* arguments */
+ while(raw && raw[0]){
+ if(raw[0] == 'T'){
+ /* type parameter */
+ raw++;
+ if(!first_arg){
+ DD_(append)(dest, ", ");
+ }else{
+ first_arg = 0;
+ }
+ raw = DD_(nextType)(dest, raw, 1);
+ }else if(raw[0] == 'V'){
+ /* value parameter */
+ if(!first_arg){
+ DD_(append)(dest, ", ");
+ }else{
+ first_arg = 0;
+ }
+ raw = DD_(nextType)(dest, raw + 1, 1);
+ DD_(append)(dest, " ");
+ if(xisdigit(raw[0])){
+ /* integer */
+integer_arg:
+ tmp = raw;
+ while(xisdigit(raw[0])){
+ raw++;
+ }
+ DD_(append_n)(dest, tmp, raw-tmp);
+ }else if(raw[0] == 'N'){
+ /* negative integer */
+ raw++;
+ DD_(append)(dest, "-");
+ goto integer_arg;
+ }else if(raw[0] == 'e'){
+ /* float */
+ raw = DD_(parseReal)(dest, raw+1);
+ }else if(raw[0] == 'c'){
+ /* complex float */
+ raw = DD_(parseReal)(dest, raw+1);
+ DD_(append)(dest, " + ");
+ raw = DD_(parseReal)(dest, raw);
+ DD_(append)(dest, "i");
+ }else if(raw[0] == 'n'){
+ DD_(append)(dest, "null");
+ raw++;
+ }else if((raw[0] == 'a') || (raw[0] == 'w') || (raw[0] == 'd')){
+ /* character literal */
+ raw++;
+ if(!xisdigit(raw[0])){
+ goto bug;
+ }
+ dataLen = xstrtol_10(raw, &raw);
+ if(raw[0] != '_'){
+ goto bug;
+ }
+ raw++;
+ DD_(append)(dest, "\"");
+ while(dataLen--){
+ if(xisxdigit(raw[0]) && xisxdigit(raw[1])){
+ DD_(append_c)(dest, (xasci2hex(raw[0]) << 4)
+ + xasci2hex(raw[1]));
+ }else{
+ DD_(append_c)(dest, '?');
+ }
+ raw += 2;
+ }
+ DD_(append)(dest, "\"");
+ }else{
+ goto bug;
+ }
+ }else if(raw[0] == 'Z'){
+ /* end of parameter list */
+ break;
+ }else{
+bug:
+ DD_(append)(dest, " @bug@[1]{");
+ DD_(append)(dest, raw);
+ DD_(append)(dest, "}");
+ break;
+ }
+ }
+ DD_(append)(dest, ")");
+}
+
+/* demangle a D symbol
+ *
+ * input:
+ * a NULL terminated mangled symbol
+ *
+ * output:
+ * UTF-8 encoded demangled symbol
+ * or NULL if unable to demangle
+ *
+ * memory:
+ * the caller is responsible to
+ * free input and output
+ */
+static char*
+DD_(demangle_d)(char* source)
+{
+ DD_(string_t)* dest;
+ DD_(string_t)* nested;
+ char* back;
+
+ if((source[0] != '_') || (source[1] != 'D') || (!xisdigit(source[2]))
+ || (source[2] == '0'))
+ {
+ /* %% @BUG@ might be mangled with 'D' but hasn't 'D' linkage
+ * samples:
+ * _aaApply10treewalkerFPS3aaA3aaAZi
+ * _aaKeys9_aaKeys_xFPS3aaA3aaAZv
+ */
+ return NULL;
+ }else{
+ source += 2;
+ }
+
+ dest = DD_(new_string)();
+
+ source = DD_(nextType)(dest, source, 0);
+
+ while(source && source[0]){
+ /* nested symbols */
+ nested = DD_(new_string)();
+ DD_(append)(dest, ".");
+ source = DD_(nextType)(nested, source, 0);
+ DD_(append_n)(dest, nested->str, nested->used);
+ xfree(nested->str);
+ xfree(nested);
+ }
+
+ back = DD_(strndup)(dest->str, dest->used+1);
+ xfree(dest->str);
+ xfree(dest);
+
+ return back;
+}
+
+#if (DEMANGLE_D_STANDALONE)
+int
+main(int argc, char** argv)
+{
+ int i;
+ if(argc < 2){
+ xfprintf(stderr,
+ "pluggable D d-demangler by Thomas Kuehne <thomas@kuehne.cn> "
+ "($Date: 2006-04-19T11:09:00.287803Z $)\n");
+ if(argc > 0){
+ xfprintf(stderr, "%s <mangledSymbol_1> [<mangledSymbol_2> ...]\n", argv[0]);
+ }else{
+ xfprintf(stderr, "dmangle_d <mangledSymbol_1> [<mangledSymbol_2> ...]\n");
+ }
+ return (EXIT_FAILURE);
+ }
+ for(i = 1; i < argc; i++){
+ char* demangled = DD_(demangle_d)(argv[i]);
+ if(4 > xprintf("%s\t%s\n", argv[i], demangled)){
+ xperror("main");
+ }
+ if(demangled){
+ xfree(demangled);
+ }
+ }
+ return (EXIT_SUCCESS);
+}
+#endif
diff -urN gdb-6.4/gdb/demangle_d/demangle_d_conf.h gdb-6.4-demangle_d/gdb/demangle_d/demangle_d_conf.h
--- gdb-6.4/gdb/demangle_d/demangle_d_conf.h 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/demangle_d/demangle_d_conf.h 2006-04-19 13:47:54.000000000 +0200
@@ -0,0 +1,115 @@
+#if !(DEMANGLE_D_CONF_H)
+#define DEMANGLE_D_CONF_H 1
+
+#include "demangle_d.h"
+
+#if (DEMANGLE_D_IN_VALGRIND)
+
+/* valgrind - http://www.valgrind.org */
+
+#include <stddef.h> /* size_t */
+
+#define xmemcpy VG_(memcpy)
+#define xmemmove MEMMOVE
+#define xstrlen VG_(strlen)
+#define xstrncmp VG_(strncmp)
+#define xmalloc VG_(malloc)
+#define DEMANGLE_D_REQUIRE_malloc 0
+#define xrealloc VG_(realloc)
+#define DEMANGLE_D_REQUIRE_realloc 0
+#define xfree VG_(free)
+#define xsnprintf VG_(snprintf)
+#define xisdigit ISDIGIT
+#define xisxdigit ISXDIGIT
+#define xasci2hex ASCI2HEX
+
+#define DEMANGLE_D_REQUIRE_strtol_10 1
+#define xstrtol_10 DD_(strtol_10)
+
+#else
+
+/* "normal" libc */
+#define DEMANGLE_D_IN_VALGRIND 0
+
+#include <string.h>
+#define xmemcpy memcpy
+#define xmemmove memmove
+#define xstrlen strlen
+#define xstrncmp strncmp
+
+#include <stdlib.h>
+#define xmalloc DD_(malloc)
+#define DEMANGLE_D_REQUIRE_malloc 1
+#define xrealloc DD_(realloc)
+#define DEMANGLE_D_REQUIRE_realloc 1
+#define xfree free
+#define xabort abort
+#define xstrtol_10(n,p) strtol((n), (p), 10)
+#define DEMANGLE_D_REQUIRE_strtol_10 0
+
+#include <stdio.h>
+#define xsnprintf snprintf
+
+#include <ctype.h>
+#define xisdigit isdigit
+#define xisxdigit isxdigit
+
+#define xasci2hex ASCI2HEX
+
+#if (DEMANGLE_D_STANDALONE)
+#define xprintf printf
+#define xperror perror
+#define xfprintf fprintf
+#else
+#define DEMANGLE_D_STANDALONE 0
+#endif
+
+#endif
+
+/* helper macros */
+
+#define MEMMOVE(dest, src, len) \
+{ \
+ if(((dest < src) && (dest + len < src)) \
+ || (((src < dest) && (src + len < dest)))) \
+ { \
+ xmemcpy(dest, src, len); \
+ }else{ \
+ void* tmp; \
+ tmp = xmalloc(len); \
+ xmemcpy(tmp, src, len); \
+ xmemcpy(dest, tmp, len); \
+ xfree(tmp); \
+ } \
+}
+
+#define ISDIGIT(c) (('0' <= (c)) && ((c) <= '9'))
+
+#define ISXDIGIT(c) ( \
+ (('0' <= (c)) && ((c) <= '9')) \
+ || (('a' <= (c)) && ((c) <= 'f')) \
+ || (('A' <= (c)) && ((c) <= 'F')) \
+ )
+
+#define ASCI2HEX(c) \
+ ( \
+ ('a' <= (c) && (c) <= 'f') \
+ ? \
+ ((c) - 'a' + 10) \
+ : \
+ ( \
+ ('A' <= (c) && (c) <= 'F') \
+ ? \
+ ((c) - 'A' + 10) \
+ : \
+ ( \
+ ('0' <= (c) && (c) <= '9') \
+ ? \
+ ((c) - '0') \
+ : \
+ 0 \
+ ) \
+ ) \
+ )
+
+#endif /* DEMANGLE_D_CONF_H */
diff -urN gdb-6.4/gdb/demangle_d/demangle_d.h gdb-6.4-demangle_d/gdb/demangle_d/demangle_d.h
--- gdb-6.4/gdb/demangle_d/demangle_d.h 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/demangle_d/demangle_d.h 2006-04-19 13:22:13.000000000 +0200
@@ -0,0 +1,21 @@
+#if !(DEMANGLE_D_H)
+#define DEMANGEL_D_H 1
+
+#define DD_(str) demangle_d_##str
+
+/* demangle a D symbol
+ *
+ * input:
+ * a NULL terminated mangled symbol
+ *
+ * output:
+ * UTF-8 encoded demangled symbol
+ * or NULL if unable to demangle
+ *
+ * memory:
+ * the caller is responsible to
+ * free input and output
+ */
+static char* DD_(demangle_d)(char* source);
+
+#endif /* DEMANGEL_D_H */
diff -urN gdb-6.4/gdb/demangle_d/demangle_d_internal.h gdb-6.4-demangle_d/gdb/demangle_d/demangle_d_internal.h
--- gdb-6.4/gdb/demangle_d/demangle_d_internal.h 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/demangle_d/demangle_d_internal.h 2006-04-19 13:47:14.000000000 +0200
@@ -0,0 +1,45 @@
+#if !(DEMANGLE_D_INTERNAL_H)
+#define DEMANGLE_D_INTERNAL_H 1
+
+#include "demangle_d.h"
+
+typedef struct{
+ size_t used;
+ char* str;
+ size_t len;
+} DD_(string_t);
+
+DD_(string_t)* DD_(new_string)(void);
+
+void DD_(append_n)(DD_(string_t)* dest, const char* source, size_t len);
+void DD_(append_c)(DD_(string_t)* dest, char source);
+void DD_(append)(DD_(string_t)* dest, const char* source);
+
+void DD_(prepend_n)(DD_(string_t)* dest, const char* source, size_t len);
+void DD_(prepend)(DD_(string_t)* dest, const char* source);
+
+void DD_(nestpend_n)(DD_(string_t)* dest, const char* source, size_t len, int is_nested);
+void DD_(nestpend)(DD_(string_t)* dest, const char* source, int is_nested);
+
+char* DD_(nextType)(DD_(string_t)* dest, char* raw, int is_nested);
+
+void DD_(interpreteTemplate)(DD_(string_t)* dest, char* raw);
+
+char* DD_(parseReal)(DD_(string_t)* dest, char* raw);
+char* DD_(parseFunction)(DD_(string_t)* dest, char* raw, char* name, int is_nested);
+
+char* DD_(strndup)(const char* source, size_t len);
+
+#if (DEMANGLE_D_REQUIRE_strtol_10)
+long int DD_(strtol_10)(char* src, char** endptr);
+#endif
+
+#if (DEMANGLE_D_REQUIRE_malloc)
+void* DD_(malloc)(size_t len);
+#endif
+
+#if (DEMANGLE_D_REQUIRE_realloc)
+void* DD_(realloc)(void* ptr, size_t len);
+#endif
+
+#endif /* DEMANGLE_D_INTERNAL_H */
diff -urN gdb-6.4/gdb/demangle_d/license.txt gdb-6.4-demangle_d/gdb/demangle_d/license.txt
--- gdb-6.4/gdb/demangle_d/license.txt 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/demangle_d/license.txt 2006-04-18 10:07:40.000000000 +0200
@@ -0,0 +1,22 @@
+Eiffel Forum License, version 1
+
+Permission is hereby granted to use, copy, modify and/or distribute this
+package, provided that:
+
+ - copyright notices are retained unchanged
+
+ - any distribution of this package, whether modified or not, includes this
+ file
+
+Permission is hereby also granted to distribute binary programs which depend
+on this package, provided that:
+
+ - if the binary program depends on a modified version of this package, you
+ must publicly release the modified version of this package
+
+THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT
+OF THE USE OF THIS PACKAGE.
diff -urN gdb-6.4/gdb/demangle_d/readme.txt gdb-6.4-demangle_d/gdb/demangle_d/readme.txt
--- gdb-6.4/gdb/demangle_d/readme.txt 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/demangle_d/readme.txt 2006-04-19 12:02:13.000000000 +0200
@@ -0,0 +1,62 @@
+ pluggable D de-mangler
+=======================
+
+Author:
+ Thomas Kuehne <thomas@kuehne.cn>
+
+License:
+ Eiffel Forum License, version 1 (see license.txt)
+
+
+Usage: stand alone
+---------------------
+
+1) compile:
+ cc -DDEMANGLE_D_STANDALONE -o demangle_d demangle_d.c
+
+2) run:
+ ./demangle_d _D3std3utf6toUTF8FG4awZAa _D3std6string7sformatFAaYAa
+ > _D3std3utf6toUTF8FG4awZAa char[] std.utf.toUTF8(char[4], dchar)
+ > _D3std6string7sformatFAaYAa char[] std.string.sformat(char[], ...)
+
+
+Usage: plugin
+---------------------
+
+1) adapt demangle_d_conf.h to your system
+
+2) include demangle_d.c in your build system
+
+3) demangle:
+ #include "demangle_d.h"
+
+ char* mangled;
+ char* demangled;
+
+ mangled = "_D1b5outerFeZf";
+ demangled = DD_(demangle_d)(mangled);
+
+ // ... process demangled ...
+
+ if(demangled){
+ free(demangled);
+ }
+
+optional:
+ adapt the DD_(str) macro in "demangle_d.h" to resolve potential
+ name clashes in your object code
+
+
+TODO
+---------------------
+
+ * better output for symbols in nested types:
+ _staticCtorFZv3Ali5_ctorFiZC_D1b11_staticCtorFZv3Ali5innerFiZi
+
+ * handle "special" names:
+ _init__D1b11_staticCtorFZv3Al
+ _Class__D1b11_staticCtorFZv3Ali
+ _vtbl__D1b11_staticCtorFZv3Ali
+ _modctor_1b
+ _assert_1b
+
diff -urN gdb-6.4/gdb/d-lang.c gdb-6.4-demangle_d/gdb/d-lang.c
--- gdb-6.4/gdb/d-lang.c 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/d-lang.c 2006-04-17 22:06:33.000000000 +0200
@@ -0,0 +1,32 @@
+/* C language support routines for GDB, the GNU debugger.
+ Copyright 2006
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "symtab.h"
+#include "demangle_d/demangle_d.c"
+
+char* d_demangle(char* symbol, int options) {
+ return DD_(demangle_d)(symbol);
+}
+
+char* d_sym_demangle(const struct general_symbol_info *gsymbol) {
+ return DD_(demangle_d)(gsymbol->name);
+}
diff -urN gdb-6.4/gdb/d-lang.h gdb-6.4-demangle_d/gdb/d-lang.h
--- gdb-6.4/gdb/d-lang.h 1970-01-01 01:00:00.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/d-lang.h 2006-04-17 21:34:12.000000000 +0200
@@ -0,0 +1,37 @@
+/* C language support definitions for GDB, the GNU debugger.
+ Copyright 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2002
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#if !defined (D_LANG_H)
+#define D_LANG_H 1
+
+#include "symtab.h"
+
+/*****************************
+ D Language stuff
+******************************/
+
+char* d_demangle(const char* mangled, int options);
+
+char* d_sym_demangle(const struct general_symbol_info *gsymbol);
+
+
+#endif /* !defined (D_LANG_H) */
diff -urN gdb-6.4/gdb/dwarf2read.c gdb-6.4-demangle_d/gdb/dwarf2read.c
--- gdb-6.4/gdb/dwarf2read.c 2005-11-04 03:58:31.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/dwarf2read.c 2006-04-17 21:30:07.000000000 +0200
@@ -6098,6 +6098,9 @@
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:
@@ -6577,7 +6580,7 @@
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
fe = &lh->file_names[file - 1];
- if (fe->dir_index)
+ if (fe->dir_index && lh->include_dirs != NULL)
dir = lh->include_dirs[fe->dir_index - 1];
else
dir = comp_dir;
diff -urN gdb-6.4/gdb/language.c gdb-6.4-demangle_d/gdb/language.c
--- gdb-6.4/gdb/language.c 2005-10-03 23:21:20.000000000 +0200
+++ gdb-6.4-demangle_d/gdb/language.c 2006-04-17 21:30:46.000000000 +0200
@@ -539,6 +539,7 @@
{
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 ?
@@ -650,6 +651,7 @@
{
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;
@@ -690,6 +692,7 @@

case language_c:
case language_cplus:
+ case language_d:
case language_objc:
return (TYPE_CODE (type) == TYPE_CODE_INT) &&
TYPE_LENGTH (type) == sizeof (char)
@@ -712,6 +715,7 @@

case language_c:
case language_cplus:
+ case language_d:
case language_objc:
/* C does not have distinct string type. */
return (0);
@@ -731,6 +735,7 @@
{
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
@@ -804,6 +809,7 @@
}
return builtin_type_f_logical_s2;
case language_cplus:
+ case language_d:
case language_pascal:
if (current_language->la_language==language_cplus)
{sym = lookup_symbol ("bool", NULL, VAR_DOMAIN, NULL, NULL);}
diff -urN gdb-6.4/gdb/Makefile.in gdb-6.4-demangle_d/gdb/Makefile.in
--- gdb-6.4/gdb/Makefile.in 2005-11-16 13:44:10.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/Makefile.in 2006-04-17 21:32:59.000000000 +0200
@@ -515,7 +515,7 @@
c-exp.y c-lang.c c-typeprint.c c-valprint.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 \
+ cp-abi.c cp-support.c cp-namespace.c cp-valprint.c d-lang.c \
cp-name-parser.y \
dbxread.c demangle.c dictionary.c disasm.c doublest.c dummy-frame.c \
dwarfread.c dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \
@@ -655,6 +655,7 @@
completer_h = completer.h
cp_abi_h = cp-abi.h
cp_support_h = cp-support.h $(symtab_h)
+d_lang_h = d-lang.h $(symtab_h)
dcache_h = dcache.h
defs_h = defs.h $(config_h) $(ansidecl_h) $(gdb_locale_h) $(gdb_signals_h) \
$(libiberty_h) $(bfd_h) $(ui_file_h) $(xm_h) $(nm_h) $(tm_h) \
@@ -918,7 +919,7 @@
dbxread.o coffread.o coff-pe-read.o elfread.o \
dwarfread.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 \
ui-out.o cli-out.o \
varobj.o wrapper.o \
jv-lang.o jv-valprint.o jv-typeprint.o \
@@ -1859,6 +1860,9 @@
c-valprint.o: c-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \
$(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \
$(c_lang_h) $(cp_abi_h) $(target_h)
+d-lang.o: d-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+ $(parser_defs_h) $(language_h) $(c_lang_h) $(valprint_h) \
+ $(macroscope_h) $(gdb_assert_h) $(charset_h) $(gdb_string_h)
# OBSOLETE d10v-tdep.o: d10v-tdep.c
dbug-rom.o: dbug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
$(serial_h) $(regcache_h) $(m68k_tdep_h)
@@ -2668,7 +2672,7 @@
$(gdb_obstack_h) $(exceptions_h) $(language_h) $(bcache_h) \
$(block_h) $(gdb_regex_h) $(dictionary_h) $(gdb_string_h) \
$(readline_h)
-symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
+symtab.o: symtab.c $(defs_h) $(d_lang_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
$(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
diff -urN gdb-6.4/gdb/symfile.c gdb-6.4-demangle_d/gdb/symfile.c
--- gdb-6.4/gdb/symfile.c 2005-08-31 23:07:33.000000000 +0200
+++ gdb-6.4-demangle_d/gdb/symfile.c 2006-04-17 21:31:23.000000000 +0200
@@ -2317,6 +2317,7 @@
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 -urN gdb-6.4/gdb/symtab.c gdb-6.4-demangle_d/gdb/symtab.c
--- gdb-6.4/gdb/symtab.c 2005-03-08 05:34:44.000000000 +0100
+++ gdb-6.4-demangle_d/gdb/symtab.c 2006-04-17 21:32:33.000000000 +0200
@@ -42,6 +42,7 @@
#include "filenames.h" /* for FILENAME_CMP */
#include "objc-lang.h"
#include "ada-lang.h"
+#include "d-lang.h"

#include "hashtab.h"

@@ -405,6 +406,7 @@
{
gsymbol->language = language;
if (gsymbol->language == language_cplus
+ || gsymbol->language == language_d
|| gsymbol->language == language_java
|| gsymbol->language == language_objc)
{
@@ -451,6 +453,15 @@
if (gsymbol->language == language_unknown)
gsymbol->language = language_auto;

+ if (gsymbol->language == language_d
+ || gsymbol->language == language_auto) {
+ demangled = d_demangle(mangled, 0);
+ if (demangled != NULL) {
+ gsymbol->language = language_d;
+ return demangled;
+ }
+ }
+
if (gsymbol->language == language_objc
|| gsymbol->language == language_auto)
{
@@ -610,6 +621,7 @@

demangled = symbol_find_demangled_name (gsymbol, mangled);
if (gsymbol->language == language_cplus
+ || gsymbol->language == language_d
|| gsymbol->language == language_java
|| gsymbol->language == language_objc)
{
@@ -639,6 +651,7 @@
switch (gsymbol->language)
{
case language_cplus:
+ case language_d:
case language_java:
case language_objc:
if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
@@ -664,6 +677,7 @@
switch (gsymbol->language)
{
case language_cplus:
+ case language_d:
case language_java:
case language_objc:
if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
@@ -1023,7 +1037,7 @@

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 (current_language->la_language == language_cplus)
{
@@ -1035,6 +1049,16 @@
needtofreename = 1;
}
}
+ else if (current_language->la_language == language_d)
+ {
+ demangled_name = d_demangle (name, 0);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ needtofreename = 1;
+ }
+ }
else if (current_language->la_language == language_java)
{
demangled_name = cplus_demangle (name,
diff -urN gdb-6.4/include/elf/dwarf2.h gdb-6.4-demangle_d/include/elf/dwarf2.h
--- gdb-6.4/include/elf/dwarf2.h 2005-07-18 06:13:05.000000000 +0200
+++ gdb-6.4-demangle_d/include/elf/dwarf2.h 2006-04-17 21:47:19.000000000 +0200
@@ -732,6 +732,7 @@
DW_LANG_C99 = 0x000c,
DW_LANG_Ada95 = 0x000d,
DW_LANG_Fortran95 = 0x000e,
+ DW_LANG_D = 0x0013,
/* MIPS. */
DW_LANG_Mips_Assembler = 0x8001,
/* UPC. */