1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "Demangler.h"
7
8#include <TypeConstants.h>
9
10#include "demangle.h"
11
12
13/*static*/ BString
14Demangler::Demangle(const BString& mangledName)
15{
16	char buffer[1024];
17
18	if (mangledName.Compare("_Z", 2) == 0) {
19		// probably a gcc3+ mangled symbol
20		const char* demangled = demangle_name_gcc3(mangledName.String(), buffer,
21			sizeof(buffer));
22		if (demangled != NULL)
23			return demangled;
24	}
25
26	// try gcc 2 demangling
27	const char* demangled = demangle_symbol_gcc2(mangledName.String(), buffer,
28		sizeof(buffer), NULL);
29
30	if (demangled == NULL) {
31		// name not mangled
32		return mangledName;
33	}
34
35	BString demangledName(demangled);
36	demangledName << "(";
37
38	size_t length;
39	int32 type;
40	int32 i = 0;
41	uint32 cookie = 0;
42	while (get_next_argument_gcc2(&cookie, mangledName.String(), buffer,
43			sizeof(buffer), &type, &length) == B_OK) {
44		if (i++ > 0)
45			demangledName << ", ";
46
47		if (buffer[0]) {
48			demangledName << buffer;
49			continue;
50		}
51
52		// unnamed argument: fallback to known type
53		switch (type) {
54			case B_ANY_TYPE:
55				break;
56			case B_INT64_TYPE:
57				demangledName << "int64";
58				break;
59			case B_INT32_TYPE:
60				demangledName << "int32";
61				break;
62			case B_INT16_TYPE:
63				demangledName << "int16";
64				break;
65			case B_INT8_TYPE:
66				demangledName << "int8";
67				break;
68			case B_UINT64_TYPE:
69				demangledName << "uint64";
70				break;
71			case B_UINT32_TYPE:
72				demangledName << "uint32";
73				break;
74			case B_UINT16_TYPE:
75				demangledName << "uint16";
76				break;
77			case B_UINT8_TYPE:
78				demangledName << "uint8";
79				break;
80			case B_BOOL_TYPE:
81				demangledName << "bool";
82				break;
83			case B_CHAR_TYPE:
84				demangledName << "char";
85				break;
86			case B_FLOAT_TYPE:
87				demangledName << "float";
88				break;
89			case B_DOUBLE_TYPE:
90				demangledName << "double";
91				break;
92			case B_POINTER_TYPE:
93				// TODO: use length as hint on pointer type
94				demangledName << "void*";
95				break;
96			case B_REF_TYPE:
97			case B_NODE_REF_TYPE:
98				// TODO: use length as hint on reference type
99				demangledName << "&";
100				break;
101			case B_STRING_TYPE:
102				demangledName << "char*";
103				break;
104			default:
105				demangledName << "?";
106				break;
107		}
108	}
109
110	demangledName << ")";
111	return demangledName;
112}
113