From 9cd2430ee0124fa0d34d6803cb148af471fa9f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 30 Oct 2008 18:16:21 +0000 Subject: [PATCH] * Namespaces of argument names are now also handled properly. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28385 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/debugger/demangle/gcc2.cpp | 149 +++++++++++------- 1 file changed, 90 insertions(+), 59 deletions(-) diff --git a/src/add-ons/kernel/debugger/demangle/gcc2.cpp b/src/add-ons/kernel/debugger/demangle/gcc2.cpp index 2545816ae0..6ef6686bd3 100644 --- a/src/add-ons/kernel/debugger/demangle/gcc2.cpp +++ b/src/add-ons/kernel/debugger/demangle/gcc2.cpp @@ -31,6 +31,10 @@ static void ignore_qualifiers(const char** _arg) { while (isupper(**_arg)) { + if (**_arg == 'Q') { + // argument has namespaces + break; + } if (**_arg == 'F') { // skip function declaration while (**_arg && **_arg != '_') @@ -165,61 +169,6 @@ skip_numbers(const char** _arg, int32 count) } -static uint32 -argument_name_length(const char** _arg) -{ - if (**_arg == 'N') - return 0; - - ignore_qualifiers(_arg); - - // See if it's a built-in type - if (isalpha(**_arg)) - return 0; - - return strtoul(*_arg, (char**)_arg, 10); -} - - -static uint32 -argument_length(const char** _arg) -{ - if (**_arg == 'N') { - // skip repeats - skip_numbers(_arg, 2); - return 0; - } else if (**_arg == 'T') { - // skip reference - skip_numbers(_arg, 1); - return 0; - } - - ignore_qualifiers(_arg); - - // See if it's a built-in type - if (isalpha(**_arg)) - return 1; - - return strtoul(*_arg, (char**)_arg, 10); -} - - -static const char* -next_argument(const char* arg) -{ - if (arg == NULL) - return NULL; - - uint32 length = argument_length(&arg); - arg += length; - - if (!arg[0]) - return NULL; - - return arg; -} - - static uint32 count_namespaces(const char** _mangled) { @@ -247,9 +196,10 @@ count_namespaces(const char** _mangled) } -static const char* -first_argument(const char* mangled) +static void +skip_namespaces(const char** _mangled) { + const char* mangled = *_mangled; int32 namespaces = count_namespaces(&mangled); while (namespaces-- > 0) { @@ -259,6 +209,67 @@ first_argument(const char* mangled) mangled += strtoul(mangled, (char**)&mangled, 10); } + *_mangled = mangled; +} + + +static bool +has_named_argument(const char** _arg) +{ + ignore_qualifiers(_arg); + + // See if it's a built-in type + return **_arg == 'Q' || isdigit(**_arg); +} + + +static uint32 +argument_length(const char** _arg) +{ + if (**_arg == 'N') { + // skip repeats + skip_numbers(_arg, 2); + return 0; + } else if (**_arg == 'T') { + // skip reference + skip_numbers(_arg, 1); + return 0; + } + + ignore_qualifiers(_arg); + + // See if it's a built-in type + if (**_arg != 'Q' && !isdigit(**_arg)) + return 1; + + const char* mangled = *_arg; + skip_namespaces(&mangled); + + return mangled - *_arg; +} + + +static const char* +next_argument(const char* arg) +{ + if (arg == NULL) + return NULL; + + uint32 length = argument_length(&arg); + arg += length; + + if (!arg[0]) + return NULL; + + return arg; +} + + +static const char* +first_argument(const char* mangled) +{ + skip_namespaces(&mangled); + return mangled; } @@ -378,8 +389,28 @@ get_next_argument_internal(uint32* _cookie, const char* symbol, char* name, if (_argumentLength != NULL) *_argumentLength = argumentLength; - uint32 length = argument_name_length(&arg); - strlcpy(name, arg, min_c(length + 1, nameSize)); + name[0] = '\0'; + if (!has_named_argument(&arg)) + return B_OK; + + const char* namespaceStart = arg; + int32 namespaces = count_namespaces(&namespaceStart); + + while (namespaces-- > 0) { + if (namespaceStart[0] == 't') { + // It's a template class after all + return B_BAD_TYPE; + } + if (!isdigit(namespaceStart[0])) + break; + + uint32 length = strtoul(namespaceStart, (char**)&namespaceStart, 10); + uint32 max = strlen(name) + length + 1; + strlcat(name, namespaceStart, min_c(max, nameSize)); + if (namespaces > 0) + strlcat(name, "::", nameSize); + namespaceStart += length; + } return B_OK; }