xref: /haiku/src/add-ons/kernel/debugger/demangle/gcc3+.cpp (revision a267f17ca645ceae1728e10680c6d1377589eef1)
1 /*
2  * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2021, Jerome Duval, jerome.duval@gmail.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include <ctype.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include <new>
14 
15 #include <TypeConstants.h>
16 
17 #ifdef _KERNEL_MODE
18 #	include <debug_heap.h>
19 #endif
20 
21 #include "demangle.h"
22 
23 
24 // C++ ABI: https://itanium-cxx-abi.github.io/cxx-abi/abi.html
25 
26 
27 //#define TRACE_GCC3_DEMANGLER
28 #ifdef TRACE_GCC3_DEMANGLER
29 #	define TRACE(x...) PRINT(x)
30 #	define DEBUG_SCOPE(name)	DebugScope debug(name, fInput.String())
31 #else
32 #	define TRACE(x...) ;
33 #	define DEBUG_SCOPE(name)	do {} while (false)
34 #endif
35 
36 #ifdef _KERNEL_MODE
37 #	define PRINT(format...)		kprintf(format)
38 #	define VPRINT(format, args)	PRINT("%s", format)
39 									// no vkprintf()
40 #	define NEW(constructor) new(kdebug_alloc) constructor
41 #	define DELETE(object)	DebugAlloc::destroy(object)
42 #else
43 #	define PRINT(format...)		printf(format)
44 #	define VPRINT(format, args)	vprintf(format, args)
45 #	define NEW(constructor) new(std::nothrow) constructor
46 #	define DELETE(object)	delete object
47 #endif
48 
49 
50 typedef long number_type;
51 
52 enum {
53 	ERROR_OK = 0,
54 	ERROR_NOT_MANGLED,
55 	ERROR_UNSUPPORTED,
56 	ERROR_INVALID,
57 	ERROR_BUFFER_TOO_SMALL,
58 	ERROR_NO_MEMORY,
59 	ERROR_INTERNAL,
60 	ERROR_INVALID_PARAMETER_INDEX
61 };
62 
63 // object classification
64 enum object_type {
65 	OBJECT_TYPE_UNKNOWN,
66 	OBJECT_TYPE_DATA,
67 	OBJECT_TYPE_FUNCTION,
68 	OBJECT_TYPE_METHOD_CLASS,
69 	OBJECT_TYPE_METHOD_OBJECT,
70 	OBJECT_TYPE_METHOD_UNKNOWN
71 };
72 
73 // prefix classification
74 enum prefix_type {
75 	PREFIX_NONE,
76 	PREFIX_NAMESPACE,
77 	PREFIX_CLASS,
78 	PREFIX_UNKNOWN
79 };
80 
81 // type classification
82 enum type_type {
83 	TYPE_ELLIPSIS,
84 	TYPE_VOID,
85 	TYPE_WCHAR_T,
86 	TYPE_BOOL,
87 	TYPE_CHAR,
88 	TYPE_SIGNED_CHAR,
89 	TYPE_UNSIGNED_CHAR,
90 	TYPE_SHORT,
91 	TYPE_UNSIGNED_SHORT,
92 	TYPE_INT,
93 	TYPE_UNSIGNED_INT,
94 	TYPE_LONG,
95 	TYPE_UNSIGNED_LONG,
96 	TYPE_LONG_LONG,
97 	TYPE_UNSIGNED_LONG_LONG,
98 	TYPE_INT128,
99 	TYPE_UNSIGNED_INT128,
100 	TYPE_FLOAT,
101 	TYPE_DOUBLE,
102 	TYPE_LONG_DOUBLE,
103 	TYPE_FLOAT128,
104 	TYPE_DFLOAT16,
105 	TYPE_DFLOAT32,
106 	TYPE_DFLOAT64,
107 	TYPE_DFLOAT128,
108 	TYPE_CHAR16_T,
109 	TYPE_CHAR32_T,
110 
111 	TYPE_UNKNOWN,
112 	TYPE_CONST_CHAR_POINTER,
113 	TYPE_POINTER,
114 	TYPE_REFERENCE
115 };
116 
117 const char* const kTypeNames[] = {
118 	"...",
119 	"void",
120 	"wchar_t",
121 	"bool",
122 	"char",
123 	"signed char",
124 	"unsigned char",
125 	"short",
126 	"unsigned short",
127 	"int",
128 	"unsigned int",
129 	"long",
130 	"unsigned long",
131 	"long long",
132 	"unsigned long long",
133 	"__int128",
134 	"unsigned __int128",
135 	"float",
136 	"double",
137 	"long double",
138 	"__float128",
139 	"__dfloat16",	// TODO: Official names for the __dfloat*!
140 	"__dfloat32",
141 	"__dfloat64",
142 	"__dfloat64",
143 	"char16_t",
144 	"char32_t",
145 
146 	"?",
147 	"char const*",
148 	"void*",
149 	"void&"
150 };
151 
152 
153 // CV qualifier flags
154 enum {
155 	CV_QUALIFIER_RESTRICT	= 0x1,
156 	CV_QUALIFIER_VOLATILE	= 0x2,
157 	CV_QUALIFIER_CONST		= 0x4
158 };
159 
160 enum type_modifier {
161 	TYPE_QUALIFIER_POINTER = 0,
162 	TYPE_QUALIFIER_REFERENCE,
163 	TYPE_QUALIFIER_RVALUE_REFERENCE,
164 	TYPE_QUALIFIER_COMPLEX,
165 	TYPE_QUALIFIER_IMAGINARY
166 };
167 
168 static const char* const kTypeModifierSuffixes[] = {
169 	"*",
170 	"&",
171 	"&&",
172 	" complex",
173 	" imaginary"
174 };
175 
176 struct operator_info {
177 	const char*	mangled_name;
178 	const char*	name;
179 	int			argument_count;
180 	int			flags;
181 };
182 
183 // operator flags
184 enum {
185 	OPERATOR_TYPE_PARAM		= 0x01,
186 	OPERATOR_IS_MEMBER		= 0x02
187 };
188 
189 
190 static const operator_info kOperatorInfos[] = {
191 	{ "nw", "new", -1, OPERATOR_IS_MEMBER },
192 	{ "na", "new[]", -1, OPERATOR_IS_MEMBER },
193 	{ "dl", "delete", -1, OPERATOR_IS_MEMBER },
194 	{ "da", "delete[]", -1, OPERATOR_IS_MEMBER },
195 	{ "ps", "+", 1, 0 },		// unary
196 	{ "ng", "-", 1, 0 },		// unary
197 	{ "ad", "&", 1, 0 },		// unary
198 	{ "de", "*", 1, 0 },		// unary
199 	{ "co", "~", 1, 0 },
200 	{ "pl", "+", 2, 0 },
201 	{ "mi", "-", 2, 0 },
202 	{ "ml", "*", 2, 0 },
203 	{ "dv", "/", 2, 0 },
204 	{ "rm", "%", 2, 0 },
205 	{ "an", "&", 2, 0 },
206 	{ "or", "|", 2, 0 },
207 	{ "eo", "^", 2, 0 },
208 	{ "aS", "=", 2, 0 },
209 	{ "pL", "+=", 2, 0 },
210 	{ "mI", "-=", 2, 0 },
211 	{ "mL", "*=", 2, 0 },
212 	{ "dV", "/=", 2, 0 },
213 	{ "rM", "%=", 2, 0 },
214 	{ "aN", "&=", 2, 0 },
215 	{ "oR", "|=", 2, 0 },
216 	{ "eO", "^=", 2, 0 },
217 	{ "ls", "<<", 2, 0 },
218 	{ "rs", ">>", 2, 0 },
219 	{ "lS", "<<=", 2, 0 },
220 	{ "rS", ">>=", 2, 0 },
221 	{ "eq", "==", 2, 0 },
222 	{ "ne", "!=", 2, 0 },
223 	{ "lt", "<", 2, 0 },
224 	{ "gt", ">", 2, 0 },
225 	{ "le", "<=", 2, 0 },
226 	{ "ge", ">=", 2, 0 },
227 	{ "nt", "!", 1, 0 },
228 	{ "aa", "&&", 2, 0 },
229 	{ "oo", "||", 2, 0 },
230 	{ "pp", "++", 1, 0 },
231 	{ "mm", "--", 1, 0 },
232 	{ "cm", ",", -1, 0 },
233 	{ "pm", "->*", 2, 0 },
234 	{ "pt", "->", 2, 0 },
235 	{ "cl", "()", -1, 0 },
236 	{ "ix", "[]", -1, 0 },
237 	{ "qu", "?", 3, 0 },
238 	{ "st", "sizeof", 1, OPERATOR_TYPE_PARAM },		// type
239 	{ "sz", "sizeof", 1, 0 },						// expression
240 	{ "at", "alignof", 1, OPERATOR_TYPE_PARAM },	// type
241 	{ "az", "alignof", 1, 0 },						// expression
242 	{}
243 };
244 
245 
246 #ifdef TRACE_GCC3_DEMANGLER
247 
248 struct DebugScope {
249 	DebugScope(const char* functionName, const char* remainingString = NULL)
250 		:
251 		fParent(sGlobalScope),
252 		fFunctionName(functionName),
253 		fLevel(fParent != NULL ? fParent->fLevel + 1 : 0)
254 	{
255 		sGlobalScope = this;
256 		if (remainingString != NULL) {
257 			PRINT("%*s%s(): \"%s\"\n", fLevel * 2, "", fFunctionName,
258 				remainingString);
259 		} else
260 			PRINT("%*s%s()\n", fLevel * 2, "", fFunctionName);
261 	}
262 
263 	~DebugScope()
264 	{
265 		sGlobalScope = fParent;
266 		PRINT("%*s%s() done\n", fLevel * 2, "", fFunctionName);
267 	}
268 
269 	static void Print(const char* format,...)
270 	{
271 		int level = sGlobalScope != NULL ? sGlobalScope->fLevel : 0;
272 
273 		va_list args;
274 		va_start(args, format);
275 		PRINT("%*s", (level + 1) * 2, "");
276 		VPRINT(format, args);
277 		va_end(args);
278 	}
279 
280 private:
281 	DebugScope*	fParent;
282 	const char*	fFunctionName;
283 	int			fLevel;
284 
285 	static DebugScope* sGlobalScope;
286 };
287 
288 DebugScope* DebugScope::sGlobalScope = NULL;
289 
290 #endif	// TRACE_GCC3_DEMANGLER
291 
292 
293 class Input {
294 public:
295 	Input()
296 		:
297 		fString(NULL),
298 		fLength(0)
299 	{
300 	}
301 
302 	void SetTo(const char* string, size_t length)
303 	{
304 		fString = string;
305 		fLength = length;
306 	}
307 
308 	const char* String() const
309 	{
310 		return fString;
311 	}
312 
313 	int CharsRemaining() const
314 	{
315 		return fLength;
316 	}
317 
318 	void Skip(size_t count)
319 	{
320 		if (count > fLength) {
321 			PRINT("Input::Skip(): fOffset > fLength\n");
322 			return;
323 		}
324 
325 		fString += count;
326 		fLength -= count;
327 	}
328 
329 	bool HasPrefix(char prefix) const
330 	{
331 		return fLength > 0 && fString[0] == prefix;
332 	}
333 
334 	bool HasPrefix(const char* prefix) const
335 	{
336 		size_t prefixLen = strlen(prefix);
337 		return prefixLen <= fLength
338 			&& strncmp(fString, prefix, strlen(prefix)) == 0;
339 	}
340 
341 	bool SkipPrefix(char prefix)
342 	{
343 		if (!HasPrefix(prefix))
344 			return false;
345 
346 		fString++;
347 		fLength--;
348 		return true;
349 	}
350 
351 	bool SkipPrefix(const char* prefix)
352 	{
353 		size_t prefixLen = strlen(prefix);
354 		if (prefixLen <= fLength && strncmp(fString, prefix, prefixLen) != 0)
355 			return false;
356 
357 		fString += prefixLen;
358 		fLength -= prefixLen;
359 		return true;
360 	}
361 
362 	char operator[](size_t index) const
363 	{
364 		if (index >= fLength) {
365 			PRINT("Input::operator[](): fOffset + index >= fLength\n");
366 			return '\0';
367 		}
368 
369 		return fString[index];
370 	}
371 
372 private:
373 	const char*	fString;
374 	size_t		fLength;
375 };
376 
377 
378 class NameBuffer {
379 public:
380 	NameBuffer(char* buffer, size_t size)
381 		:
382 		fBuffer(buffer),
383 		fSize(size),
384 		fLength(0),
385 		fOverflow(false)
386 	{
387 	}
388 
389 	bool IsEmpty() const
390 	{
391 		return fLength == 0;
392 	}
393 
394 	char LastChar() const
395 	{
396 		return fLength > 0 ? fBuffer[fLength - 1] : '\0';
397 	}
398 
399 	bool HadOverflow() const
400 	{
401 		return fOverflow;
402 	}
403 
404 	char* Terminate()
405 	{
406 		fBuffer[fLength] = '\0';
407 		return fBuffer;
408 	}
409 
410 	bool Append(const char* string, size_t length)
411 	{
412 		if (fLength + length >= fSize) {
413 			fOverflow = true;
414 			return false;
415 		}
416 
417 		memcpy(fBuffer + fLength, string, length);
418 		fLength += length;
419 		return true;
420 	}
421 
422 	bool Append(const char* string)
423 	{
424 		return Append(string, strlen(string));
425 	}
426 
427 private:
428 	char*	fBuffer;
429 	size_t	fSize;
430 	size_t	fLength;
431 	bool	fOverflow;
432 };
433 
434 
435 struct TypeInfo {
436 	type_type	type;
437 	int			cvQualifiers;
438 
439 	TypeInfo()
440 		:
441 		type(TYPE_UNKNOWN),
442 		cvQualifiers(0)
443 	{
444 	}
445 
446 	TypeInfo(type_type type)
447 		:
448 		type(type),
449 		cvQualifiers(0)
450 	{
451 	}
452 
453 	TypeInfo(const TypeInfo& other, int cvQualifiers = 0)
454 		:
455 		type(other.type),
456 		cvQualifiers(other.cvQualifiers | cvQualifiers)
457 	{
458 	}
459 
460 	TypeInfo& operator=(const TypeInfo& other)
461 	{
462 		type = other.type;
463 		cvQualifiers = other.cvQualifiers;
464 		return *this;
465 	}
466 };
467 
468 
469 struct DemanglingParameters {
470 	bool	objectNameOnly;
471 
472 	DemanglingParameters(bool objectNameOnly)
473 		:
474 		objectNameOnly(objectNameOnly)
475 	{
476 	}
477 };
478 
479 
480 struct DemanglingInfo : DemanglingParameters {
481 	object_type	objectType;
482 
483 	DemanglingInfo(bool objectNameOnly)
484 		:
485 		DemanglingParameters(objectNameOnly),
486 		objectType(OBJECT_TYPE_UNKNOWN)
487 	{
488 	}
489 };
490 
491 
492 struct ParameterInfo {
493 	TypeInfo	type;
494 
495 	ParameterInfo()
496 	{
497 	}
498 };
499 
500 
501 class Node;
502 
503 struct NameDecorationInfo {
504 	const Node*	firstDecorator;
505 	const Node*	closestCVDecoratorList;
506 
507 	NameDecorationInfo(const Node* decorator)
508 		:
509 		firstDecorator(decorator),
510 		closestCVDecoratorList(NULL)
511 	{
512 	}
513 };
514 
515 struct CVQualifierInfo {
516 	const Node*	firstCVQualifier;
517 	const Node*	firstNonCVQualifier;
518 
519 	CVQualifierInfo()
520 		:
521 		firstCVQualifier(NULL),
522 		firstNonCVQualifier(NULL)
523 	{
524 	}
525 };
526 
527 
528 class Node {
529 public:
530 	Node()
531 		:
532 		fNextAllocated(NULL),
533 		fParent(NULL),
534 		fNext(NULL),
535 		fNextReferenceable(NULL),
536 		fReferenceable(true)
537 	{
538 	}
539 
540 	virtual ~Node()
541 	{
542 	}
543 
544 	Node* NextAllocated() const			{ return fNextAllocated; }
545 	void SetNextAllocated(Node* node)	{ fNextAllocated = node; }
546 
547 	Node* Parent() const				{ return fParent; }
548 	virtual void SetParent(Node* node)	{ fParent = node; }
549 
550 	Node* Next() const			{ return fNext; }
551 	void SetNext(Node* node)	{ fNext = node; }
552 
553 	bool IsReferenceable() const		{ return fReferenceable; }
554 	void SetReferenceable(bool flag)	{ fReferenceable = flag; }
555 
556 	Node* NextReferenceable() const			{ return fNextReferenceable; }
557 	void SetNextReferenceable(Node* node)	{ fNextReferenceable = node; }
558 
559 	virtual bool GetName(NameBuffer& buffer) const = 0;
560 
561 	virtual bool GetDecoratedName(NameBuffer& buffer,
562 		NameDecorationInfo& decorationInfo) const
563 	{
564 		if (!GetName(buffer))
565 			return false;
566 
567 		return decorationInfo.firstDecorator == NULL
568 			|| decorationInfo.firstDecorator->AddDecoration(buffer, NULL);
569 	}
570 
571 	virtual bool AddDecoration(NameBuffer& buffer,
572 		const Node* stopDecorator) const
573 	{
574 		return true;
575 	}
576 
577 	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
578 	{
579 		info.firstNonCVQualifier = this;
580 	}
581 
582 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
583 	{
584 		return this;
585 	}
586 
587 	virtual bool IsTemplatized() const
588 	{
589 		return false;
590 	}
591 
592 	virtual Node* TemplateParameterAt(int index) const
593 	{
594 		return NULL;
595 	}
596 
597 	virtual bool IsNoReturnValueFunction() const
598 	{
599 		return false;
600 	}
601 
602 	virtual bool IsTypeName(const char* name, size_t length) const
603 	{
604 		return false;
605 	}
606 
607 	virtual object_type ObjectType() const
608 	{
609 		return OBJECT_TYPE_UNKNOWN;
610 	}
611 
612 	virtual prefix_type PrefixType() const
613 	{
614 		return PREFIX_NONE;
615 	}
616 
617 	virtual TypeInfo Type() const
618 	{
619 		return TypeInfo();
620 	}
621 
622 private:
623 	Node*	fNextAllocated;
624 	Node*	fParent;
625 	Node*	fNext;
626 	Node*	fNextReferenceable;
627 	bool	fReferenceable;
628 };
629 
630 
631 class NamedTypeNode : public Node {
632 public:
633 	NamedTypeNode(Node* name)
634 		:
635 		fName(name)
636 	{
637 		if (fName != NULL)
638 			fName->SetParent(this);
639 	}
640 
641 	virtual bool GetName(NameBuffer& buffer) const
642 	{
643 		return fName == NULL || fName->GetName(buffer);
644 	}
645 
646 	virtual bool IsNoReturnValueFunction() const
647 	{
648 		return fName != NULL && fName->IsNoReturnValueFunction();
649 	}
650 
651 	virtual TypeInfo Type() const
652 	{
653 		return fName != NULL ? fName->Type() : TypeInfo();
654 	}
655 
656 protected:
657 	Node*	fName;
658 };
659 
660 
661 class SubstitutionNode : public Node {
662 public:
663 	SubstitutionNode(Node* node)
664 		:
665 		fNode(node)
666 	{
667 	}
668 
669 	virtual bool GetName(NameBuffer& buffer) const
670 	{
671 		return fNode->GetName(buffer);
672 	}
673 
674 	virtual bool GetDecoratedName(NameBuffer& buffer,
675 		NameDecorationInfo& decorationInfo) const
676 	{
677 		return fNode->GetDecoratedName(buffer, decorationInfo);
678 	}
679 
680 	virtual bool AddDecoration(NameBuffer& buffer,
681 		const Node* stopDecorator) const
682 	{
683 		return fNode->AddDecoration(buffer, stopDecorator);
684 	}
685 
686 	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
687 	{
688 		fNode->GetCVQualifierInfo(info);
689 	}
690 
691 	virtual bool IsTemplatized() const
692 	{
693 		return fNode->IsTemplatized();
694 	}
695 
696 	virtual Node* TemplateParameterAt(int index) const
697 	{
698 		return fNode->TemplateParameterAt(index);
699 	}
700 
701 	virtual bool IsNoReturnValueFunction() const
702 	{
703 		return fNode->IsNoReturnValueFunction();
704 	}
705 
706 	virtual bool IsTypeName(const char* name, size_t length) const
707 	{
708 		return fNode->IsTypeName(name, length);
709 	}
710 
711 	virtual object_type ObjectType() const
712 	{
713 		return fNode->ObjectType();
714 	}
715 
716 	virtual prefix_type PrefixType() const
717 	{
718 		return fNode->PrefixType();
719 	}
720 
721 	virtual TypeInfo Type() const
722 	{
723 		return fNode->Type();
724 	}
725 
726 private:
727 	Node*	fNode;
728 };
729 
730 
731 class ArrayNode : public NamedTypeNode {
732 public:
733 	ArrayNode(Node* type, int dimension)
734 		:
735 		NamedTypeNode(type),
736 		fDimensionExpression(NULL),
737 		fDimensionNumber(dimension)
738 	{
739 	}
740 
741 	ArrayNode(Node* type, Node* dimension)
742 		:
743 		NamedTypeNode(type),
744 		fDimensionExpression(dimension),
745 		fDimensionNumber(0)
746 	{
747 		fDimensionExpression->SetParent(this);
748 	}
749 
750 	virtual bool GetName(NameBuffer& buffer) const
751 	{
752 		if (!fName->GetName(buffer))
753 			return false;
754 
755 		buffer.Append("[", 1);
756 
757 		if (fDimensionExpression != NULL) {
758 			if (!fDimensionExpression->GetName(buffer))
759 				return false;
760 		} else {
761 			char stringBuffer[16];
762 			snprintf(stringBuffer, sizeof(stringBuffer), "%d",
763 				fDimensionNumber);
764 			buffer.Append(stringBuffer);
765 		}
766 
767 		return buffer.Append("]", 1);
768 	}
769 
770 	virtual object_type ObjectType() const
771 	{
772 		return OBJECT_TYPE_DATA;
773 	}
774 
775 	virtual TypeInfo Type() const
776 	{
777 // TODO: Check!
778 		return TypeInfo(TYPE_POINTER);
779 	}
780 
781 
782 private:
783 	Node*	fDimensionExpression;
784 	int		fDimensionNumber;
785 };
786 
787 
788 class ObjectNode : public NamedTypeNode {
789 public:
790 	ObjectNode(Node* name)
791 		:
792 		NamedTypeNode(name)
793 	{
794 	}
795 
796 	virtual bool GetObjectName(NameBuffer& buffer,
797 		const DemanglingParameters& parameters)
798 	{
799 		if (parameters.objectNameOnly)
800 			return fName != NULL ? fName->GetName(buffer) : true;
801 
802 		return GetName(buffer);
803 	}
804 
805 	virtual object_type ObjectType() const
806 	{
807 		return OBJECT_TYPE_DATA;
808 	}
809 
810 	virtual Node* ParameterAt(uint32 index) const
811 	{
812 		return NULL;
813 	}
814 };
815 
816 
817 class SimpleNameNode : public Node {
818 public:
819 	SimpleNameNode(const char* name)
820 		:
821 		fName(name),
822 		fLength(strlen(name))
823 	{
824 	}
825 
826 	SimpleNameNode(const char* name, size_t length)
827 		:
828 		fName(name),
829 		fLength(length)
830 	{
831 	}
832 
833 	virtual bool GetName(NameBuffer& buffer) const
834 	{
835 		return buffer.Append(fName, fLength);
836 	}
837 
838 protected:
839 	const char*	fName;
840 	size_t		fLength;
841 };
842 
843 
844 class SimpleTypeNode : public SimpleNameNode {
845 public:
846 	SimpleTypeNode(const char* name)
847 		:
848 		SimpleNameNode(name),
849 		fType(TYPE_UNKNOWN)
850 	{
851 	}
852 
853 	SimpleTypeNode(type_type type)
854 		:
855 		SimpleNameNode(kTypeNames[type]),
856 		fType(type)
857 	{
858 	}
859 
860 	virtual bool IsTypeName(const char* name, size_t length) const
861 	{
862 		return fLength == length && strcmp(fName, name) == 0;
863 	}
864 
865 	virtual object_type ObjectType() const
866 	{
867 		return OBJECT_TYPE_DATA;
868 	}
869 
870 	virtual TypeInfo Type() const
871 	{
872 		return TypeInfo(fType);
873 	}
874 
875 private:
876 	type_type	fType;
877 };
878 
879 
880 class TypedNumberLiteralNode : public Node {
881 public:
882 	TypedNumberLiteralNode(Node* type, const char* number, size_t length)
883 		:
884 		fType(type),
885 		fNumber(number),
886 		fLength(length)
887 	{
888 		fType->SetParent(this);
889 	}
890 
891 	virtual bool GetName(NameBuffer& buffer) const
892 	{
893 		// If the type is bool and the number is 0 or 1, we use "false" or
894 		// "true" respectively.
895 		if (fType->IsTypeName("bool", 4) && fLength == 1
896 			&& (fNumber[0] == '0' || fNumber[0] == '1')) {
897 			return buffer.Append(fNumber[0] == '0' ? "false" : "true");
898 		}
899 
900 		// Add the type in parentheses. The GNU demangler omits "int", so do we.
901 		if (!fType->IsTypeName("int", 3)) {
902 			buffer.Append("(");
903 			if (!fType->GetName(buffer))
904 				return false;
905 			buffer.Append(")");
906 		}
907 
908 		// add the number -- replace a leading 'n' by '-', if necessary
909 		if (fLength > 0 && fNumber[0] == 'n') {
910 			buffer.Append("-");
911 			return buffer.Append(fNumber + 1, fLength - 1);
912 		}
913 
914 		return buffer.Append(fNumber, fLength);
915 	}
916 
917 	virtual object_type ObjectType() const
918 	{
919 		return OBJECT_TYPE_DATA;
920 	}
921 
922 private:
923 	Node*		fType;
924 	const char*	fNumber;
925 	size_t		fLength;
926 };
927 
928 
929 class XtructorNode : public Node {
930 public:
931 	XtructorNode(bool constructor, char type)
932 		:
933 		fConstructor(constructor),
934 		fType(type)
935 	{
936 	}
937 
938 	virtual void SetParent(Node* node)
939 	{
940 		fUnqualifiedNode = node->GetUnqualifiedNode(this);
941 		Node::SetParent(node);
942 	}
943 
944 	virtual bool GetName(NameBuffer& buffer) const
945 	{
946 		if (fUnqualifiedNode == NULL)
947 			return false;
948 
949 		if (!fConstructor)
950 			buffer.Append("~");
951 
952 		return fUnqualifiedNode->GetName(buffer);
953 	}
954 
955 	virtual bool IsNoReturnValueFunction() const
956 	{
957 		return true;
958 	}
959 
960 	virtual object_type ObjectType() const
961 	{
962 		return OBJECT_TYPE_METHOD_CLASS;
963 	}
964 
965 private:
966 	bool		fConstructor;
967 	char		fType;
968 	Node*		fUnqualifiedNode;
969 };
970 
971 
972 class SpecialNameNode : public Node {
973 public:
974 	SpecialNameNode(const char* name, Node* child)
975 		:
976 		fName(name),
977 		fChild(child)
978 	{
979 		fChild->SetParent(this);
980 	}
981 
982 	virtual bool GetName(NameBuffer& buffer) const
983 	{
984 		return buffer.Append(fName) && fChild->GetName(buffer);
985 	}
986 
987 protected:
988 	const char*	fName;
989 	Node*		fChild;
990 };
991 
992 
993 class DecoratingNode : public Node {
994 public:
995 	DecoratingNode(Node* child)
996 		:
997 		fChildNode(child)
998 	{
999 		fChildNode->SetParent(this);
1000 	}
1001 
1002 	virtual bool GetName(NameBuffer& buffer) const
1003 	{
1004 		NameDecorationInfo decorationInfo(this);
1005 		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1006 	}
1007 
1008 	virtual bool GetDecoratedName(NameBuffer& buffer,
1009 		NameDecorationInfo& decorationInfo) const
1010 	{
1011 		decorationInfo.closestCVDecoratorList = NULL;
1012 		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1013 	}
1014 
1015 protected:
1016 	Node*	fChildNode;
1017 };
1018 
1019 
1020 class CVQualifiersNode : public DecoratingNode {
1021 public:
1022 	CVQualifiersNode(int qualifiers, Node* child)
1023 		:
1024 		DecoratingNode(child),
1025 		fCVQualifiers(qualifiers)
1026 	{
1027 	}
1028 
1029 	virtual bool GetDecoratedName(NameBuffer& buffer,
1030 		NameDecorationInfo& decorationInfo) const
1031 	{
1032 		if (decorationInfo.closestCVDecoratorList == NULL)
1033 			decorationInfo.closestCVDecoratorList = this;
1034 		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1035 	}
1036 
1037 	virtual bool AddDecoration(NameBuffer& buffer,
1038 		const Node* stopDecorator) const
1039 	{
1040 		if (this == stopDecorator)
1041 			return true;
1042 
1043 		if (!fChildNode->AddDecoration(buffer, stopDecorator))
1044 			return false;
1045 
1046 		if ((fCVQualifiers & CV_QUALIFIER_RESTRICT) != 0)
1047 			buffer.Append(" restrict");
1048 		if ((fCVQualifiers & CV_QUALIFIER_VOLATILE) != 0)
1049 			buffer.Append(" volatile");
1050 		if ((fCVQualifiers & CV_QUALIFIER_CONST) != 0)
1051 			buffer.Append(" const");
1052 
1053 		return true;
1054 	}
1055 
1056 	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
1057 	{
1058 		if (info.firstCVQualifier == NULL)
1059 			info.firstCVQualifier = this;
1060 		fChildNode->GetCVQualifierInfo(info);
1061 	}
1062 
1063 	virtual bool IsTemplatized() const
1064 	{
1065 		return fChildNode->IsTemplatized();
1066 	}
1067 
1068 	virtual Node* TemplateParameterAt(int index) const
1069 	{
1070 		return fChildNode->TemplateParameterAt(index);
1071 	}
1072 
1073 	virtual bool IsNoReturnValueFunction() const
1074 	{
1075 		return fChildNode->IsNoReturnValueFunction();
1076 	}
1077 
1078 	virtual object_type ObjectType() const
1079 	{
1080 		return fChildNode->ObjectType();
1081 	}
1082 
1083 	virtual prefix_type PrefixType() const
1084 	{
1085 		return fChildNode->PrefixType();
1086 	}
1087 
1088 	virtual TypeInfo Type() const
1089 	{
1090 		return TypeInfo(fChildNode->Type(), fCVQualifiers);
1091 	}
1092 
1093 private:
1094 	int		fCVQualifiers;
1095 };
1096 
1097 
1098 class TypeModifierNode : public DecoratingNode {
1099 public:
1100 	TypeModifierNode(type_modifier modifier, Node* child)
1101 		:
1102 		DecoratingNode(child),
1103 		fModifier(modifier)
1104 	{
1105 	}
1106 
1107 	virtual bool AddDecoration(NameBuffer& buffer,
1108 		const Node* stopDecorator) const
1109 	{
1110 		if (this == stopDecorator)
1111 			return true;
1112 
1113 		return fChildNode->AddDecoration(buffer, stopDecorator)
1114 			&& buffer.Append(kTypeModifierSuffixes[fModifier]);
1115 	}
1116 
1117 	virtual object_type ObjectType() const
1118 	{
1119 		return OBJECT_TYPE_DATA;
1120 	}
1121 
1122 	virtual TypeInfo Type() const
1123 	{
1124 		TypeInfo type = fChildNode->Type();
1125 		if (type.type == TYPE_CHAR
1126 			&& (type.cvQualifiers & CV_QUALIFIER_CONST) != 0) {
1127 			return TypeInfo(TYPE_CONST_CHAR_POINTER);
1128 		}
1129 
1130 		switch (fModifier) {
1131 			case TYPE_QUALIFIER_POINTER:
1132 				return TypeInfo(TYPE_POINTER);
1133 			case TYPE_QUALIFIER_REFERENCE:
1134 				return TypeInfo(TYPE_REFERENCE);
1135 			default:
1136 				return TypeInfo();
1137 		}
1138 	}
1139 
1140 private:
1141 	type_modifier	fModifier;
1142 };
1143 
1144 
1145 class VendorTypeModifierNode : public DecoratingNode {
1146 public:
1147 	VendorTypeModifierNode(Node* name, Node* child)
1148 		:
1149 		DecoratingNode(child),
1150 		fName(name)
1151 	{
1152 		fName->SetParent(this);
1153 	}
1154 
1155 	virtual bool AddDecoration(NameBuffer& buffer,
1156 		const Node* stopDecorator) const
1157 	{
1158 		if (this == stopDecorator)
1159 			return true;
1160 
1161 		return fChildNode->AddDecoration(buffer, stopDecorator)
1162 			&& buffer.Append(" ")
1163 			&& fName->GetName(buffer);
1164 	}
1165 
1166 	virtual object_type ObjectType() const
1167 	{
1168 		return OBJECT_TYPE_DATA;
1169 	}
1170 
1171 private:
1172 	Node*	fName;
1173 };
1174 
1175 
1176 class OperatorNode : public Node {
1177 public:
1178 	OperatorNode(const operator_info* info)
1179 		:
1180 		fInfo(info)
1181 	{
1182 		SetReferenceable(false);
1183 	}
1184 
1185 	virtual bool GetName(NameBuffer& buffer) const
1186 	{
1187 		return buffer.Append(
1188 				isalpha(fInfo->name[0]) ?  "operator " : "operator")
1189 			&& buffer.Append(fInfo->name);
1190 	}
1191 
1192 	virtual object_type ObjectType() const
1193 	{
1194 		return (fInfo->flags & OPERATOR_IS_MEMBER) != 0
1195 			? OBJECT_TYPE_METHOD_CLASS : OBJECT_TYPE_UNKNOWN;
1196 	}
1197 
1198 private:
1199 	const operator_info*	fInfo;
1200 };
1201 
1202 
1203 class VendorOperatorNode : public Node {
1204 public:
1205 	VendorOperatorNode(Node* name)
1206 		:
1207 		fName(name)
1208 	{
1209 		fName->SetParent(this);
1210 		SetReferenceable(false);
1211 	}
1212 
1213 	virtual bool GetName(NameBuffer& buffer) const
1214 	{
1215 		return buffer.Append("operator ")
1216 			&& fName->GetName(buffer);
1217 	}
1218 
1219 private:
1220 	Node*	fName;
1221 };
1222 
1223 
1224 class CastOperatorNode : public Node {
1225 public:
1226 	CastOperatorNode(Node* child)
1227 		:
1228 		fChildNode(child)
1229 	{
1230 		fChildNode->SetParent(this);
1231 	}
1232 
1233 	virtual bool GetName(NameBuffer& buffer) const
1234 	{
1235 		return buffer.Append("operator ") && fChildNode->GetName(buffer);
1236 	}
1237 
1238 	virtual bool IsNoReturnValueFunction() const
1239 	{
1240 		return true;
1241 	}
1242 
1243 	virtual object_type ObjectType() const
1244 	{
1245 		return OBJECT_TYPE_METHOD_OBJECT;
1246 	}
1247 
1248 private:
1249 	Node*	fChildNode;
1250 };
1251 
1252 
1253 class PrefixedNode : public Node {
1254 public:
1255 	PrefixedNode(Node* prefix, Node* node)
1256 		:
1257 		fPrefixNode(prefix),
1258 		fNode(node)
1259 	{
1260 		fPrefixNode->SetParent(this);
1261 		fNode->SetParent(this);
1262 	}
1263 
1264 	virtual bool GetName(NameBuffer& buffer) const
1265 	{
1266 		if (!fPrefixNode->GetName(buffer))
1267 			return false;
1268 
1269 		buffer.Append("::");
1270 		return fNode->GetName(buffer);
1271 	}
1272 
1273 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1274 	{
1275 		return beforeNode == fNode
1276 			? fPrefixNode->GetUnqualifiedNode(beforeNode)
1277 			: fNode->GetUnqualifiedNode(beforeNode);
1278 	}
1279 
1280 	virtual bool IsNoReturnValueFunction() const
1281 	{
1282 		return fNode->IsNoReturnValueFunction();
1283 	}
1284 
1285 	virtual object_type ObjectType() const
1286 	{
1287 		return fNode->ObjectType();
1288 	}
1289 
1290 	virtual prefix_type PrefixType() const
1291 	{
1292 		return PREFIX_UNKNOWN;
1293 	}
1294 
1295 private:
1296 	Node*	fPrefixNode;
1297 	Node*	fNode;
1298 };
1299 
1300 
1301 class ClonedNode : public ObjectNode {
1302 public:
1303 	ClonedNode(Node* clone, Node* node)
1304 		:
1305 		ObjectNode(NULL),
1306 		fNode(node),
1307 		fCloneNode(clone)
1308 	{
1309 		fNode->SetParent(this);
1310 		fCloneNode->SetParent(this);
1311 	}
1312 
1313 	virtual bool GetName(NameBuffer& buffer) const
1314 	{
1315 		if (!fNode->GetName(buffer))
1316 			return false;
1317 
1318 		buffer.Append(" [clone ");
1319 		if (!fCloneNode->GetName(buffer))
1320 			return false;
1321 		buffer.Append("]");
1322 		return true;
1323 	}
1324 
1325 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1326 	{
1327 		return beforeNode == fCloneNode
1328 			? fNode->GetUnqualifiedNode(beforeNode)
1329 			: fCloneNode->GetUnqualifiedNode(beforeNode);
1330 	}
1331 
1332 	virtual bool IsNoReturnValueFunction() const
1333 	{
1334 		return fNode->IsNoReturnValueFunction();
1335 	}
1336 
1337 	virtual object_type ObjectType() const
1338 	{
1339 		return fNode->ObjectType();
1340 	}
1341 
1342 	virtual prefix_type PrefixType() const
1343 	{
1344 		return PREFIX_UNKNOWN;
1345 	}
1346 
1347 private:
1348 	Node*	fNode;
1349 	Node*	fCloneNode;
1350 };
1351 
1352 
1353 typedef PrefixedNode DependentNameNode;
1354 
1355 
1356 class TemplateNode : public Node {
1357 public:
1358 	TemplateNode(Node* base)
1359 		:
1360 		fBase(base),
1361 		fFirstArgument(NULL),
1362 		fLastArgument(NULL)
1363 	{
1364 		fBase->SetParent(this);
1365 	}
1366 
1367 	void AddArgument(Node* child)
1368 	{
1369 		child->SetParent(this);
1370 
1371 		if (fLastArgument != NULL) {
1372 			fLastArgument->SetNext(child);
1373 			fLastArgument = child;
1374 		} else {
1375 			fFirstArgument = child;
1376 			fLastArgument = child;
1377 		}
1378 	}
1379 
1380 	virtual bool GetName(NameBuffer& buffer) const
1381 	{
1382 		if (!fBase->GetName(buffer))
1383 			return false;
1384 
1385 		buffer.Append("<");
1386 
1387 		Node* child = fFirstArgument;
1388 		while (child != NULL) {
1389 			if (child != fFirstArgument)
1390 				buffer.Append(", ");
1391 
1392 			if (!child->GetName(buffer))
1393 				return false;
1394 
1395 			child = child->Next();
1396 		}
1397 
1398 		// add a space between consecutive '>'
1399 		if (buffer.LastChar() == '>')
1400 			buffer.Append(" ");
1401 
1402 		return buffer.Append(">");
1403 	}
1404 
1405 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1406 	{
1407 		return fBase != beforeNode
1408 			? fBase->GetUnqualifiedNode(beforeNode) : this;
1409 	}
1410 
1411 	virtual bool IsTemplatized() const
1412 	{
1413 		return true;
1414 	}
1415 
1416 	virtual Node* TemplateParameterAt(int index) const
1417 	{
1418 		Node* child = fFirstArgument;
1419 		while (child != NULL) {
1420 			if (index == 0)
1421 				return child;
1422 			index--;
1423 			child = child->Next();
1424 		}
1425 
1426 		return NULL;
1427 	}
1428 
1429 	virtual bool IsNoReturnValueFunction() const
1430 	{
1431 		return fBase->IsNoReturnValueFunction();
1432 	}
1433 
1434 	virtual object_type ObjectType() const
1435 	{
1436 		return fBase->ObjectType();
1437 	}
1438 
1439 	virtual prefix_type PrefixType() const
1440 	{
1441 		return fBase->PrefixType();
1442 	}
1443 
1444 protected:
1445 	Node*	fBase;
1446 	Node*	fFirstArgument;
1447 	Node*	fLastArgument;
1448 };
1449 
1450 
1451 class MultiSubExpressionsNode : public Node {
1452 public:
1453 	MultiSubExpressionsNode()
1454 		:
1455 		fFirstSubExpression(NULL),
1456 		fLastSubExpression(NULL)
1457 	{
1458 	}
1459 
1460 	void AddSubExpression(Node* child)
1461 	{
1462 		child->SetParent(this);
1463 
1464 		if (fLastSubExpression != NULL) {
1465 			fLastSubExpression->SetNext(child);
1466 			fLastSubExpression = child;
1467 		} else {
1468 			fFirstSubExpression = child;
1469 			fLastSubExpression = child;
1470 		}
1471 	}
1472 
1473 protected:
1474 	Node*		fFirstSubExpression;
1475 	Node*		fLastSubExpression;
1476 };
1477 
1478 
1479 class CallNode : public MultiSubExpressionsNode {
1480 public:
1481 	CallNode()
1482 	{
1483 	}
1484 
1485 	virtual bool GetName(NameBuffer& buffer) const
1486 	{
1487 		// TODO: Use the real syntax!
1488 		buffer.Append("call(");
1489 
1490 		Node* child = fFirstSubExpression;
1491 		while (child != NULL) {
1492 			if (child != fFirstSubExpression)
1493 				buffer.Append(", ");
1494 
1495 			if (!child->GetName(buffer))
1496 				return false;
1497 
1498 			child = child->Next();
1499 		}
1500 
1501 		buffer.Append(")");
1502 
1503 		return true;
1504 	}
1505 };
1506 
1507 
1508 class OperatorExpressionNode : public MultiSubExpressionsNode {
1509 public:
1510 	OperatorExpressionNode(const operator_info* info)
1511 		:
1512 		fInfo(info)
1513 	{
1514 	}
1515 
1516 	virtual bool GetName(NameBuffer& buffer) const
1517 	{
1518 		bool isIdentifier = isalpha(fInfo->name[0]) || fInfo->name[0] == '_';
1519 
1520 		if (fInfo->argument_count == 1 || isIdentifier
1521 			|| fInfo->argument_count > 3
1522 			|| (fInfo->argument_count == 3 && strcmp(fInfo->name, "?") != 0)) {
1523 			// prefix operator
1524 			buffer.Append(fInfo->name);
1525 
1526 			if (isIdentifier)
1527 				buffer.Append("(");
1528 
1529 			Node* child = fFirstSubExpression;
1530 			while (child != NULL) {
1531 				if (child != fFirstSubExpression)
1532 					buffer.Append(", ");
1533 
1534 				if (!child->GetName(buffer))
1535 					return false;
1536 
1537 				child = child->Next();
1538 			}
1539 
1540 			if (isIdentifier)
1541 				buffer.Append(")");
1542 
1543 			return true;
1544 		}
1545 
1546 		Node* arg1 = fFirstSubExpression;
1547 		Node* arg2 = arg1->Next();
1548 
1549 		buffer.Append("(");
1550 
1551 		if (fInfo->argument_count == 2) {
1552 			// binary infix operator
1553 			if (!arg1->GetName(buffer))
1554 				return false;
1555 
1556 			buffer.Append(" ");
1557 			buffer.Append(fInfo->name);
1558 			buffer.Append(" ");
1559 
1560 			if (!arg2->GetName(buffer))
1561 				return false;
1562 
1563 			return buffer.Append(")");
1564 		}
1565 
1566 		Node* arg3 = arg2->Next();
1567 
1568 		if (fInfo->argument_count == 2) {
1569 			// trinary operator "... ? ... : ..."
1570 			if (!arg1->GetName(buffer))
1571 				return false;
1572 
1573 			buffer.Append(" ? ");
1574 
1575 			if (!arg2->GetName(buffer))
1576 				return false;
1577 
1578 			buffer.Append(" : ");
1579 
1580 			if (!arg3->GetName(buffer))
1581 				return false;
1582 
1583 			return buffer.Append(")");
1584 		}
1585 
1586 		return false;
1587 	}
1588 
1589 private:
1590 	const operator_info*	fInfo;
1591 };
1592 
1593 
1594 class ConversionExpressionNode : public MultiSubExpressionsNode {
1595 public:
1596 	ConversionExpressionNode(Node* type)
1597 		:
1598 		fType(type)
1599 	{
1600 		fType->SetParent(this);
1601 	}
1602 
1603 	virtual bool GetName(NameBuffer& buffer) const
1604 	{
1605 		buffer.Append("(");
1606 
1607 		if (!fType->GetName(buffer))
1608 			return false;
1609 
1610 		buffer.Append(")(");
1611 
1612 		Node* child = fFirstSubExpression;
1613 		while (child != NULL) {
1614 			if (child != fFirstSubExpression)
1615 				buffer.Append(", ");
1616 
1617 			if (!child->GetName(buffer))
1618 				return false;
1619 
1620 			child = child->Next();
1621 		}
1622 
1623 		return buffer.Append(")");
1624 	}
1625 
1626 private:
1627 	Node*	fType;
1628 };
1629 
1630 
1631 class PointerToMemberNode : public DecoratingNode {
1632 public:
1633 	PointerToMemberNode(Node* classType, Node* memberType)
1634 		:
1635 		DecoratingNode(memberType),
1636 		fClassType(classType)
1637 	{
1638 		fClassType->SetParent(this);
1639 	}
1640 
1641 	virtual bool AddDecoration(NameBuffer& buffer,
1642 		const Node* stopDecorator) const
1643 	{
1644 		if (this == stopDecorator)
1645 			return true;
1646 
1647 		if (!fChildNode->AddDecoration(buffer, stopDecorator))
1648 			return false;
1649 
1650 		// In most cases we need a space before the name. In some it is
1651 		// superfluous, though.
1652 		if (!buffer.IsEmpty() && buffer.LastChar() != '(')
1653 			buffer.Append(" ");
1654 
1655 		if (!fClassType->GetName(buffer))
1656 			return false;
1657 
1658 		return buffer.Append("::*");
1659 	}
1660 
1661 	virtual object_type ObjectType() const
1662 	{
1663 		return OBJECT_TYPE_DATA;
1664 	}
1665 
1666 	virtual TypeInfo Type() const
1667 	{
1668 		// TODO: Method pointers aren't ordinary pointers. Though we might not
1669 		// be able to determine the difference.
1670 		return TypeInfo(TYPE_POINTER);
1671 	}
1672 
1673 
1674 private:
1675 	Node*	fClassType;
1676 };
1677 
1678 
1679 class FunctionNode : public ObjectNode {
1680 public:
1681 	FunctionNode(Node* nameNode, bool hasReturnType, bool isExternC)
1682 		:
1683 		ObjectNode(nameNode),
1684 		fFirstTypeNode(NULL),
1685 		fLastTypeNode(NULL),
1686 		fHasReturnType(hasReturnType),
1687 		fIsExternC(isExternC)
1688 	{
1689 	}
1690 
1691 	void AddType(Node* child)
1692 	{
1693 		child->SetParent(this);
1694 
1695 		if (fLastTypeNode != NULL) {
1696 			fLastTypeNode->SetNext(child);
1697 			fLastTypeNode = child;
1698 		} else {
1699 			fFirstTypeNode = child;
1700 			fLastTypeNode = child;
1701 		}
1702 	}
1703 
1704 	virtual bool GetName(NameBuffer& buffer) const
1705 	{
1706 		NameDecorationInfo decorationInfo(NULL);
1707 		return GetDecoratedName(buffer, decorationInfo);
1708 	}
1709 
1710 	virtual bool GetDecoratedName(NameBuffer& buffer,
1711 		NameDecorationInfo& decorationInfo) const
1712 	{
1713 		// write 'extern "C"'
1714 //		if (fIsExternC)
1715 //			buffer.Append("extern \"C\"");
1716 
1717 		// write the return type
1718 		Node* child = fFirstTypeNode;
1719 		if (_HasReturnType() && child != NULL) {
1720 			if (!child->GetName(buffer))
1721 				return false;
1722 			child = child->Next();
1723 
1724 			buffer.Append(" ", 1);
1725 		}
1726 
1727 		// write the function name
1728 		if (fName == NULL)
1729 			buffer.Append("(", 1);
1730 
1731 		CVQualifierInfo info;
1732 		if (fName != NULL) {
1733 			// skip CV qualifiers on our name -- we'll add them later
1734 			fName->GetCVQualifierInfo(info);
1735 			if (info.firstNonCVQualifier != NULL
1736 				&& !info.firstNonCVQualifier->GetName(buffer)) {
1737 				return false;
1738 			}
1739 		}
1740 
1741 		// add non-CV qualifier decorations
1742 		if (decorationInfo.firstDecorator != NULL) {
1743 			if (!decorationInfo.firstDecorator->AddDecoration(buffer,
1744 				decorationInfo.closestCVDecoratorList)) {
1745 				return false;
1746 			}
1747 		}
1748 
1749 		if (fName == NULL)
1750 			buffer.Append(")", 1);
1751 
1752 		// add the parameter types
1753 		buffer.Append("(");
1754 
1755 		// don't add a single "void" parameter
1756 		if (child != NULL && child->Next() == NULL
1757 			&& child->IsTypeName("void", 4)) {
1758 			child = NULL;
1759 		}
1760 
1761 		Node* firstParam = child;
1762 		while (child != NULL) {
1763 			if (child != firstParam)
1764 				buffer.Append(", ");
1765 
1766 			if (!child->GetName(buffer))
1767 				return false;
1768 
1769 			child = child->Next();
1770 		}
1771 
1772 		buffer.Append(")");
1773 
1774 		// add CV qualifiers on our name
1775 		if (info.firstCVQualifier != NULL) {
1776 			if (!info.firstCVQualifier->AddDecoration(buffer,
1777 					info.firstNonCVQualifier)) {
1778 				return false;
1779 			}
1780 		}
1781 
1782 		// add CV qualifiers on us
1783 		if (decorationInfo.closestCVDecoratorList != NULL)
1784 			decorationInfo.closestCVDecoratorList->AddDecoration(buffer, NULL);
1785 
1786 		return true;
1787 	}
1788 
1789 	virtual object_type ObjectType() const
1790 	{
1791 		// no name, no fun
1792 		if (fName == NULL)
1793 			return OBJECT_TYPE_FUNCTION;
1794 
1795 		// check our name's prefix
1796 		switch (fName->PrefixType()) {
1797 			case PREFIX_NONE:
1798 			case PREFIX_NAMESPACE:
1799 				return OBJECT_TYPE_FUNCTION;
1800 			case PREFIX_CLASS:
1801 			case PREFIX_UNKNOWN:
1802 				break;
1803 		}
1804 
1805 		// Our name has a prefix, but we don't know, whether it is a class or
1806 		// namespace. Let's ask our name what it thinks it is.
1807 		object_type type = fName->ObjectType();
1808 		switch (type) {
1809 			case OBJECT_TYPE_FUNCTION:
1810 			case OBJECT_TYPE_METHOD_CLASS:
1811 			case OBJECT_TYPE_METHOD_OBJECT:
1812 			case OBJECT_TYPE_METHOD_UNKNOWN:
1813 				// That's as good as it gets.
1814 				return type;
1815 			case OBJECT_TYPE_UNKNOWN:
1816 			case OBJECT_TYPE_DATA:
1817 			default:
1818 				// Obviously our name doesn't have a clue.
1819 				return OBJECT_TYPE_METHOD_UNKNOWN;
1820 		}
1821 	}
1822 
1823 	virtual Node* ParameterAt(uint32 index) const
1824 	{
1825 		// skip return type
1826 		Node* child = fFirstTypeNode;
1827 		if (_HasReturnType() && child != NULL)
1828 			child = child->Next();
1829 
1830 		// ignore a single "void" parameter
1831 		if (child != NULL && child->Next() == NULL
1832 			&& child->IsTypeName("void", 4)) {
1833 			return NULL;
1834 		}
1835 
1836 		// get the type at the index
1837 		while (child != NULL && index > 0) {
1838 			child = child->Next();
1839 			index--;
1840 		}
1841 
1842 		return child;
1843 	}
1844 
1845 private:
1846 	bool _HasReturnType() const
1847 	{
1848 		return fHasReturnType
1849 			|| fName == NULL
1850 			|| (fName->IsTemplatized() && !fName->IsNoReturnValueFunction());
1851 	}
1852 
1853 private:
1854 	Node*		fFirstTypeNode;
1855 	Node*		fLastTypeNode;
1856 	bool		fHasReturnType;
1857 	bool		fIsExternC;
1858 };
1859 
1860 
1861 // #pragma mark - Demangler
1862 
1863 
1864 class Demangler {
1865 public:
1866 								Demangler();
1867 
1868 			int					Demangle(const char* mangledName, char* buffer,
1869 									size_t size,
1870 									DemanglingInfo& demanglingInfo);
1871 			int					GetParameterInfo(const char* mangledName,
1872 									uint32 index, char* buffer, size_t size,
1873 									ParameterInfo& info);
1874 
1875 	// actually private, but public to make gcc 2 happy
1876 	inline	bool				_SetError(int error);
1877 	inline	void				_AddAllocatedNode(Node* node);
1878 
1879 private:
1880 	template<typename NodeType> struct NodeCreator;
1881 
1882 	inline	bool				_SkipExpected(char c);
1883 	inline	bool				_SkipExpected(const char* string);
1884 
1885 			void				_Init();
1886 			void				_Cleanup();
1887 
1888 			int					_Demangle(const char* mangledName, char* buffer,
1889 									size_t size,
1890 									DemanglingInfo& demanglingInfo);
1891 			int					_GetParameterInfo(const char* mangledName,
1892 									uint32 index, char* buffer, size_t size,
1893 									ParameterInfo& info);
1894 
1895 			int					_Parse(const char* mangledName,
1896 									const char*& versionSuffix,
1897 									ObjectNode*& _node);
1898 
1899 			bool				_ParseClone(ObjectNode*& _node);
1900 			bool				_ParseEncoding(ObjectNode*& _node);
1901 			bool				_ParseSpecialName(Node*& _node);
1902 			bool				_ParseCallOffset(bool& nonVirtual,
1903 									number_type& offset1, number_type& offset2);
1904 			bool				_ParseName(Node*& _node);
1905 			bool				_ParseNestedName(Node*& _node);
1906 			bool				_ParseNestedNameInternal(Node*& _node);
1907 			bool				_ParseLocalName(Node*& _node);
1908 			bool				_ParseUnqualifiedName(Node*& _node);
1909 			bool				_ParseSourceName(Node*& _node);
1910 			bool				_ParseOperatorName(Node*& _node);
1911 			bool				_ParseType(Node*& _node);
1912 			bool				_ParseTypeInternal(Node*& _node);
1913 			void				_ParseCVQualifiers(int& qualifiers);
1914 			bool				_ParseTypeWithModifier(type_modifier modifier,
1915 									int toSkip, Node*& _node);
1916 			bool				_TryParseBuiltinType(Node*& _node);
1917 			bool				_ParseFunctionType(FunctionNode*& _node);;
1918 			bool				_ParseArrayType(Node*& _node);
1919 			bool				_ParsePointerToMemberType(Node*& _node);
1920 			bool				_ParseTemplateParam(Node*& _node);
1921 			bool				_ParseSubstitution(Node*& _node);
1922 			bool				_ParseSubstitutionInternal(Node*& _node);
1923 			bool				_ParseBareFunctionType(FunctionNode* node);
1924 			bool				_ParseTemplateArgs(Node* node, Node*& _node);
1925 			bool				_ParseTemplateArg(Node*& _node);
1926 			bool				_ParseExpression(Node*& _node);
1927 			bool				_ParseExpressionPrimary(Node*& _node);
1928 			bool				_ParseNumber(number_type& number);
1929 
1930 			bool				_CreateNodeAndSkip(const char* name,
1931 									size_t length, int toSkip, Node*& _node);
1932 			bool				_CreateNodeAndSkip(const char* name, int toSkip,
1933 									Node*& _node);
1934 			bool				_CreateTypeNodeAndSkip(type_type type,
1935 									int toSkip, Node*& _node);
1936 			bool				_CreateTypeNodeAndSkip(const char* name,
1937 									const char* prefix,
1938 									const char* templateArgs, int toSkip,
1939 									Node*& _node);
1940 
1941 			void				_RegisterReferenceableNode(Node* node);
1942 			bool				_CreateSubstitutionNode(int index,
1943 									Node*& _node);
1944 
1945 private:
1946 			Input				fInput;
1947 			int					fError;
1948 			Node*				fAllocatedNodes;
1949 			Node*				fFirstReferenceableNode;
1950 			Node*				fLastReferenceableNode;
1951 			Node*				fTemplatizedNode;
1952 };
1953 
1954 
1955 template<typename NodeType>
1956 struct Demangler::NodeCreator {
1957 	NodeCreator(Demangler* demangler)
1958 		:
1959 		fDemangler(demangler)
1960 	{
1961 	}
1962 
1963 	template<typename ReturnType>
1964 	inline bool operator()(ReturnType*& _node) const
1965 	{
1966 		_node = NEW(NodeType);
1967 		if (_node == NULL)
1968 			return fDemangler->_SetError(ERROR_NO_MEMORY);
1969 
1970 		fDemangler->_AddAllocatedNode(_node);
1971 		return true;
1972 	}
1973 
1974 	template<typename ParameterType1, typename ReturnType>
1975 	inline bool operator()(ParameterType1 arg1, ReturnType*& _node) const
1976 	{
1977 		_node = NEW(NodeType(arg1));
1978 		if (_node == NULL)
1979 			return fDemangler->_SetError(ERROR_NO_MEMORY);
1980 
1981 		fDemangler->_AddAllocatedNode(_node);
1982 		return true;
1983 	}
1984 
1985 	template<typename ParameterType1, typename ParameterType2,
1986 		typename ReturnType>
1987 	inline bool operator()(ParameterType1 arg1, ParameterType2 arg2,
1988 		ReturnType*& _node) const
1989 	{
1990 		_node = NEW(NodeType(arg1, arg2));
1991 		if (_node == NULL)
1992 			return fDemangler->_SetError(ERROR_NO_MEMORY);
1993 
1994 		fDemangler->_AddAllocatedNode(_node);
1995 		return true;
1996 	}
1997 
1998 	template<typename ParameterType1, typename ParameterType2,
1999 		typename ParameterType3, typename ReturnType>
2000 	inline bool operator()(ParameterType1 arg1, ParameterType2 arg2,
2001 		ParameterType3 arg3, ReturnType*& _node) const
2002 	{
2003 		_node = NEW(NodeType(arg1, arg2, arg3));
2004 		if (_node == NULL)
2005 			return fDemangler->_SetError(ERROR_NO_MEMORY);
2006 
2007 		fDemangler->_AddAllocatedNode(_node);
2008 		return true;
2009 	}
2010 
2011 private:
2012 		Demangler*	fDemangler;
2013 };
2014 
2015 
2016 inline bool
2017 Demangler::_SetError(int error)
2018 {
2019 	if (fError == ERROR_OK) {
2020 		fError = error;
2021 #ifdef TRACE_GCC3_DEMANGLER
2022 		DebugScope::Print("_SetError(): %d, remaining input: \"%s\"\n",
2023 			error, fInput.String());
2024 #endif
2025 	}
2026 	return false;
2027 }
2028 
2029 
2030 inline void
2031 Demangler::_AddAllocatedNode(Node* node)
2032 {
2033 	node->SetNextAllocated(fAllocatedNodes);
2034 	fAllocatedNodes = node;
2035 }
2036 
2037 
2038 inline bool
2039 Demangler::_SkipExpected(char c)
2040 {
2041 	return fInput.SkipPrefix(c) || _SetError(ERROR_INVALID);
2042 }
2043 
2044 
2045 inline bool
2046 Demangler::_SkipExpected(const char* string)
2047 {
2048 	return fInput.SkipPrefix(string) || _SetError(ERROR_INVALID);
2049 }
2050 
2051 
2052 Demangler::Demangler()
2053 	:
2054 	fInput(),
2055 	fAllocatedNodes(NULL)
2056 {
2057 }
2058 
2059 
2060 int
2061 Demangler::Demangle(const char* mangledName, char* buffer, size_t size,
2062 	DemanglingInfo& demanglingInfo)
2063 {
2064 	DEBUG_SCOPE("Demangle");
2065 
2066 	_Init();
2067 
2068 	int result = _Demangle(mangledName, buffer, size, demanglingInfo);
2069 
2070 	_Cleanup();
2071 
2072 	return result;
2073 }
2074 
2075 
2076 int
2077 Demangler::GetParameterInfo(const char* mangledName, uint32 index, char* buffer,
2078 	size_t size, ParameterInfo& info)
2079 {
2080 	DEBUG_SCOPE("GetParameterInfo");
2081 
2082 	_Init();
2083 
2084 	int result = _GetParameterInfo(mangledName, index, buffer, size, info);
2085 
2086 	_Cleanup();
2087 
2088 	return result;
2089 }
2090 
2091 
2092 void
2093 Demangler::_Init()
2094 {
2095 	fError = ERROR_OK;
2096 
2097 	fFirstReferenceableNode = NULL;
2098 	fLastReferenceableNode = NULL;
2099 	fAllocatedNodes = NULL;
2100 	fTemplatizedNode = NULL;
2101 }
2102 
2103 
2104 void
2105 Demangler::_Cleanup()
2106 {
2107 	while (fAllocatedNodes != NULL) {
2108 		Node* node = fAllocatedNodes;
2109 		fAllocatedNodes = node->NextAllocated();
2110 		DELETE(node);
2111 	}
2112 }
2113 
2114 
2115 int
2116 Demangler::_Demangle(const char* mangledName, char* buffer, size_t size,
2117 	DemanglingInfo& demanglingInfo)
2118 {
2119 	// parse the name
2120 	const char* versionSuffix;
2121 	ObjectNode* node;
2122 	int error = _Parse(mangledName, versionSuffix, node);
2123 	if (error != ERROR_OK)
2124 		return error;
2125 
2126 	NameBuffer nameBuffer(buffer, size);
2127 	bool success = node->GetObjectName(nameBuffer, demanglingInfo);
2128 
2129 	// If versioned, append the unmodified version string
2130 	if (success && versionSuffix != NULL)
2131 		nameBuffer.Append(versionSuffix);
2132 
2133 	if (nameBuffer.HadOverflow())
2134 		return ERROR_BUFFER_TOO_SMALL;
2135 
2136 	if (!success)
2137 		return ERROR_INTERNAL;
2138 
2139 	demanglingInfo.objectType = node->ObjectType();
2140 
2141 	nameBuffer.Terminate();
2142 	return ERROR_OK;
2143 }
2144 
2145 
2146 int
2147 Demangler::_GetParameterInfo(const char* mangledName, uint32 index,
2148 	char* buffer, size_t size, ParameterInfo& info)
2149 {
2150 	// parse the name
2151 	const char* versionSuffix;
2152 	ObjectNode* node;
2153 	int error = _Parse(mangledName, versionSuffix, node);
2154 	if (error != ERROR_OK)
2155 		return error;
2156 
2157 	// get the parameter node
2158 	Node* parameter = node->ParameterAt(index);
2159 	if (parameter == NULL)
2160 		return ERROR_INVALID_PARAMETER_INDEX;
2161 
2162 	// get the parameter name
2163 	NameBuffer nameBuffer(buffer, size);
2164 	bool success = parameter->GetName(nameBuffer);
2165 
2166 	if (nameBuffer.HadOverflow())
2167 		return ERROR_BUFFER_TOO_SMALL;
2168 
2169 	if (!success)
2170 		return ERROR_INTERNAL;
2171 
2172 	nameBuffer.Terminate();
2173 
2174 	// get the type
2175 	info.type = parameter->Type();
2176 
2177 	return ERROR_OK;
2178 }
2179 
2180 
2181 int
2182 Demangler::_Parse(const char* mangledName, const char*& versionSuffix,
2183 	ObjectNode*& _node)
2184 {
2185 	// To support versioned symbols, we ignore the version suffix when
2186 	// demangling.
2187 	versionSuffix = strchr(mangledName, '@');
2188 	fInput.SetTo(mangledName,
2189 		versionSuffix != NULL
2190 			? versionSuffix - mangledName : strlen(mangledName));
2191 
2192 	// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
2193 
2194 	if (!fInput.SkipPrefix("_Z"))
2195 		return ERROR_NOT_MANGLED;
2196 
2197 	if (!_ParseEncoding(_node) || !_ParseClone(_node))
2198 		return fError;
2199 
2200 	if (fInput.CharsRemaining() != 0) {
2201 		// bogus at end of input
2202 		return ERROR_INVALID;
2203 	}
2204 
2205 	return ERROR_OK;
2206 }
2207 
2208 
2209 bool
2210 Demangler::_ParseClone(ObjectNode*& _node)
2211 {
2212 	DEBUG_SCOPE("_ParseClone");
2213 
2214 	while (fInput.HasPrefix('.')) {
2215 		int count = fInput.CharsRemaining();
2216 		int i = 1;
2217 		while (true) {
2218 			for (; i < count && fInput[i] != '.'; i++)
2219 				;
2220 			if (i + 1 >= count || fInput[i + 1] < '0' || fInput[i + 1] > '9')
2221 				break;
2222 			i++;
2223 		}
2224 		if (i == 1)
2225 			break;
2226 		Node* clone;
2227 		if (!_CreateNodeAndSkip(fInput.String(), i, i, clone))
2228 			return false;
2229 
2230 		if (!NodeCreator<ClonedNode>(this)(clone, _node, _node))
2231 			return false;
2232 	}
2233 	return true;
2234 }
2235 
2236 
2237 bool
2238 Demangler::_ParseEncoding(ObjectNode*& _node)
2239 {
2240 	DEBUG_SCOPE("_ParseEncoding");
2241 
2242 	// <encoding> ::= <function name> <bare-function-type>
2243 	//	          ::= <data name>
2244 	//	          ::= <special-name>
2245 
2246 	// NOTE: This is not in the specs: Local entities seem to be prefixed
2247 	// by an 'L'.
2248 	fInput.SkipPrefix('L');
2249 
2250 	// parse <special-name>, if it is one
2251 	Node* name;
2252 	if (fInput.HasPrefix('T') || fInput.HasPrefix("GV")) {
2253 		return _ParseSpecialName(name)
2254 			&& NodeCreator<ObjectNode>(this)(name, _node);
2255 	}
2256 
2257 	// either <data name> or <function name>
2258 	if (!_ParseName(name))
2259 		return false;
2260 
2261 	if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')
2262 		|| fInput.HasPrefix('.')) {
2263 		// <data name>
2264 		return NodeCreator<ObjectNode>(this)(name, _node);
2265 	}
2266 
2267 	// <function name> -- parse remaining <bare-function-type>
2268 	FunctionNode* functionNode;
2269 	if (!NodeCreator<FunctionNode>(this)(name, false, false, functionNode))
2270 		return false;
2271 	_node = functionNode;
2272 
2273 	// If our name is templatized, we push it onto the templatized node
2274 	// stack while parsing the function parameters.
2275 	Node* previousTemplatizedNode = fTemplatizedNode;
2276 	if (name->IsTemplatized())
2277 		fTemplatizedNode = name;
2278 
2279 	if (!_ParseBareFunctionType(functionNode))
2280 		return false;
2281 
2282 	fTemplatizedNode = previousTemplatizedNode;
2283 
2284 	return true;
2285 }
2286 
2287 
2288 bool
2289 Demangler::_ParseSpecialName(Node*& _node)
2290 {
2291 	DEBUG_SCOPE("_ParseSpecialName");
2292 
2293 	if (fInput.CharsRemaining() == 0)
2294 		return _SetError(ERROR_INVALID);
2295 
2296 	// <special-name> ::= GV <object name>	# Guard variable for one-time
2297 	//                                      # initialization
2298 	//                    # No <type>
2299 	if (!fInput.SkipPrefix('T')) {
2300 		Node* name;
2301 		return _SkipExpected("GV")
2302 			&& _ParseName(name)
2303 			&& NodeCreator<SpecialNameNode>(this)("guard variable for ",
2304 				name, _node);
2305 	}
2306 
2307 	// <special-name> ::= TV <type>	# virtual table
2308 	//                ::= TT <type>	# VTT structure (construction vtable
2309 	//                              # index)
2310 	//                ::= TI <type>	# typeinfo structure
2311 	//                ::= TS <type>	# typeinfo name (null-terminated byte
2312 	//                              # string)
2313 	const char* prefix = NULL;
2314 	switch (fInput[0]) {
2315 		case 'V':
2316 			prefix = "vtable for ";
2317 			break;
2318 		case 'T':
2319 			prefix = "VTT for ";
2320 			break;
2321 		case 'I':
2322 			prefix = "typeinfo for ";
2323 			break;
2324 		case 'S':
2325 			prefix = "typeinfo name for ";
2326 			break;
2327 	}
2328 
2329 	if (prefix != NULL) {
2330 		fInput.Skip(1);
2331 		Node* type;
2332 		return _ParseType(type)
2333 			&& NodeCreator<SpecialNameNode>(this)(prefix, type, _node);
2334 	}
2335 
2336 	// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
2337 	//                    # base is the nominal target function of thunk
2338 	//                    # first call-offset is 'this' adjustment
2339 	//                    # second call-offset is result adjustment
2340 	if (fInput.SkipPrefix('c')) {
2341 		bool nonVirtual;
2342 		number_type offset1;
2343 		number_type offset2;
2344 		ObjectNode* name;
2345 		return _ParseCallOffset(nonVirtual, offset1, offset2)
2346 			&& _ParseCallOffset(nonVirtual, offset1, offset2)
2347 			&& _ParseEncoding(name)
2348 			&& NodeCreator<SpecialNameNode>(this)(
2349 				"covariant return thunk to ", name, _node);
2350 	}
2351 
2352 	// <special-name> ::= T <call-offset> <base encoding>
2353 	//                    # base is the nominal target function of thunk
2354 	bool nonVirtual;
2355 	number_type offset1;
2356 	number_type offset2;
2357 	ObjectNode* name;
2358 	return _ParseCallOffset(nonVirtual, offset1, offset2)
2359 		&& _ParseEncoding(name)
2360 		&& NodeCreator<SpecialNameNode>(this)(
2361 			nonVirtual ? "non-virtual thunk to " : "virtual thunk to ",
2362 			name, _node);
2363 }
2364 
2365 
2366 bool
2367 Demangler::_ParseCallOffset(bool& nonVirtual, number_type& offset1,
2368 	number_type& offset2)
2369 {
2370 	// <call-offset> ::= h <nv-offset> _
2371 	//               ::= v <v-offset> _
2372 	// <nv-offset> ::= <offset number>
2373 	//                 # non-virtual base override
2374 	// <v-offset>  ::= <offset number> _ <virtual offset number>
2375 	//                 # virtual base override, with vcall offset
2376 
2377 	// non-virtual
2378 	if (fInput.SkipPrefix('h')) {
2379 		nonVirtual = true;
2380 		return _ParseNumber(offset1) && _SkipExpected('_');
2381 	}
2382 
2383 	// virtual
2384 	nonVirtual = false;
2385 	return _SkipExpected('v')
2386 		&& _ParseNumber(offset1)
2387 		&& _SkipExpected('_')
2388 		&& _ParseNumber(offset2)
2389 		&& _SkipExpected('_');
2390 }
2391 
2392 bool
2393 Demangler::_ParseName(Node*& _node)
2394 {
2395 	DEBUG_SCOPE("_ParseName");
2396 
2397 	if (fInput.CharsRemaining() == 0)
2398 		return _SetError(ERROR_INVALID);
2399 
2400 	// <name> ::= <nested-name>
2401 	//        ::= <unscoped-name>
2402 	//        ::= <unscoped-template-name> <template-args>
2403 	//        ::= <local-name>	# See Scope Encoding below
2404 	//
2405 	// <unscoped-name> ::= <unqualified-name>
2406 	//                 ::= St <unqualified-name>   # ::std::
2407 	//
2408 	// <unscoped-template-name> ::= <unscoped-name>
2409 	//                          ::= <substitution>
2410 
2411 	switch (fInput[0]) {
2412 		case 'N':
2413 			// <nested-name>
2414 			return _ParseNestedName(_node);
2415 		case 'Z':
2416 			// <local-name>
2417 			return _ParseLocalName(_node);
2418 		case 'S':
2419 		{
2420 			// <substitution>
2421 			if (!fInput.HasPrefix("St")) {
2422 				if (!_ParseSubstitution(_node))
2423 					return false;
2424 				break;
2425 			}
2426 
2427 			// std:: namespace
2428 			fInput.Skip(2);
2429 
2430 			Node* prefix;
2431 			if (!NodeCreator<SimpleNameNode>(this)("std", prefix))
2432 				return false;
2433 
2434 			// <unqualified-name>
2435 			Node* node;
2436 			if (!_ParseUnqualifiedName(node)
2437 				|| !NodeCreator<PrefixedNode>(this)(prefix, node, _node)) {
2438 				return false;
2439 			}
2440 
2441 			break;
2442 		}
2443 		default:
2444 			// <unqualified-name>
2445 			if (!_ParseUnqualifiedName(_node))
2446 				return false;
2447 			break;
2448 	}
2449 
2450 	// We get here for the names that might be an <unscoped-template-name>.
2451 	// Check whether <template-args> are following.
2452 	if (!fInput.HasPrefix('I'))
2453 		return true;
2454 
2455 	// <unscoped-template-name> is referenceable
2456 	_RegisterReferenceableNode(_node);
2457 
2458 	return _ParseTemplateArgs(_node, _node);
2459 }
2460 
2461 
2462 bool
2463 Demangler::_ParseNestedName(Node*& _node)
2464 {
2465 	DEBUG_SCOPE("_ParseNestedName");
2466 
2467 	// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
2468 	//               ::= N [<CV-qualifiers>] <template-prefix>
2469 	//                   <template-args> E
2470 	//
2471 	// <CV-qualifiers> ::= [r] [V] [K] 	# restrict (C99), volatile, const
2472 	//
2473 	// <prefix> ::= <prefix> <unqualified-name>
2474 	//          ::= <template-prefix> <template-args>
2475 	//          ::= <template-param>
2476 	//          ::= # empty
2477 	//          ::= <substitution>
2478 	//
2479 	// <template-prefix> ::= <prefix> <template unqualified-name>
2480 	//                   ::= <template-param>
2481 	//                   ::= <substitution>
2482 
2483 	if (!_SkipExpected('N'))
2484 		return false;
2485 
2486 	// parse CV qualifiers
2487 	int qualifiers;
2488 	_ParseCVQualifiers(qualifiers);
2489 
2490 	// parse the main part
2491 	if (!_ParseNestedNameInternal(_node))
2492 		return false;
2493 
2494 	// create a CV qualifiers wrapper node, if necessary
2495 	if (qualifiers != 0) {
2496 		return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node,
2497 			_node);
2498 	}
2499 
2500 	return true;
2501 }
2502 
2503 
2504 bool
2505 Demangler::_ParseNestedNameInternal(Node*& _node)
2506 {
2507 	DEBUG_SCOPE("_ParseNestedNameMain");
2508 
2509 	if (fInput.CharsRemaining() == 0)
2510 		return _SetError(ERROR_INVALID);
2511 
2512 	// the initial prefix might be a template param or a substitution
2513 	Node* initialPrefixNode = NULL;
2514 	Node* prefixNode = NULL;
2515 	switch (fInput[0]) {
2516 		case 'T':	// <template-param>
2517 			if (!_ParseTemplateParam(initialPrefixNode))
2518 				return false;
2519 
2520 			// a <prefix> or <template-prefix> and as such referenceable
2521 			_RegisterReferenceableNode(initialPrefixNode);
2522 			break;
2523 
2524 		case 'S':	// <substitution>
2525 			if (!_ParseSubstitution(initialPrefixNode))
2526 				return false;
2527 			break;
2528 	}
2529 
2530 	while (true) {
2531 		bool canTerminate = false;
2532 		Node* node;
2533 
2534 		if (initialPrefixNode != NULL) {
2535 			node = initialPrefixNode;
2536 			initialPrefixNode = NULL;
2537 		} else {
2538 			if (!_ParseUnqualifiedName(node))
2539 				return false;
2540 			canTerminate = true;
2541 		}
2542 
2543 		// join prefix and the new node
2544 		if (prefixNode != NULL) {
2545 			if (!NodeCreator<PrefixedNode>(this)(prefixNode, node, node))
2546 				return false;
2547 		}
2548 
2549 		// template arguments?
2550 		if (fInput.HasPrefix('I')) {
2551 			// <template-prefix> is referenceable
2552 			_RegisterReferenceableNode(node);
2553 
2554 			// parse the template arguments
2555 			if (!_ParseTemplateArgs(node, node))
2556 				return false;
2557 			canTerminate = true;
2558 		}
2559 
2560 		if (fInput.CharsRemaining() == 0)
2561 			return _SetError(ERROR_INVALID);
2562 
2563 		// end of nested name?
2564 		if (fInput.SkipPrefix('E')) {
2565 			// If it doesn't have template args, it must end in an
2566 			// unqualified name.
2567 			if (!canTerminate)
2568 				return _SetError(ERROR_INVALID);
2569 
2570 			_node = node;
2571 			return true;
2572 		}
2573 
2574 		// The fun continues, so this is a <prefix> or <template-prefix>
2575 		// and as such referenceable.
2576 		prefixNode = node;
2577 		_RegisterReferenceableNode(node);
2578 	}
2579 }
2580 
2581 
2582 bool
2583 Demangler::_ParseLocalName(Node*& _node)
2584 {
2585 	DEBUG_SCOPE("_ParseLocalName");
2586 
2587 	// <local-name> := Z <function encoding> E <entity name>
2588 	//                 [<discriminator>]
2589 	//              := Z <function encoding> E s [<discriminator>]
2590 	// <discriminator> := _ <non-negative number>
2591 
2592 	// parse the function name
2593 	ObjectNode* functionName;
2594 	if (!_SkipExpected('Z')
2595 		|| !_ParseEncoding(functionName)
2596 		|| !_SkipExpected('E')) {
2597 		return false;
2598 	}
2599 
2600 	Node* entityName;
2601 	if (fInput.SkipPrefix('s')) {
2602 		// string literal
2603 		if (!NodeCreator<SimpleNameNode>(this)("string literal",
2604 				entityName)) {
2605 			return false;
2606 		}
2607 	} else {
2608 		// local type or object
2609 		if (!_ParseName(entityName))
2610 			return false;
2611 	}
2612 
2613 	// parse discriminator
2614 	number_type discriminator = 0;
2615 	if (fInput.SkipPrefix('_')) {
2616 		if (!_ParseNumber(discriminator))
2617 			return false;
2618 		if (discriminator < 0)
2619 			return _SetError(ERROR_INVALID);
2620 		discriminator++;
2621 	}
2622 
2623 	return NodeCreator<PrefixedNode>(this)(functionName, entityName, _node);
2624 }
2625 
2626 
2627 bool
2628 Demangler::_ParseUnqualifiedName(Node*& _node)
2629 {
2630 	DEBUG_SCOPE("_ParseUnqualifiedName");
2631 
2632 	// <unqualified-name> ::= <operator-name>
2633 	//                    ::= <ctor-dtor-name>
2634 	//                    ::= <source-name>
2635 	//
2636 	// <source-name> ::= <positive length number> <identifier>
2637 	// <number> ::= [n] <non-negative decimal integer>
2638 	// <identifier> ::= <unqualified source code identifier>
2639 	//
2640 	// <ctor-dtor-name> ::= C1	# complete object constructor
2641 	//                  ::= C2	# base object constructor
2642 	//                  ::= C3	# complete object allocating constructor
2643 	//                  ::= D0	# deleting destructor
2644 	//                  ::= D1	# complete object destructor
2645 	//                  ::= D2	# base object destructor
2646 
2647 	// we need at least 2 chars
2648 	if (fInput.CharsRemaining() < 2)
2649 		return _SetError(ERROR_INVALID);
2650 
2651 	if (isdigit(fInput[0]) || (fInput[0] == 'n' && isdigit(fInput[1]))) {
2652 		// <source-name>
2653 		return _ParseSourceName(_node);
2654 	}
2655 
2656 	if (fInput[0] == 'C') {
2657 		// <ctor-dtor-name> -- constructors
2658 		switch (fInput[1]) {
2659 			case '1':
2660 			case '2':
2661 			case '3':
2662 				if (!NodeCreator<XtructorNode>(this)(true, fInput[1] - '1',
2663 						_node)) {
2664 					return false;
2665 				}
2666 
2667 				fInput.Skip(2);
2668 				return true;
2669 			default:
2670 				return _SetError(ERROR_INVALID);
2671 		}
2672 	}
2673 
2674 	if (fInput[0] == 'D') {
2675 		// <ctor-dtor-name> -- destructors
2676 		switch (fInput[1]) {
2677 			case '0':
2678 			case '1':
2679 			case '2':
2680 				if (!NodeCreator<XtructorNode>(this)(false, fInput[1] - '0',
2681 						_node)) {
2682 					return false;
2683 				}
2684 
2685 				fInput.Skip(2);
2686 				return true;
2687 			default:
2688 				return _SetError(ERROR_INVALID);
2689 		}
2690 	}
2691 
2692 	// must be an <operator-name>
2693 	return _ParseOperatorName(_node);
2694 }
2695 
2696 
2697 bool
2698 Demangler::_ParseSourceName(Node*& _node)
2699 {
2700 	DEBUG_SCOPE("_ParseSourceName");
2701 
2702 	if (fInput.CharsRemaining() == 0)
2703 		return _SetError(ERROR_INVALID);
2704 
2705 	number_type number;
2706 	if (!_ParseNumber(number))
2707 		return false;
2708 
2709 	if (number <= 0 || number > fInput.CharsRemaining())
2710 		return _SetError(ERROR_INVALID);
2711 
2712 	return _CreateNodeAndSkip(fInput.String(), number, number, _node);
2713 }
2714 
2715 
2716 bool
2717 Demangler::_ParseOperatorName(Node*& _node)
2718 {
2719 	DEBUG_SCOPE("_ParseOperatorName");
2720 
2721 	if (fInput.CharsRemaining() < 2)
2722 		return _SetError(ERROR_INVALID);
2723 
2724 	const operator_info* info = NULL;
2725 	for (int i = 0; kOperatorInfos[i].name != NULL; i++) {
2726 		if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) {
2727 			info = &kOperatorInfos[i];
2728 			break;
2729 		}
2730 	}
2731 
2732 	if (info != NULL)
2733 		return NodeCreator<OperatorNode>(this)(info, _node);
2734 
2735 	// <operator-name> ::= cv <type>	# (cast)
2736 	if (fInput.SkipPrefix("cv")) {
2737 		Node* typeNode;
2738 		if (!_ParseType(typeNode))
2739 			return false;
2740 
2741 		return NodeCreator<CastOperatorNode>(this)(typeNode, _node);
2742 	}
2743 
2744 	//  <operator-name> ::= v <digit> <source-name>	# vendor extended
2745 	//                                                operator
2746 	if (fInput.SkipPrefix('v')) {
2747 		if (fInput.CharsRemaining() == 0 || !isdigit(fInput[0]))
2748 			return _SetError(ERROR_INVALID);
2749 		fInput.Skip(1);
2750 
2751 		Node* name;
2752 		return _ParseSourceName(name)
2753 			&& NodeCreator<VendorOperatorNode>(this)(name, _node);
2754 	}
2755 
2756 	return _SetError(ERROR_INVALID);
2757 }
2758 
2759 
2760 bool
2761 Demangler::_ParseType(Node*& _node)
2762 {
2763 	DEBUG_SCOPE("_ParseType");
2764 
2765 	if (!_ParseTypeInternal(_node))
2766 		return false;
2767 
2768 	_RegisterReferenceableNode(_node);
2769 	return true;
2770 }
2771 
2772 
2773 bool
2774 Demangler::_ParseTypeInternal(Node*& _node)
2775 {
2776 	DEBUG_SCOPE("_ParseTypeInternal");
2777 
2778 	// <type> ::= <builtin-type>
2779 	//        ::= <function-type>
2780 	//        ::= <class-enum-type>
2781 	//        ::= <array-type>
2782 	//        ::= <pointer-to-member-type>
2783 	//        ::= <template-param>
2784 	//        ::= <template-template-param> <template-args>
2785 	//        ::= <substitution> # See Compression below
2786 	//
2787 	// <template-template-param> ::= <template-param>
2788 	//                           ::= <substitution>
2789 	//
2790 	// <type> ::= <CV-qualifiers> <type>
2791 	//        ::= P <type>	# pointer-to
2792 	//        ::= R <type>	# reference-to
2793 	//        ::= O <type>	# rvalue reference-to (C++0x)
2794 	//        ::= C <type>	# complex pair (C 2000)
2795 	//        ::= G <type>	# imaginary (C 2000)
2796 	//        ::= U <source-name> <type>	# vendor extended type qualifier
2797 	//
2798 	// <CV-qualifiers> ::= [r] [V] [K] 	# restrict (C99), volatile, const
2799 	//
2800 	// <type>  ::= Dp <type>          # pack expansion of (C++0x)
2801 	//         ::= Dt <expression> E  # decltype of an id-expression or
2802 	//                                # class member access (C++0x)
2803 	//         ::= DT <expression> E  # decltype of an expression (C++0x)
2804 
2805 	if (_TryParseBuiltinType(_node)) {
2806 		_node->SetReferenceable(false);
2807 		return true;
2808 	}
2809 	if (fError != ERROR_OK)
2810 		return false;
2811 
2812 	if (fInput.CharsRemaining() == 0)
2813 		return _SetError(ERROR_INVALID);
2814 
2815 	switch (fInput[0]) {
2816 		// function type
2817 		case 'F':
2818 		{
2819 			FunctionNode* functionNode;
2820 			if (!_ParseFunctionType(functionNode))
2821 				return false;
2822 			_node = functionNode;
2823 			return true;
2824 		}
2825 
2826 		// array type
2827 		case 'A':
2828 			return _ParseArrayType(_node);
2829 
2830 		// pointer to member type
2831 		case 'M':
2832 			return _ParsePointerToMemberType(_node);
2833 
2834 		// template param
2835 		case 'T':
2836 			if (!_ParseTemplateParam(_node))
2837 				return false;
2838 			break;
2839 
2840 		// CV qualifiers
2841 		case 'r':
2842 		case 'V':
2843 		case 'K':
2844 		{
2845 			// parse CV qualifiers
2846 			int qualifiers;
2847 			_ParseCVQualifiers(qualifiers);
2848 
2849 			// parse the type
2850 			if (!_ParseType(_node))
2851 				return false;
2852 
2853 			// create the wrapper node
2854 			return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node,
2855 				_node);
2856 		}
2857 
2858 		// pointer, reference, etc.
2859 		case 'P':
2860 			return _ParseTypeWithModifier(TYPE_QUALIFIER_POINTER, 1, _node);
2861 		case 'R':
2862 			return _ParseTypeWithModifier(TYPE_QUALIFIER_REFERENCE, 1,
2863 				_node);
2864 		case 'O':
2865 			return _ParseTypeWithModifier(
2866 				TYPE_QUALIFIER_RVALUE_REFERENCE, 1, _node);
2867 		case 'C':
2868 			return _ParseTypeWithModifier(TYPE_QUALIFIER_COMPLEX, 1, _node);
2869 		case 'G':
2870 			return _ParseTypeWithModifier(TYPE_QUALIFIER_IMAGINARY, 1,
2871 				_node);
2872 
2873 		// pack and decltype
2874 		case 'D':
2875 #if 0
2876 			if (fInput.CharsRemaining() < 2)
2877 				return _SetError(ERROR_INVALID);
2878 
2879 			switch(fInput[1]) {
2880 				case 'p':
2881 					fInput.Skip(2);
2882 					return _ParseType(_node);
2883 				case 't':
2884 				case 'T':
2885 				{
2886 					fInput.Skip(2);
2887 					Node* nameNode;
2888 					if (!_ParseExpression(nameNode))
2889 						return false;
2890 					if (!fInput.SkipPrefix('E'))
2891 						return ERROR_INVALID;
2892 				}
2893 			}
2894 #endif
2895 			// NOTE: Unsupported by the GNU demangler.
2896 			return _SetError(ERROR_UNSUPPORTED);
2897 
2898 		// vendor extended type qualifier
2899 		case 'U':
2900 			fInput.Skip(1);
2901 			Node* name;
2902 			Node* type;
2903 			return _ParseSourceName(name) && _ParseType(type)
2904 				&& NodeCreator<VendorTypeModifierNode>(this)(name, type,
2905 					_node);
2906 
2907 		// substitution
2908 		case 'S':
2909 			if (!fInput.HasPrefix("St")) {
2910 				if (!_ParseSubstitution(_node))
2911 					return false;
2912 				break;
2913 			}
2914 
2915 			// "St" -- the "std" namespace. The grammar is ambiguous here,
2916 			// since we could parse that as <substitution> or as
2917 			// <class-enum-type>. We assume the latter and fall through.
2918 
2919 		default:
2920 		{
2921 			// <class-enum-type> ::= <name>
2922 			Node* nameNode;
2923 			return _ParseName(nameNode)
2924 				&& NodeCreator<NamedTypeNode>(this)(nameNode, _node);
2925 		}
2926 	}
2927 
2928 	// We get here for the types that might be a <template-template-param>.
2929 	// Check whether <template-args> are following.
2930 	if (!fInput.HasPrefix('I'))
2931 		return true;
2932 
2933 	// <template-template-param> is referenceable
2934 	_RegisterReferenceableNode(_node);
2935 
2936 	return _ParseTemplateArgs(_node, _node);
2937 }
2938 
2939 
2940 void
2941 Demangler::_ParseCVQualifiers(int& qualifiers)
2942 {
2943 	qualifiers = 0;
2944 
2945 	if (fInput.SkipPrefix('r'))
2946 		qualifiers |= CV_QUALIFIER_RESTRICT;
2947 	if (fInput.SkipPrefix('V'))
2948 		qualifiers |= CV_QUALIFIER_VOLATILE;
2949 	if (fInput.SkipPrefix('K'))
2950 		qualifiers |= CV_QUALIFIER_CONST;
2951 }
2952 
2953 
2954 bool
2955 Demangler::_ParseTypeWithModifier(type_modifier modifier, int toSkip,
2956 	Node*& _node)
2957 {
2958 	if (toSkip > 0)
2959 		fInput.Skip(toSkip);
2960 
2961 	Node* node;
2962 	if (!_ParseType(node))
2963 		return false;
2964 
2965 	return NodeCreator<TypeModifierNode>(this)(modifier, node, _node);
2966 }
2967 
2968 
2969 bool
2970 Demangler::_TryParseBuiltinType(Node*& _node)
2971 {
2972 	DEBUG_SCOPE("_TryParseBuiltinType");
2973 
2974 	// <builtin-type> ::= v	# void
2975 	//                ::= w	# wchar_t
2976 	//                ::= b	# bool
2977 	//                ::= c	# char
2978 	//                ::= a	# signed char
2979 	//                ::= h	# unsigned char
2980 	//                ::= s	# short
2981 	//                ::= t	# unsigned short
2982 	//                ::= i	# int
2983 	//                ::= j	# unsigned int
2984 	//                ::= l	# long
2985 	//                ::= m	# unsigned long
2986 	//                ::= x	# long long, __int64
2987 	//                ::= y	# unsigned long long, __int64
2988 	//                ::= n	# __int128
2989 	//                ::= o	# unsigned __int128
2990 	//                ::= f	# float
2991 	//                ::= d	# double
2992 	//                ::= e	# long double, __float80
2993 	//                ::= g	# __float128
2994 	//                ::= z	# ellipsis
2995 	//                ::= Dd # IEEE 754r decimal floating point (64 bits)
2996 	//                ::= De # IEEE 754r decimal floating point (128 bits)
2997 	//                ::= Df # IEEE 754r decimal floating point (32 bits)
2998 	//                ::= Dh # IEEE 754r half-precision floating point
2999 	//                       # (16 bits)
3000 	//                ::= Di # char32_t
3001 	//                ::= Ds # char16_t
3002 	//                ::= u <source-name>	# vendor extended type
3003 
3004 	if (fInput.CharsRemaining() == 0)
3005 		return false;
3006 
3007 	switch (fInput[0]) {
3008 		case 'v':
3009 			return _CreateTypeNodeAndSkip(TYPE_VOID, 1, _node);
3010 		case 'w':
3011 			return _CreateTypeNodeAndSkip(TYPE_WCHAR_T, 1, _node);
3012 		case 'b':
3013 			return _CreateTypeNodeAndSkip(TYPE_BOOL, 1, _node);
3014 		case 'c':
3015 			return _CreateTypeNodeAndSkip(TYPE_CHAR, 1, _node);
3016 		case 'a':
3017 			return _CreateTypeNodeAndSkip(TYPE_SIGNED_CHAR, 1, _node);
3018 		case 'h':
3019 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_CHAR, 1, _node);
3020 		case 's':
3021 			return _CreateTypeNodeAndSkip(TYPE_SHORT, 1, _node);
3022 		case 't':
3023 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_SHORT, 1,
3024 				_node);
3025 		case 'i':
3026 			return _CreateTypeNodeAndSkip(TYPE_INT, 1, _node);
3027 		case 'j':
3028 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT, 1, _node);
3029 		case 'l':
3030 			return _CreateTypeNodeAndSkip(TYPE_LONG, 1, _node);
3031 		case 'm':
3032 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG, 1, _node);
3033 		case 'x':
3034 			return _CreateTypeNodeAndSkip(TYPE_LONG_LONG, 1, _node);
3035 		case 'y':
3036 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG_LONG, 1, _node);
3037 		case 'n':
3038 			return _CreateTypeNodeAndSkip(TYPE_INT128, 1, _node);
3039 		case 'o':
3040 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT128, 1, _node);
3041 		case 'f':
3042 			return _CreateTypeNodeAndSkip(TYPE_FLOAT, 1, _node);
3043 		case 'd':
3044 			return _CreateTypeNodeAndSkip(TYPE_DOUBLE, 1, _node);
3045 		case 'e':
3046 			return _CreateTypeNodeAndSkip(TYPE_LONG_DOUBLE, 1, _node);
3047 		case 'g':
3048 			return _CreateTypeNodeAndSkip(TYPE_FLOAT128, 1, _node);
3049 		case 'z':
3050 			return _CreateTypeNodeAndSkip(TYPE_ELLIPSIS, 1, _node);
3051 
3052 		case 'D':
3053 			if (fInput.CharsRemaining() < 2)
3054 				return false;
3055 
3056 			// TODO: Official names for the __dfloat*!
3057 			switch (fInput[1]) {
3058 				case 'd':
3059 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT64, 2, _node);
3060 				case 'e':
3061 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT128, 2, _node);
3062 				case 'f':
3063 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT32, 2, _node);
3064 				case 'h':
3065 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT16, 2, _node);
3066 				case 'i':
3067 					return _CreateTypeNodeAndSkip(TYPE_CHAR16_T, 2, _node);
3068 				case 's':
3069 					return _CreateTypeNodeAndSkip(TYPE_CHAR32_T, 2, _node);
3070 				default:
3071 					return false;
3072 			}
3073 
3074 		case 'u':
3075 		{
3076 			fInput.Skip(1);
3077 			Node* nameNode;
3078 			return _ParseSourceName(nameNode)
3079 				&& NodeCreator<NamedTypeNode>(this)(nameNode, _node);
3080 		}
3081 
3082 		default:
3083 			return false;
3084 	}
3085 }
3086 
3087 
3088 bool
3089 Demangler::_ParseFunctionType(FunctionNode*& _node)
3090 {
3091 	DEBUG_SCOPE("_ParseFunctionType");
3092 
3093 	// <function-type> ::= F [Y] <bare-function-type> E
3094 
3095 	if (!_SkipExpected('F'))
3096 		return false;
3097 
3098 	// is 'extern "C"'?
3099 	bool isExternC = fInput.SkipPrefix('Y');
3100 
3101 	// create function and parse function type
3102 	if (!NodeCreator<FunctionNode>(this)((Node*)NULL, true, isExternC,
3103 			_node)
3104 		|| !_ParseBareFunctionType(_node)) {
3105 		return false;
3106 	}
3107 
3108 	// skip terminating 'E'
3109 	return _SkipExpected('E');
3110 }
3111 
3112 
3113 bool
3114 Demangler::_ParseArrayType(Node*& _node)
3115 {
3116 	DEBUG_SCOPE("_ParseArrayType");
3117 
3118 	// <array-type> ::= A <positive dimension number> _ <element type>
3119 	//              ::= A [<dimension expression>] _ <element type>
3120 
3121 	if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('A'))
3122 		return _SetError(ERROR_INVALID);
3123 
3124 	number_type dimensionNumber;
3125 	Node* dimensionExpression = NULL;
3126 
3127 	// If it looks like a number, it must be the first production, otherwise
3128 	// the second one.
3129 	if (isdigit(fInput[0])
3130 		|| (fInput[0] == 'n' && fInput.CharsRemaining() >= 2
3131 			&& isdigit(fInput[1]))) {
3132 		if (!_ParseNumber(dimensionNumber))
3133 			return false;
3134 	} else {
3135 		if (!_ParseExpression(dimensionExpression))
3136 			return false;
3137 	}
3138 
3139 	// parse the type
3140 	Node* type;
3141 	if (!_SkipExpected('_') || !_ParseType(type))
3142 		return false;
3143 
3144 	// create the array node
3145 	return dimensionExpression != NULL
3146 		? NodeCreator<ArrayNode>(this)(type, dimensionExpression, _node)
3147 		: NodeCreator<ArrayNode>(this)(type, dimensionNumber, _node);
3148 }
3149 
3150 
3151 bool
3152 Demangler::_ParsePointerToMemberType(Node*& _node)
3153 {
3154 	DEBUG_SCOPE("_ParsePointerToMemberType");
3155 
3156 	// <pointer-to-member-type> ::= M <class type> <member type>
3157 	Node* classType;
3158 	Node* memberType;
3159 	return _SkipExpected('M')
3160 		&& _ParseType(classType)
3161 		&& _ParseType(memberType)
3162 		&& NodeCreator<PointerToMemberNode>(this)(classType, memberType,
3163 			_node);
3164 }
3165 
3166 
3167 bool
3168 Demangler::_ParseTemplateParam(Node*& _node)
3169 {
3170 	DEBUG_SCOPE("_ParseTemplateParam");
3171 
3172 	// <template-param> ::= T_	# first template parameter
3173 	//                  ::= T <parameter-2 non-negative number> _
3174 
3175 	if (!_SkipExpected('T'))
3176 		return false;
3177 	if (fTemplatizedNode == NULL)
3178 		return _SetError(ERROR_INVALID);
3179 
3180 	// get the index;
3181 	number_type index = 0;
3182 	if (!fInput.HasPrefix('_')) {
3183 		if (!_ParseNumber(index))
3184 			return false;
3185 
3186 		if (index < 0)
3187 			return _SetError(ERROR_INVALID);
3188 		index++;
3189 	}
3190 
3191 	if (!_SkipExpected('_'))
3192 		return false;
3193 
3194 	// get the parameter
3195 	Node* parameter = fTemplatizedNode->TemplateParameterAt(index);
3196 	if (parameter == NULL)
3197 		return _SetError(ERROR_INVALID);
3198 
3199 	// create a substitution node
3200 	return NodeCreator<SubstitutionNode>(this)(parameter, _node);
3201 }
3202 
3203 
3204 bool
3205 Demangler::_ParseSubstitution(Node*& _node)
3206 {
3207 	DEBUG_SCOPE("_ParseSubstitution");
3208 
3209 	if (!_ParseSubstitutionInternal(_node))
3210 		return false;
3211 
3212 	// substitutions are never referenceable
3213 	_node->SetReferenceable(false);
3214 
3215 	return true;
3216 }
3217 
3218 
3219 bool
3220 Demangler::_ParseSubstitutionInternal(Node*& _node)
3221 {
3222 	DEBUG_SCOPE("_ParseSubstitutionInternal");
3223 
3224 	// <substitution> ::= S <seq-id> _
3225 	//                ::= S_
3226 	//
3227 	// <substitution> ::= St # ::std::
3228 	// <substitution> ::= Sa # ::std::allocator
3229 	// <substitution> ::= Sb # ::std::basic_string
3230 	// <substitution> ::= Ss # ::std::basic_string < char,
3231 	//                         ::std::char_traits<char>,
3232 	//                         ::std::allocator<char> >
3233 	// <substitution> ::= Si # ::std::basic_istream<char,
3234 	//                             std::char_traits<char> >
3235 	// <substitution> ::= So # ::std::basic_ostream<char,
3236 	//                             std::char_traits<char> >
3237 	// <substitution> ::= Sd # ::std::basic_iostream<char,
3238 	//                             std::char_traits<char> >
3239 
3240 	if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('S'))
3241 		return _SetError(ERROR_INVALID);
3242 
3243 	switch (fInput[0]) {
3244 		case 't':
3245 			return _CreateNodeAndSkip("std", 1, _node);
3246 		case 'a':
3247 			return _CreateTypeNodeAndSkip("allocator", "std", NULL, 1,
3248 				_node);
3249 		case 'b':
3250 			return _CreateTypeNodeAndSkip("basic_string", "std", NULL, 1,
3251 				_node);
3252 		case 's':
3253 			return _CreateTypeNodeAndSkip("basic_string", "std",
3254 				"char, std::char_traits<char>, std::allocator<char>", 1,
3255 				_node);
3256 		case 'i':
3257 			return _CreateTypeNodeAndSkip("basic_istream", "std",
3258 				"char, std::char_traits<char>", 1, _node);
3259 		case 'o':
3260 			return _CreateTypeNodeAndSkip("basic_ostream", "std",
3261 				"char, std::char_traits<char>", 1, _node);
3262 		case 'd':
3263 			return _CreateTypeNodeAndSkip("basic_iostream", "std",
3264 				"char, std::char_traits<char>", 1, _node);
3265 		case '_':
3266 			fInput.Skip(1);
3267 			return _CreateSubstitutionNode(0, _node);
3268 	}
3269 
3270 	// parse <seq-id>
3271 	int seqID = 0;
3272 	int count = fInput.CharsRemaining();
3273 	int i = 0;
3274 	for (; i < count && fInput[i] != '_'; i++) {
3275 		char c = fInput[i];
3276 		if (isdigit(c))
3277 			seqID = seqID * 36 + (c - '0');
3278 		else if (c >= 'A' && c <= 'Z')
3279 			seqID = seqID * 36 + 10 + (c - 'A');
3280 		else
3281 			return _SetError(ERROR_INVALID);
3282 	}
3283 
3284 	if (i == count)
3285 		return _SetError(ERROR_INVALID);
3286 
3287 	// skip digits and '_'
3288 	fInput.Skip(i + 1);
3289 
3290 	return _CreateSubstitutionNode(seqID + 1, _node);
3291 }
3292 
3293 
3294 bool
3295 Demangler::_ParseBareFunctionType(FunctionNode* node)
3296 {
3297 	DEBUG_SCOPE("_ParseBareFunctionType");
3298 
3299 	// <bare-function-type> ::= <signature type>+
3300 	//     # types are possible return type, then parameter types
3301 
3302 	if (fInput.CharsRemaining() == 0)
3303 		return _SetError(ERROR_INVALID);
3304 
3305 	do {
3306 		Node* typeNode;
3307 		if (!_ParseType(typeNode))
3308 			return false;
3309 
3310 		node->AddType(typeNode);
3311 	} while (fInput.CharsRemaining() > 0 && fInput[0] != 'E'
3312 		&& fInput[0] != '.');
3313 		// 'E' und '.' delimit <function-type>
3314 
3315 	return true;
3316 }
3317 
3318 
3319 bool
3320 Demangler::_ParseTemplateArgs(Node* node, Node*& _node)
3321 {
3322 	DEBUG_SCOPE("_ParseTemplateArgs");
3323 
3324 	// <template-args> ::= I <template-arg>+ E
3325 
3326 	if (!_SkipExpected('I'))
3327 		return false;
3328 
3329 	// we need at least one <template-arg>
3330 	if (fInput.CharsRemaining() == 0 || fInput[0] == 'E')
3331 		return _SetError(ERROR_INVALID);
3332 
3333 	// create the node
3334 	TemplateNode* templateNode;
3335 	if (!NodeCreator<TemplateNode>(this)(node, templateNode))
3336 		return false;
3337 	_node = templateNode;
3338 
3339 	// parse the args
3340 	while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3341 		Node* arg;
3342 		if (!_ParseTemplateArg(arg))
3343 			return false;
3344 		templateNode->AddArgument(arg);
3345 	}
3346 
3347 	// skip the trailing 'E'
3348 	return _SkipExpected('E');
3349 }
3350 
3351 
3352 bool
3353 Demangler::_ParseTemplateArg(Node*& _node)
3354 {
3355 	DEBUG_SCOPE("_ParseTemplateArg");
3356 
3357 	// <template-arg> ::= <type>			   # type or template
3358 	//                ::= X <expression> E	   # expression
3359 	//                ::= <expr-primary>       # simple expressions
3360 	//                ::= I <template-arg>* E  # argument pack
3361 	//                ::= sp <expression>      # pack expansion of (C++0x)
3362 
3363 	if (fInput.CharsRemaining() == 0)
3364 		return _SetError(ERROR_INVALID);
3365 
3366 	switch (fInput[0]) {
3367 		case 'X':	// X <expression> E
3368 			fInput.Skip(1);
3369 			return _ParseExpression(_node) && _SkipExpected('E');
3370 
3371 		case 'L':	// <expr-primary>
3372 			return _ParseExpressionPrimary(_node);
3373 
3374 		case 'I':	// I <template-arg>* E
3375 		{
3376 #if 0
3377 			fInput.Skip(1);
3378 
3379 			while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3380 				Node* arg;
3381 				if (!_ParseTemplateArg(arg))
3382 					return false;
3383 			}
3384 
3385 			if (!fInput.SkipPrefix('E'))
3386 				return _SetError(ERROR_INVALID);
3387 			return true;
3388 #endif
3389 			// NOTE: Unsupported by the GNU demangler.
3390 			return _SetError(ERROR_UNSUPPORTED);
3391 		}
3392 
3393 		case 's':
3394 			if (fInput.SkipPrefix("sp")) {
3395 				// sp <expression>
3396 #if 0
3397 				return _ParseExpression(_node);
3398 #endif
3399 				// NOTE: Unsupported by the GNU demangler.
3400 				return _SetError(ERROR_UNSUPPORTED);
3401 			}
3402 
3403 			// fall through...
3404 
3405 		default:	// <type>
3406 			return _ParseType(_node);
3407 	}
3408 }
3409 
3410 
3411 bool
3412 Demangler::_ParseExpression(Node*& _node)
3413 {
3414 	DEBUG_SCOPE("_ParseExpression");
3415 
3416 	// <expression> ::= <unary operator-name> <expression>
3417 	//              ::= <binary operator-name> <expression> <expression>
3418 	//              ::= <trinary operator-name> <expression> <expression>
3419 	//                  <expression>
3420 	//              ::= cl <expression>* E          # call
3421 	//              ::= cv <type> expression        # conversion with one
3422 	//                                                argument
3423 	//              ::= cv <type> _ <expression>* E # conversion with a
3424 	//                                                different number of
3425 	//                                                arguments
3426 	//              ::= st <type>		            # sizeof (a type)
3427 	//              ::= at <type>                   # alignof (a type)
3428 	//              ::= <template-param>
3429 	//              ::= <function-param>
3430 	//              ::= sr <type> <unqualified-name>
3431 	//                    # dependent name
3432 	//              ::= sr <type> <unqualified-name> <template-args>
3433 	//                    # dependent template-id
3434 	//              ::= sZ <template-param>
3435 	//                    # size of a parameter pack
3436 	//              ::= <expr-primary>
3437 	//
3438 	// <expr-primary> ::= L <type> <value number> E  # integer literal
3439 	//                ::= L <type <value float> E    # floating literal
3440 	//                ::= L <mangled-name> E         # external name
3441 
3442 	if (fInput.CharsRemaining() == 0)
3443 		return _SetError(ERROR_INVALID);
3444 
3445 	switch (fInput[0]) {
3446 		case 'L':
3447 			return _ParseExpressionPrimary(_node);
3448 		case 'T':
3449 			return _ParseTemplateParam(_node);
3450 		// NOTE: <function-param> is not defined in the specs!
3451 	}
3452 
3453 	// must be an operator
3454 	if (fInput.CharsRemaining() < 2)
3455 		return _SetError(ERROR_INVALID);
3456 
3457 	// some operators need special handling
3458 
3459 	if (fInput.SkipPrefix("cl")) {
3460 		// cl <expression>* E          # call
3461 		CallNode* callNode;
3462 		if (!NodeCreator<CallNode>(this)(callNode))
3463 			return false;
3464 
3465 		while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3466 			Node* subExpression;
3467 			if (!_ParseExpression(subExpression))
3468 				return false;
3469 			callNode->AddSubExpression(subExpression);
3470 		}
3471 
3472 		_node = callNode;
3473 		return _SkipExpected('E');
3474 	}
3475 
3476 	if (fInput.SkipPrefix("cv")) {
3477 		// cv <type> expression        # conversion with one argument
3478 		// cv <type> _ <expression>* E # conversion with a different number
3479 		//                               of arguments
3480 
3481 		// parse the type
3482 		Node* type;
3483 		if (!_ParseType(type))
3484 			return false;
3485 
3486 		// create a conversion expression node
3487 		ConversionExpressionNode* expression;
3488 		if (!NodeCreator<ConversionExpressionNode>(this)(type, expression))
3489 			return false;
3490 		_node = expression;
3491 
3492 		if (fInput.SkipPrefix('_')) {
3493 			// multi argument conversion
3494 			while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3495 				Node* subExpression;
3496 				if (!_ParseExpression(subExpression))
3497 					return false;
3498 				expression->AddSubExpression(subExpression);
3499 			}
3500 
3501 			return _SkipExpected('E');
3502 		}
3503 
3504 		// single argument conversion
3505 		Node* subExpression;
3506 		if (!_ParseExpression(subExpression))
3507 			return false;
3508 		expression->AddSubExpression(subExpression);
3509 
3510 		return true;
3511 	}
3512 
3513 	if (fInput.SkipPrefix("sr")) {
3514 		// sr <type> <unqualified-name>
3515 		// sr <type> <unqualified-name> <template-args>
3516 
3517 		// parse type and unqualified name and create the node
3518 		Node* type;
3519 		Node* name;
3520 		if (!_ParseType(type) || !_ParseUnqualifiedName(name)
3521 			|| !NodeCreator<DependentNameNode>(this)(type, name, _node)) {
3522 			return false;
3523 		}
3524 
3525 		// If there are template arguments left, add them.
3526 		if (!fInput.HasPrefix('I'))
3527 			return true;
3528 
3529 		return _ParseTemplateArgs(_node, _node);
3530 	}
3531 
3532 	if (fInput.SkipPrefix("sZ")) {
3533 		// sZ <template-param>
3534 
3535 		// NOTE: Unsupported by the GNU demangler.
3536 		return _SetError(ERROR_UNSUPPORTED);
3537 	}
3538 
3539 	// no special operator, so have a look for the others
3540 
3541 	const operator_info* info = NULL;
3542 	for (int i = 0; kOperatorInfos[i].name != NULL; i++) {
3543 		if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) {
3544 			info = &kOperatorInfos[i];
3545 			break;
3546 		}
3547 	}
3548 
3549 	// We can only deal with operators with a fixed argument count at this
3550 	// point.
3551 	if (info == NULL || info->argument_count < 0)
3552 		return _SetError(ERROR_INVALID);
3553 
3554 	// create an operator node
3555 	OperatorExpressionNode* operatorNode;
3556 	if (!NodeCreator<OperatorExpressionNode>(this)(info, operatorNode))
3557 		return false;
3558 
3559 	// parse the arguments
3560 	int i = 0;
3561 
3562 	// the first one might be a type
3563 	if ((info->flags & OPERATOR_TYPE_PARAM) != 0) {
3564 		Node* type;
3565 		if (!_ParseType(type))
3566 			return false;
3567 
3568 		operatorNode->AddSubExpression(type);
3569 		i++;
3570 	}
3571 
3572 	// the others are expressions
3573 	for (; i < info->argument_count; i++) {
3574 		Node* subExpression;
3575 		if (!_ParseExpression(subExpression))
3576 			return false;
3577 		operatorNode->AddSubExpression(subExpression);
3578 	}
3579 
3580 	_node = operatorNode;
3581 	return true;
3582 }
3583 
3584 
3585 bool
3586 Demangler::_ParseExpressionPrimary(Node*& _node)
3587 {
3588 	DEBUG_SCOPE("_ParseExpressionPrimary");
3589 
3590 	// <expr-primary> ::= L <type> <value number> E  # integer literal
3591 	//                ::= L <type <value float> E    # floating literal
3592 	//                ::= L <mangled-name> E         # external name
3593 
3594 	if (!_SkipExpected('L'))
3595 		return false;
3596 
3597 	if (fInput.SkipPrefix("_Z")) {
3598 		ObjectNode* node;
3599 		if (!_ParseEncoding(node))
3600 			return false;
3601 		_node = node;
3602 	} else {
3603 		// number or float literal
3604 		Node* type;
3605 		if (!_ParseType(type))
3606 			return false;
3607 
3608 		// GNU's demangler doesn't really seem to parse the integer/float,
3609 		// but only replaces a leading 'n' by '-'. Good enough for us, too.
3610 
3611 		// determine the length
3612 		int maxLength = fInput.CharsRemaining();
3613 		int length = 0;
3614 		while (length < maxLength && fInput[length] != 'E')
3615 			length++;
3616 
3617 		if (length == 0)
3618 			return _SetError(ERROR_INVALID);
3619 
3620 		if (!NodeCreator<TypedNumberLiteralNode>(this)(type,
3621 				fInput.String(), length, _node)) {
3622 			return false;
3623 		}
3624 
3625 		fInput.Skip(length);
3626 	}
3627 
3628 	return _SkipExpected('E');
3629 }
3630 
3631 
3632 bool
3633 Demangler::_ParseNumber(number_type& number)
3634 {
3635 	DEBUG_SCOPE("_ParseNumber");
3636 
3637 	bool negative = fInput.SkipPrefix('n');
3638 
3639 	if (fInput.CharsRemaining() == 0)
3640 		return _SetError(ERROR_INVALID);
3641 
3642 	number = 0;
3643 	int count = fInput.CharsRemaining();
3644 	int i = 0;
3645 	for (; i < count && isdigit(fInput[i]); i++)
3646 		number = number * 10 + (fInput[i] - '0');
3647 
3648 	fInput.Skip(i);
3649 
3650 	if (negative)
3651 		number =-number;
3652 	return true;
3653 }
3654 
3655 
3656 bool
3657 Demangler::_CreateNodeAndSkip(const char* name, size_t length, int toSkip,
3658 	Node*& _node)
3659 {
3660 	if (toSkip > 0)
3661 		fInput.Skip(toSkip);
3662 
3663 	return NodeCreator<SimpleNameNode>(this)(name, length, _node);
3664 }
3665 
3666 
3667 bool
3668 Demangler::_CreateNodeAndSkip(const char* name, int toSkip, Node*& _node)
3669 {
3670 	return _CreateNodeAndSkip(name, strlen(name), toSkip, _node);
3671 }
3672 
3673 
3674 bool
3675 Demangler::_CreateTypeNodeAndSkip(type_type type, int toSkip, Node*& _node)
3676 {
3677 	if (toSkip > 0)
3678 		fInput.Skip(toSkip);
3679 
3680 	return NodeCreator<SimpleTypeNode>(this)(type, _node);
3681 }
3682 
3683 
3684 bool
3685 Demangler::_CreateTypeNodeAndSkip(const char* name, const char* prefix,
3686 	const char* templateArgs, int toSkip, Node*& _node)
3687 {
3688 	if (toSkip > 0)
3689 		fInput.Skip(toSkip);
3690 
3691 	// create the name node
3692 	if (!NodeCreator<SimpleTypeNode>(this)(name, _node))
3693 		return false;
3694 
3695 	// add the prefix
3696 	if (prefix != NULL) {
3697 		Node* prefixNode;
3698 		if (!NodeCreator<SimpleTypeNode>(this)(prefix, prefixNode)
3699 			|| !NodeCreator<PrefixedNode>(this)(prefixNode, _node, _node)) {
3700 			return false;
3701 		}
3702 	}
3703 
3704 	// wrap the node to add the template args
3705 	if (templateArgs != NULL) {
3706 		TemplateNode* templateNode;
3707 		Node* argsNode;
3708 		if (!NodeCreator<TemplateNode>(this)(_node, templateNode)
3709 			|| !NodeCreator<SimpleTypeNode>(this)(templateArgs, argsNode)) {
3710 			return false;
3711 		}
3712 		templateNode->AddArgument(argsNode);
3713 		_node = templateNode;
3714 	}
3715 
3716 	return true;
3717 }
3718 
3719 
3720 void
3721 Demangler::_RegisterReferenceableNode(Node* node)
3722 {
3723 	// check, if not referenceable or already registered
3724 	if (!node->IsReferenceable() || node == fLastReferenceableNode
3725 		|| node->NextReferenceable() != NULL) {
3726 		return;
3727 	}
3728 
3729 	if (fFirstReferenceableNode == NULL) {
3730 		fFirstReferenceableNode = node;
3731 		fLastReferenceableNode = node;
3732 	} else {
3733 		fLastReferenceableNode->SetNextReferenceable(node);
3734 		fLastReferenceableNode = node;
3735 	}
3736 }
3737 
3738 
3739 bool
3740 Demangler::_CreateSubstitutionNode(int index, Node*& _node)
3741 {
3742 	Node* node = fFirstReferenceableNode;
3743 	while (node != NULL && index > 0) {
3744 		node = node->NextReferenceable();
3745 		index--;
3746 	}
3747 
3748 	if (node == NULL)
3749 		return _SetError(ERROR_INVALID);
3750 
3751 	// create a substitution node
3752 	return NodeCreator<SubstitutionNode>(this)(node, _node);
3753 }
3754 
3755 
3756 // #pragma mark -
3757 
3758 
3759 const char*
3760 demangle_symbol_gcc3(const char* mangledName, char* buffer, size_t bufferSize,
3761 	bool* _isObjectMethod)
3762 {
3763 	bool isObjectMethod;
3764 	if (_isObjectMethod == NULL)
3765 		_isObjectMethod = &isObjectMethod;
3766 
3767 	Demangler demangler;
3768 	DemanglingInfo info(true);
3769 	if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK)
3770 		return NULL;
3771 
3772 	// Set the object method return value. Unless we know for sure that it isn't
3773 	// an object method, we assume that it is.
3774 	switch (info.objectType) {
3775 		case OBJECT_TYPE_DATA:
3776 		case OBJECT_TYPE_FUNCTION:
3777 		case OBJECT_TYPE_METHOD_CLASS:
3778 			*_isObjectMethod = false;
3779 			break;
3780 		case OBJECT_TYPE_METHOD_OBJECT:
3781 			*_isObjectMethod = true;
3782 			break;
3783 		case OBJECT_TYPE_UNKNOWN:
3784 		case OBJECT_TYPE_METHOD_UNKNOWN:
3785 			*_isObjectMethod = strstr(buffer, "::") != NULL;
3786 			break;
3787 	}
3788 
3789 	return buffer;
3790 }
3791 
3792 
3793 status_t
3794 get_next_argument_gcc3(uint32* _cookie, const char* mangledName, char* name,
3795 	size_t nameSize, int32* _type, size_t* _argumentLength)
3796 {
3797 	Demangler demangler;
3798 	ParameterInfo info;
3799 	int result = demangler.GetParameterInfo(mangledName, *_cookie, name,
3800 		nameSize, info);
3801 	if (result != ERROR_OK) {
3802 		switch (result) {
3803 			case ERROR_NOT_MANGLED:
3804 				return B_BAD_VALUE;
3805 			case ERROR_UNSUPPORTED:
3806 				return B_BAD_VALUE;
3807 			case ERROR_INVALID:
3808 				return B_BAD_VALUE;
3809 			case ERROR_BUFFER_TOO_SMALL:
3810 				return B_BUFFER_OVERFLOW;
3811 			case ERROR_NO_MEMORY:
3812 				return B_NO_MEMORY;
3813 			case ERROR_INVALID_PARAMETER_INDEX:
3814 				return B_BAD_INDEX;
3815 			case ERROR_INTERNAL:
3816 			default:
3817 				return B_ERROR;
3818 		}
3819 	}
3820 
3821 	// translate the type
3822 	switch (info.type.type) {
3823 		case TYPE_BOOL:
3824 			*_type = B_BOOL_TYPE;
3825 			*_argumentLength = 1;
3826 			break;
3827 
3828 		case TYPE_CHAR:
3829 			*_type = B_CHAR_TYPE;
3830 			*_argumentLength = 1;
3831 			break;
3832 
3833 		case TYPE_SIGNED_CHAR:
3834 			*_type = B_INT8_TYPE;
3835 			*_argumentLength = 1;
3836 			break;
3837 		case TYPE_UNSIGNED_CHAR:
3838 			*_type = B_UINT8_TYPE;
3839 			*_argumentLength = 1;
3840 			break;
3841 
3842 		case TYPE_SHORT:
3843 			*_type = B_INT16_TYPE;
3844 			*_argumentLength = 2;
3845 			break;
3846 		case TYPE_UNSIGNED_SHORT:
3847 			*_type = B_UINT16_TYPE;
3848 			*_argumentLength = 2;
3849 			break;
3850 
3851 		case TYPE_INT:
3852 			*_type = B_INT32_TYPE;
3853 			*_argumentLength = 4;
3854 			break;
3855 		case TYPE_UNSIGNED_INT:
3856 			*_type = B_UINT32_TYPE;
3857 			*_argumentLength = 4;
3858 			break;
3859 
3860 		case TYPE_LONG:
3861 			*_type = sizeof(long) == 4 ? B_INT32_TYPE : B_INT64_TYPE;
3862 			*_argumentLength = sizeof(long);
3863 			break;
3864 		case TYPE_UNSIGNED_LONG:
3865 			*_type = sizeof(long) == 4 ? B_UINT32_TYPE : B_UINT64_TYPE;
3866 			*_argumentLength = sizeof(long);
3867 			break;
3868 
3869 		case TYPE_LONG_LONG:
3870 			*_type = B_INT64_TYPE;
3871 			*_argumentLength = 8;
3872 			break;
3873 		case TYPE_UNSIGNED_LONG_LONG:
3874 			*_type = B_INT64_TYPE;
3875 			*_argumentLength = 8;
3876 			break;
3877 
3878 		case TYPE_INT128:
3879 			*_type = 0;
3880 			*_argumentLength = 16;
3881 			break;
3882 		case TYPE_UNSIGNED_INT128:
3883 			*_type = 0;
3884 			*_argumentLength = 16;
3885 			break;
3886 
3887 		case TYPE_FLOAT:
3888 			*_type = B_FLOAT_TYPE;
3889 			*_argumentLength = sizeof(float);
3890 			break;
3891 		case TYPE_DOUBLE:
3892 			*_type = B_DOUBLE_TYPE;
3893 			*_argumentLength = sizeof(double);
3894 			break;
3895 
3896 		case TYPE_LONG_DOUBLE:
3897 			*_type = 0;
3898 			*_argumentLength = sizeof(long double);
3899 			break;
3900 
3901 		case TYPE_FLOAT128:
3902 			*_type = 0;
3903 			*_argumentLength = 16;
3904 			break;
3905 
3906 		case TYPE_DFLOAT16:
3907 			*_argumentLength = 2;
3908 		case TYPE_DFLOAT32:
3909 			*_argumentLength *= 2;
3910 		case TYPE_DFLOAT64:
3911 			*_argumentLength *= 2;
3912 		case TYPE_DFLOAT128:
3913 			*_argumentLength *= 2;
3914 			*_type = 0;
3915 			break;
3916 
3917 		case TYPE_CHAR16_T:
3918 			*_type = B_UINT16_TYPE;
3919 			*_argumentLength = 2;
3920 			break;
3921 
3922 		case TYPE_CHAR32_T:
3923 			*_type = B_UINT32_TYPE;
3924 			*_argumentLength = 2;
3925 			break;
3926 
3927 		case TYPE_CONST_CHAR_POINTER:
3928 			*_type = B_STRING_TYPE;
3929 			*_argumentLength = sizeof(void*);
3930 			break;
3931 
3932 		case TYPE_POINTER:
3933 			*_type = B_POINTER_TYPE;
3934 			*_argumentLength = sizeof(void*);
3935 			break;
3936 
3937 		case TYPE_REFERENCE:
3938 			*_type = B_REF_TYPE;
3939 				// TODO: That's actually entry_ref!
3940 			*_argumentLength = sizeof(void*);
3941 			break;
3942 
3943 		case TYPE_WCHAR_T:
3944 			// TODO: Type/size might change!
3945 			*_type = B_UINT16_TYPE;
3946 			*_argumentLength = 2;
3947 			break;
3948 
3949 		case TYPE_UNKNOWN:
3950 		case TYPE_ELLIPSIS:
3951 		case TYPE_VOID:
3952 		default:
3953 			// Well, tell our caller *something*.
3954 			*_type = 0;
3955 			*_argumentLength = sizeof(int);
3956 	}
3957 
3958 	// assume sizeof(int) argument alignment
3959 	if (*_argumentLength < sizeof(int))
3960 		*_argumentLength = sizeof(int);
3961 
3962 	++*_cookie;
3963 	return B_OK;
3964 }
3965 
3966 
3967 #ifndef _KERNEL_MODE
3968 
3969 const char*
3970 demangle_name_gcc3(const char* mangledName, char* buffer, size_t bufferSize)
3971 {
3972 
3973 	Demangler demangler;
3974 	DemanglingInfo info(false);
3975 	if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK)
3976 		return NULL;
3977 	return buffer;
3978 }
3979 
3980 #endif
3981