This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

D Symbol Demangling


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
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.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]