From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13805 invoked by alias); 19 Apr 2006 11:18:18 -0000 Received: (qmail 13790 invoked by uid 22791); 19 Apr 2006 11:18:14 -0000 X-Spam-Check-By: sourceware.org Received: from N4306.n.pppool.de (HELO [89.50.67.6]) (89.50.67.6) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 19 Apr 2006 11:18:08 +0000 Message-ID: <44462A40.1040004@kuehne.cn> Date: Wed, 19 Apr 2006 11:18:00 -0000 From: Thomas Kuehne User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20060304 MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: D Symbol Demangling Content-Type: multipart/mixed; boundary="------------050507040501030405020701" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-04/txt/msg00259.txt.bz2 This is a multi-part message in MIME format. --------------050507040501030405020701 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-length: 664 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 --------------050507040501030405020701 Content-Type: text/plain; name="gdb-6.4-demangle_d.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="gdb-6.4-demangle_d.diff" Content-length: 40717 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 + * + * + * 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 " + "($Date: 2006-04-19T11:09:00.287803Z $)\n"); + if(argc > 0){ + xfprintf(stderr, "%s [ ...]\n", argv[0]); + }else{ + xfprintf(stderr, "dmangle_d [ ...]\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 /* 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 +#define xmemcpy memcpy +#define xmemmove memmove +#define xstrlen strlen +#define xstrncmp strncmp + +#include +#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 +#define xsnprintf snprintf + +#include +#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 + +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. */ --------------050507040501030405020701--