xref: /haiku/src/add-ons/kernel/debugger/demangle/gcc3+.cpp (revision 0945c7e4e6b52126886ef81d8f217690f0dbe7e6)
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 {
DebugScopeDebugScope249 	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 
~DebugScopeDebugScope263 	~DebugScope()
264 	{
265 		sGlobalScope = fParent;
266 		PRINT("%*s%s() done\n", fLevel * 2, "", fFunctionName);
267 	}
268 
PrintDebugScope269 	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:
Input()295 	Input()
296 		:
297 		fString(NULL),
298 		fLength(0)
299 	{
300 	}
301 
SetTo(const char * string,size_t length)302 	void SetTo(const char* string, size_t length)
303 	{
304 		fString = string;
305 		fLength = length;
306 	}
307 
String() const308 	const char* String() const
309 	{
310 		return fString;
311 	}
312 
CharsRemaining() const313 	int CharsRemaining() const
314 	{
315 		return fLength;
316 	}
317 
Skip(size_t count)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 
HasPrefix(char prefix) const329 	bool HasPrefix(char prefix) const
330 	{
331 		return fLength > 0 && fString[0] == prefix;
332 	}
333 
HasPrefix(const char * prefix) const334 	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 
SkipPrefix(char prefix)341 	bool SkipPrefix(char prefix)
342 	{
343 		if (!HasPrefix(prefix))
344 			return false;
345 
346 		fString++;
347 		fLength--;
348 		return true;
349 	}
350 
SkipPrefix(const char * prefix)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 
operator [](size_t index) const362 	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:
NameBuffer(char * buffer,size_t size)380 	NameBuffer(char* buffer, size_t size)
381 		:
382 		fBuffer(buffer),
383 		fSize(size),
384 		fLength(0),
385 		fOverflow(false)
386 	{
387 	}
388 
IsEmpty() const389 	bool IsEmpty() const
390 	{
391 		return fLength == 0;
392 	}
393 
LastChar() const394 	char LastChar() const
395 	{
396 		return fLength > 0 ? fBuffer[fLength - 1] : '\0';
397 	}
398 
HadOverflow() const399 	bool HadOverflow() const
400 	{
401 		return fOverflow;
402 	}
403 
Terminate()404 	char* Terminate()
405 	{
406 		fBuffer[fLength] = '\0';
407 		return fBuffer;
408 	}
409 
Append(const char * string,size_t length)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 
Append(const char * string)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 
TypeInfoTypeInfo439 	TypeInfo()
440 		:
441 		type(TYPE_UNKNOWN),
442 		cvQualifiers(0)
443 	{
444 	}
445 
TypeInfoTypeInfo446 	TypeInfo(type_type type)
447 		:
448 		type(type),
449 		cvQualifiers(0)
450 	{
451 	}
452 
TypeInfoTypeInfo453 	TypeInfo(const TypeInfo& other, int cvQualifiers = 0)
454 		:
455 		type(other.type),
456 		cvQualifiers(other.cvQualifiers | cvQualifiers)
457 	{
458 	}
459 
operator =TypeInfo460 	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 
DemanglingParametersDemanglingParameters472 	DemanglingParameters(bool objectNameOnly)
473 		:
474 		objectNameOnly(objectNameOnly)
475 	{
476 	}
477 };
478 
479 
480 struct DemanglingInfo : DemanglingParameters {
481 	object_type	objectType;
482 
DemanglingInfoDemanglingInfo483 	DemanglingInfo(bool objectNameOnly)
484 		:
485 		DemanglingParameters(objectNameOnly),
486 		objectType(OBJECT_TYPE_UNKNOWN)
487 	{
488 	}
489 };
490 
491 
492 struct ParameterInfo {
493 	TypeInfo	type;
494 
ParameterInfoParameterInfo495 	ParameterInfo()
496 	{
497 	}
498 };
499 
500 
501 class Node;
502 
503 struct NameDecorationInfo {
504 	const Node*	firstDecorator;
505 	const Node*	closestCVDecoratorList;
506 
NameDecorationInfoNameDecorationInfo507 	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 
CVQualifierInfoCVQualifierInfo519 	CVQualifierInfo()
520 		:
521 		firstCVQualifier(NULL),
522 		firstNonCVQualifier(NULL)
523 	{
524 	}
525 };
526 
527 
528 class Node {
529 public:
Node()530 	Node()
531 		:
532 		fNextAllocated(NULL),
533 		fParent(NULL),
534 		fNext(NULL),
535 		fNextReferenceable(NULL),
536 		fReferenceable(true)
537 	{
538 	}
539 
~Node()540 	virtual ~Node()
541 	{
542 	}
543 
NextAllocated() const544 	Node* NextAllocated() const			{ return fNextAllocated; }
SetNextAllocated(Node * node)545 	void SetNextAllocated(Node* node)	{ fNextAllocated = node; }
546 
Parent() const547 	Node* Parent() const				{ return fParent; }
SetParent(Node * node)548 	virtual void SetParent(Node* node)	{ fParent = node; }
549 
Next() const550 	Node* Next() const			{ return fNext; }
SetNext(Node * node)551 	void SetNext(Node* node)	{ fNext = node; }
552 
IsReferenceable() const553 	bool IsReferenceable() const		{ return fReferenceable; }
SetReferenceable(bool flag)554 	void SetReferenceable(bool flag)	{ fReferenceable = flag; }
555 
NextReferenceable() const556 	Node* NextReferenceable() const			{ return fNextReferenceable; }
SetNextReferenceable(Node * node)557 	void SetNextReferenceable(Node* node)	{ fNextReferenceable = node; }
558 
559 	virtual bool GetName(NameBuffer& buffer) const = 0;
560 
GetDecoratedName(NameBuffer & buffer,NameDecorationInfo & decorationInfo) const561 	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 
AddDecoration(NameBuffer & buffer,const Node * stopDecorator) const571 	virtual bool AddDecoration(NameBuffer& buffer,
572 		const Node* stopDecorator) const
573 	{
574 		return true;
575 	}
576 
GetCVQualifierInfo(CVQualifierInfo & info) const577 	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
578 	{
579 		info.firstNonCVQualifier = this;
580 	}
581 
GetUnqualifiedNode(Node * beforeNode)582 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
583 	{
584 		return this;
585 	}
586 
IsTemplatized() const587 	virtual bool IsTemplatized() const
588 	{
589 		return false;
590 	}
591 
TemplateParameterAt(int index) const592 	virtual Node* TemplateParameterAt(int index) const
593 	{
594 		return NULL;
595 	}
596 
IsNoReturnValueFunction() const597 	virtual bool IsNoReturnValueFunction() const
598 	{
599 		return false;
600 	}
601 
IsTypeName(const char * name,size_t length) const602 	virtual bool IsTypeName(const char* name, size_t length) const
603 	{
604 		return false;
605 	}
606 
ObjectType() const607 	virtual object_type ObjectType() const
608 	{
609 		return OBJECT_TYPE_UNKNOWN;
610 	}
611 
PrefixType() const612 	virtual prefix_type PrefixType() const
613 	{
614 		return PREFIX_NONE;
615 	}
616 
Type() const617 	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:
NamedTypeNode(Node * name)633 	NamedTypeNode(Node* name)
634 		:
635 		fName(name)
636 	{
637 		if (fName != NULL)
638 			fName->SetParent(this);
639 	}
640 
GetName(NameBuffer & buffer) const641 	virtual bool GetName(NameBuffer& buffer) const
642 	{
643 		return fName == NULL || fName->GetName(buffer);
644 	}
645 
IsNoReturnValueFunction() const646 	virtual bool IsNoReturnValueFunction() const
647 	{
648 		return fName != NULL && fName->IsNoReturnValueFunction();
649 	}
650 
Type() const651 	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:
SubstitutionNode(Node * node)663 	SubstitutionNode(Node* node)
664 		:
665 		fNode(node)
666 	{
667 	}
668 
GetName(NameBuffer & buffer) const669 	virtual bool GetName(NameBuffer& buffer) const
670 	{
671 		return fNode->GetName(buffer);
672 	}
673 
GetDecoratedName(NameBuffer & buffer,NameDecorationInfo & decorationInfo) const674 	virtual bool GetDecoratedName(NameBuffer& buffer,
675 		NameDecorationInfo& decorationInfo) const
676 	{
677 		return fNode->GetDecoratedName(buffer, decorationInfo);
678 	}
679 
AddDecoration(NameBuffer & buffer,const Node * stopDecorator) const680 	virtual bool AddDecoration(NameBuffer& buffer,
681 		const Node* stopDecorator) const
682 	{
683 		return fNode->AddDecoration(buffer, stopDecorator);
684 	}
685 
GetCVQualifierInfo(CVQualifierInfo & info) const686 	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
687 	{
688 		fNode->GetCVQualifierInfo(info);
689 	}
690 
IsTemplatized() const691 	virtual bool IsTemplatized() const
692 	{
693 		return fNode->IsTemplatized();
694 	}
695 
TemplateParameterAt(int index) const696 	virtual Node* TemplateParameterAt(int index) const
697 	{
698 		return fNode->TemplateParameterAt(index);
699 	}
700 
IsNoReturnValueFunction() const701 	virtual bool IsNoReturnValueFunction() const
702 	{
703 		return fNode->IsNoReturnValueFunction();
704 	}
705 
IsTypeName(const char * name,size_t length) const706 	virtual bool IsTypeName(const char* name, size_t length) const
707 	{
708 		return fNode->IsTypeName(name, length);
709 	}
710 
ObjectType() const711 	virtual object_type ObjectType() const
712 	{
713 		return fNode->ObjectType();
714 	}
715 
PrefixType() const716 	virtual prefix_type PrefixType() const
717 	{
718 		return fNode->PrefixType();
719 	}
720 
Type() const721 	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:
ArrayNode(Node * type,int dimension)733 	ArrayNode(Node* type, int dimension)
734 		:
735 		NamedTypeNode(type),
736 		fDimensionExpression(NULL),
737 		fDimensionNumber(dimension)
738 	{
739 	}
740 
ArrayNode(Node * type,Node * dimension)741 	ArrayNode(Node* type, Node* dimension)
742 		:
743 		NamedTypeNode(type),
744 		fDimensionExpression(dimension),
745 		fDimensionNumber(0)
746 	{
747 		fDimensionExpression->SetParent(this);
748 	}
749 
GetName(NameBuffer & buffer) const750 	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 
ObjectType() const770 	virtual object_type ObjectType() const
771 	{
772 		return OBJECT_TYPE_DATA;
773 	}
774 
Type() const775 	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:
ObjectNode(Node * name)790 	ObjectNode(Node* name)
791 		:
792 		NamedTypeNode(name)
793 	{
794 	}
795 
GetObjectName(NameBuffer & buffer,const DemanglingParameters & parameters)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 
ObjectType() const805 	virtual object_type ObjectType() const
806 	{
807 		return OBJECT_TYPE_DATA;
808 	}
809 
ParameterAt(uint32 index) const810 	virtual Node* ParameterAt(uint32 index) const
811 	{
812 		return NULL;
813 	}
814 };
815 
816 
817 class SimpleNameNode : public Node {
818 public:
SimpleNameNode(const char * name)819 	SimpleNameNode(const char* name)
820 		:
821 		fName(name),
822 		fLength(strlen(name))
823 	{
824 	}
825 
SimpleNameNode(const char * name,size_t length)826 	SimpleNameNode(const char* name, size_t length)
827 		:
828 		fName(name),
829 		fLength(length)
830 	{
831 	}
832 
GetName(NameBuffer & buffer) const833 	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:
SimpleTypeNode(const char * name)846 	SimpleTypeNode(const char* name)
847 		:
848 		SimpleNameNode(name),
849 		fType(TYPE_UNKNOWN)
850 	{
851 	}
852 
SimpleTypeNode(type_type type)853 	SimpleTypeNode(type_type type)
854 		:
855 		SimpleNameNode(kTypeNames[type]),
856 		fType(type)
857 	{
858 	}
859 
IsTypeName(const char * name,size_t length) const860 	virtual bool IsTypeName(const char* name, size_t length) const
861 	{
862 		return fLength == length && strcmp(fName, name) == 0;
863 	}
864 
ObjectType() const865 	virtual object_type ObjectType() const
866 	{
867 		return OBJECT_TYPE_DATA;
868 	}
869 
Type() const870 	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:
TypedNumberLiteralNode(Node * type,const char * number,size_t length)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 
GetName(NameBuffer & buffer) const891 	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 
ObjectType() const917 	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:
XtructorNode(bool constructor,char type)931 	XtructorNode(bool constructor, char type)
932 		:
933 		fConstructor(constructor),
934 		fType(type)
935 	{
936 	}
937 
SetParent(Node * node)938 	virtual void SetParent(Node* node)
939 	{
940 		fUnqualifiedNode = node->GetUnqualifiedNode(this);
941 		Node::SetParent(node);
942 	}
943 
GetName(NameBuffer & buffer) const944 	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 
IsNoReturnValueFunction() const955 	virtual bool IsNoReturnValueFunction() const
956 	{
957 		return true;
958 	}
959 
ObjectType() const960 	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:
SpecialNameNode(const char * name,Node * child)974 	SpecialNameNode(const char* name, Node* child)
975 		:
976 		fName(name),
977 		fChild(child)
978 	{
979 		fChild->SetParent(this);
980 	}
981 
GetName(NameBuffer & buffer) const982 	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:
DecoratingNode(Node * child)995 	DecoratingNode(Node* child)
996 		:
997 		fChildNode(child)
998 	{
999 		fChildNode->SetParent(this);
1000 	}
1001 
GetName(NameBuffer & buffer) const1002 	virtual bool GetName(NameBuffer& buffer) const
1003 	{
1004 		NameDecorationInfo decorationInfo(this);
1005 		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1006 	}
1007 
GetDecoratedName(NameBuffer & buffer,NameDecorationInfo & decorationInfo) const1008 	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:
CVQualifiersNode(int qualifiers,Node * child)1022 	CVQualifiersNode(int qualifiers, Node* child)
1023 		:
1024 		DecoratingNode(child),
1025 		fCVQualifiers(qualifiers)
1026 	{
1027 	}
1028 
GetDecoratedName(NameBuffer & buffer,NameDecorationInfo & decorationInfo) const1029 	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 
AddDecoration(NameBuffer & buffer,const Node * stopDecorator) const1037 	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 
GetCVQualifierInfo(CVQualifierInfo & info) const1056 	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
1057 	{
1058 		if (info.firstCVQualifier == NULL)
1059 			info.firstCVQualifier = this;
1060 		fChildNode->GetCVQualifierInfo(info);
1061 	}
1062 
IsTemplatized() const1063 	virtual bool IsTemplatized() const
1064 	{
1065 		return fChildNode->IsTemplatized();
1066 	}
1067 
TemplateParameterAt(int index) const1068 	virtual Node* TemplateParameterAt(int index) const
1069 	{
1070 		return fChildNode->TemplateParameterAt(index);
1071 	}
1072 
IsNoReturnValueFunction() const1073 	virtual bool IsNoReturnValueFunction() const
1074 	{
1075 		return fChildNode->IsNoReturnValueFunction();
1076 	}
1077 
ObjectType() const1078 	virtual object_type ObjectType() const
1079 	{
1080 		return fChildNode->ObjectType();
1081 	}
1082 
PrefixType() const1083 	virtual prefix_type PrefixType() const
1084 	{
1085 		return fChildNode->PrefixType();
1086 	}
1087 
Type() const1088 	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:
TypeModifierNode(type_modifier modifier,Node * child)1100 	TypeModifierNode(type_modifier modifier, Node* child)
1101 		:
1102 		DecoratingNode(child),
1103 		fModifier(modifier)
1104 	{
1105 	}
1106 
AddDecoration(NameBuffer & buffer,const Node * stopDecorator) const1107 	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 
ObjectType() const1117 	virtual object_type ObjectType() const
1118 	{
1119 		return OBJECT_TYPE_DATA;
1120 	}
1121 
Type() const1122 	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:
VendorTypeModifierNode(Node * name,Node * child)1147 	VendorTypeModifierNode(Node* name, Node* child)
1148 		:
1149 		DecoratingNode(child),
1150 		fName(name)
1151 	{
1152 		fName->SetParent(this);
1153 	}
1154 
AddDecoration(NameBuffer & buffer,const Node * stopDecorator) const1155 	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 
ObjectType() const1166 	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:
OperatorNode(const operator_info * info)1178 	OperatorNode(const operator_info* info)
1179 		:
1180 		fInfo(info)
1181 	{
1182 		SetReferenceable(false);
1183 	}
1184 
GetName(NameBuffer & buffer) const1185 	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 
ObjectType() const1192 	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:
VendorOperatorNode(Node * name)1205 	VendorOperatorNode(Node* name)
1206 		:
1207 		fName(name)
1208 	{
1209 		fName->SetParent(this);
1210 		SetReferenceable(false);
1211 	}
1212 
GetName(NameBuffer & buffer) const1213 	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:
CastOperatorNode(Node * child)1226 	CastOperatorNode(Node* child)
1227 		:
1228 		fChildNode(child)
1229 	{
1230 		fChildNode->SetParent(this);
1231 	}
1232 
GetName(NameBuffer & buffer) const1233 	virtual bool GetName(NameBuffer& buffer) const
1234 	{
1235 		return buffer.Append("operator ") && fChildNode->GetName(buffer);
1236 	}
1237 
IsNoReturnValueFunction() const1238 	virtual bool IsNoReturnValueFunction() const
1239 	{
1240 		return true;
1241 	}
1242 
ObjectType() const1243 	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:
PrefixedNode(Node * prefix,Node * node)1255 	PrefixedNode(Node* prefix, Node* node)
1256 		:
1257 		fPrefixNode(prefix),
1258 		fNode(node)
1259 	{
1260 		fPrefixNode->SetParent(this);
1261 		fNode->SetParent(this);
1262 	}
1263 
GetName(NameBuffer & buffer) const1264 	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 
GetUnqualifiedNode(Node * beforeNode)1273 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1274 	{
1275 		return beforeNode == fNode
1276 			? fPrefixNode->GetUnqualifiedNode(beforeNode)
1277 			: fNode->GetUnqualifiedNode(beforeNode);
1278 	}
1279 
IsNoReturnValueFunction() const1280 	virtual bool IsNoReturnValueFunction() const
1281 	{
1282 		return fNode->IsNoReturnValueFunction();
1283 	}
1284 
ObjectType() const1285 	virtual object_type ObjectType() const
1286 	{
1287 		return fNode->ObjectType();
1288 	}
1289 
PrefixType() const1290 	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:
ClonedNode(Node * clone,ObjectNode * node)1303 	ClonedNode(Node* clone, ObjectNode* node)
1304 		:
1305 		ObjectNode(NULL),
1306 		fNode(node),
1307 		fCloneNode(clone)
1308 	{
1309 		fNode->SetParent(this);
1310 		fCloneNode->SetParent(this);
1311 	}
1312 
GetName(NameBuffer & buffer) const1313 	virtual bool GetName(NameBuffer& buffer) const
1314 	{
1315 		if (!fNode->GetName(buffer))
1316 			return false;
1317 		buffer.Append(" ", 1);
1318 		return _AppendCloneName(buffer);
1319 	}
1320 
GetObjectName(NameBuffer & buffer,const DemanglingParameters & parameters)1321 	virtual bool GetObjectName(NameBuffer& buffer,
1322 		const DemanglingParameters& parameters)
1323 	{
1324 		if (parameters.objectNameOnly) {
1325 			if (!fNode->GetObjectName(buffer, parameters))
1326 				return false;
1327 			if (!_AppendCloneName(buffer))
1328 				return false;
1329 			return buffer.Append(" ", 1);
1330 		}
1331 
1332 		return ObjectNode::GetObjectName(buffer, parameters);
1333 	}
1334 
GetUnqualifiedNode(Node * beforeNode)1335 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1336 	{
1337 		return beforeNode == fCloneNode
1338 			? fNode->GetUnqualifiedNode(beforeNode)
1339 			: fCloneNode->GetUnqualifiedNode(beforeNode);
1340 	}
1341 
IsNoReturnValueFunction() const1342 	virtual bool IsNoReturnValueFunction() const
1343 	{
1344 		return fNode->IsNoReturnValueFunction();
1345 	}
1346 
ObjectType() const1347 	virtual object_type ObjectType() const
1348 	{
1349 		return fNode->ObjectType();
1350 	}
1351 
PrefixType() const1352 	virtual prefix_type PrefixType() const
1353 	{
1354 		return PREFIX_UNKNOWN;
1355 	}
1356 
ParameterAt(uint32 index) const1357 	virtual Node* ParameterAt(uint32 index) const
1358 	{
1359 		return fNode->ParameterAt(index);
1360 	}
1361 
1362 private:
_AppendCloneName(NameBuffer & buffer) const1363 	bool _AppendCloneName(NameBuffer& buffer) const
1364 	{
1365 		buffer.Append("[clone ");
1366 		if (!fCloneNode->GetName(buffer))
1367 			return false;
1368 		buffer.Append("]");
1369 		return true;
1370 	}
1371 
1372 private:
1373 	ObjectNode*	fNode;
1374 	Node*		fCloneNode;
1375 };
1376 
1377 
1378 typedef PrefixedNode DependentNameNode;
1379 
1380 
1381 class TemplateNode : public Node {
1382 public:
TemplateNode(Node * base)1383 	TemplateNode(Node* base)
1384 		:
1385 		fBase(base),
1386 		fFirstArgument(NULL),
1387 		fLastArgument(NULL)
1388 	{
1389 		fBase->SetParent(this);
1390 	}
1391 
AddArgument(Node * child)1392 	void AddArgument(Node* child)
1393 	{
1394 		child->SetParent(this);
1395 
1396 		if (fLastArgument != NULL) {
1397 			fLastArgument->SetNext(child);
1398 			fLastArgument = child;
1399 		} else {
1400 			fFirstArgument = child;
1401 			fLastArgument = child;
1402 		}
1403 	}
1404 
GetName(NameBuffer & buffer) const1405 	virtual bool GetName(NameBuffer& buffer) const
1406 	{
1407 		if (!fBase->GetName(buffer))
1408 			return false;
1409 
1410 		buffer.Append("<");
1411 
1412 		Node* child = fFirstArgument;
1413 		while (child != NULL) {
1414 			if (child != fFirstArgument)
1415 				buffer.Append(", ");
1416 
1417 			if (!child->GetName(buffer))
1418 				return false;
1419 
1420 			child = child->Next();
1421 		}
1422 
1423 		// add a space between consecutive '>'
1424 		if (buffer.LastChar() == '>')
1425 			buffer.Append(" ");
1426 
1427 		return buffer.Append(">");
1428 	}
1429 
GetUnqualifiedNode(Node * beforeNode)1430 	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1431 	{
1432 		return fBase != beforeNode
1433 			? fBase->GetUnqualifiedNode(beforeNode) : this;
1434 	}
1435 
IsTemplatized() const1436 	virtual bool IsTemplatized() const
1437 	{
1438 		return true;
1439 	}
1440 
TemplateParameterAt(int index) const1441 	virtual Node* TemplateParameterAt(int index) const
1442 	{
1443 		Node* child = fFirstArgument;
1444 		while (child != NULL) {
1445 			if (index == 0)
1446 				return child;
1447 			index--;
1448 			child = child->Next();
1449 		}
1450 
1451 		return NULL;
1452 	}
1453 
IsNoReturnValueFunction() const1454 	virtual bool IsNoReturnValueFunction() const
1455 	{
1456 		return fBase->IsNoReturnValueFunction();
1457 	}
1458 
ObjectType() const1459 	virtual object_type ObjectType() const
1460 	{
1461 		return fBase->ObjectType();
1462 	}
1463 
PrefixType() const1464 	virtual prefix_type PrefixType() const
1465 	{
1466 		return fBase->PrefixType();
1467 	}
1468 
1469 protected:
1470 	Node*	fBase;
1471 	Node*	fFirstArgument;
1472 	Node*	fLastArgument;
1473 };
1474 
1475 
1476 class MultiSubExpressionsNode : public Node {
1477 public:
MultiSubExpressionsNode()1478 	MultiSubExpressionsNode()
1479 		:
1480 		fFirstSubExpression(NULL),
1481 		fLastSubExpression(NULL)
1482 	{
1483 	}
1484 
AddSubExpression(Node * child)1485 	void AddSubExpression(Node* child)
1486 	{
1487 		child->SetParent(this);
1488 
1489 		if (fLastSubExpression != NULL) {
1490 			fLastSubExpression->SetNext(child);
1491 			fLastSubExpression = child;
1492 		} else {
1493 			fFirstSubExpression = child;
1494 			fLastSubExpression = child;
1495 		}
1496 	}
1497 
1498 protected:
1499 	Node*		fFirstSubExpression;
1500 	Node*		fLastSubExpression;
1501 };
1502 
1503 
1504 class CallNode : public MultiSubExpressionsNode {
1505 public:
CallNode()1506 	CallNode()
1507 	{
1508 	}
1509 
GetName(NameBuffer & buffer) const1510 	virtual bool GetName(NameBuffer& buffer) const
1511 	{
1512 		// TODO: Use the real syntax!
1513 		buffer.Append("call(");
1514 
1515 		Node* child = fFirstSubExpression;
1516 		while (child != NULL) {
1517 			if (child != fFirstSubExpression)
1518 				buffer.Append(", ");
1519 
1520 			if (!child->GetName(buffer))
1521 				return false;
1522 
1523 			child = child->Next();
1524 		}
1525 
1526 		buffer.Append(")");
1527 
1528 		return true;
1529 	}
1530 };
1531 
1532 
1533 class OperatorExpressionNode : public MultiSubExpressionsNode {
1534 public:
OperatorExpressionNode(const operator_info * info)1535 	OperatorExpressionNode(const operator_info* info)
1536 		:
1537 		fInfo(info)
1538 	{
1539 	}
1540 
GetName(NameBuffer & buffer) const1541 	virtual bool GetName(NameBuffer& buffer) const
1542 	{
1543 		bool isIdentifier = isalpha(fInfo->name[0]) || fInfo->name[0] == '_';
1544 
1545 		if (fInfo->argument_count == 1 || isIdentifier
1546 			|| fInfo->argument_count > 3
1547 			|| (fInfo->argument_count == 3 && strcmp(fInfo->name, "?") != 0)) {
1548 			// prefix operator
1549 			buffer.Append(fInfo->name);
1550 
1551 			if (isIdentifier)
1552 				buffer.Append("(");
1553 
1554 			Node* child = fFirstSubExpression;
1555 			while (child != NULL) {
1556 				if (child != fFirstSubExpression)
1557 					buffer.Append(", ");
1558 
1559 				if (!child->GetName(buffer))
1560 					return false;
1561 
1562 				child = child->Next();
1563 			}
1564 
1565 			if (isIdentifier)
1566 				buffer.Append(")");
1567 
1568 			return true;
1569 		}
1570 
1571 		Node* arg1 = fFirstSubExpression;
1572 		Node* arg2 = arg1->Next();
1573 
1574 		buffer.Append("(");
1575 
1576 		if (fInfo->argument_count == 2) {
1577 			// binary infix operator
1578 			if (!arg1->GetName(buffer))
1579 				return false;
1580 
1581 			buffer.Append(" ");
1582 			buffer.Append(fInfo->name);
1583 			buffer.Append(" ");
1584 
1585 			if (!arg2->GetName(buffer))
1586 				return false;
1587 
1588 			return buffer.Append(")");
1589 		}
1590 
1591 		Node* arg3 = arg2->Next();
1592 
1593 		if (fInfo->argument_count == 2) {
1594 			// trinary operator "... ? ... : ..."
1595 			if (!arg1->GetName(buffer))
1596 				return false;
1597 
1598 			buffer.Append(" ? ");
1599 
1600 			if (!arg2->GetName(buffer))
1601 				return false;
1602 
1603 			buffer.Append(" : ");
1604 
1605 			if (!arg3->GetName(buffer))
1606 				return false;
1607 
1608 			return buffer.Append(")");
1609 		}
1610 
1611 		return false;
1612 	}
1613 
1614 private:
1615 	const operator_info*	fInfo;
1616 };
1617 
1618 
1619 class ConversionExpressionNode : public MultiSubExpressionsNode {
1620 public:
ConversionExpressionNode(Node * type)1621 	ConversionExpressionNode(Node* type)
1622 		:
1623 		fType(type)
1624 	{
1625 		fType->SetParent(this);
1626 	}
1627 
GetName(NameBuffer & buffer) const1628 	virtual bool GetName(NameBuffer& buffer) const
1629 	{
1630 		buffer.Append("(");
1631 
1632 		if (!fType->GetName(buffer))
1633 			return false;
1634 
1635 		buffer.Append(")(");
1636 
1637 		Node* child = fFirstSubExpression;
1638 		while (child != NULL) {
1639 			if (child != fFirstSubExpression)
1640 				buffer.Append(", ");
1641 
1642 			if (!child->GetName(buffer))
1643 				return false;
1644 
1645 			child = child->Next();
1646 		}
1647 
1648 		return buffer.Append(")");
1649 	}
1650 
1651 private:
1652 	Node*	fType;
1653 };
1654 
1655 
1656 class PointerToMemberNode : public DecoratingNode {
1657 public:
PointerToMemberNode(Node * classType,Node * memberType)1658 	PointerToMemberNode(Node* classType, Node* memberType)
1659 		:
1660 		DecoratingNode(memberType),
1661 		fClassType(classType)
1662 	{
1663 		fClassType->SetParent(this);
1664 	}
1665 
AddDecoration(NameBuffer & buffer,const Node * stopDecorator) const1666 	virtual bool AddDecoration(NameBuffer& buffer,
1667 		const Node* stopDecorator) const
1668 	{
1669 		if (this == stopDecorator)
1670 			return true;
1671 
1672 		if (!fChildNode->AddDecoration(buffer, stopDecorator))
1673 			return false;
1674 
1675 		// In most cases we need a space before the name. In some it is
1676 		// superfluous, though.
1677 		if (!buffer.IsEmpty() && buffer.LastChar() != '(')
1678 			buffer.Append(" ");
1679 
1680 		if (!fClassType->GetName(buffer))
1681 			return false;
1682 
1683 		return buffer.Append("::*");
1684 	}
1685 
ObjectType() const1686 	virtual object_type ObjectType() const
1687 	{
1688 		return OBJECT_TYPE_DATA;
1689 	}
1690 
Type() const1691 	virtual TypeInfo Type() const
1692 	{
1693 		// TODO: Method pointers aren't ordinary pointers. Though we might not
1694 		// be able to determine the difference.
1695 		return TypeInfo(TYPE_POINTER);
1696 	}
1697 
1698 
1699 private:
1700 	Node*	fClassType;
1701 };
1702 
1703 
1704 class FunctionNode : public ObjectNode {
1705 public:
FunctionNode(Node * nameNode,bool hasReturnType,bool isExternC)1706 	FunctionNode(Node* nameNode, bool hasReturnType, bool isExternC)
1707 		:
1708 		ObjectNode(nameNode),
1709 		fFirstTypeNode(NULL),
1710 		fLastTypeNode(NULL),
1711 		fHasReturnType(hasReturnType),
1712 		fIsExternC(isExternC)
1713 	{
1714 	}
1715 
AddType(Node * child)1716 	void AddType(Node* child)
1717 	{
1718 		child->SetParent(this);
1719 
1720 		if (fLastTypeNode != NULL) {
1721 			fLastTypeNode->SetNext(child);
1722 			fLastTypeNode = child;
1723 		} else {
1724 			fFirstTypeNode = child;
1725 			fLastTypeNode = child;
1726 		}
1727 	}
1728 
GetName(NameBuffer & buffer) const1729 	virtual bool GetName(NameBuffer& buffer) const
1730 	{
1731 		NameDecorationInfo decorationInfo(NULL);
1732 		return GetDecoratedName(buffer, decorationInfo);
1733 	}
1734 
GetDecoratedName(NameBuffer & buffer,NameDecorationInfo & decorationInfo) const1735 	virtual bool GetDecoratedName(NameBuffer& buffer,
1736 		NameDecorationInfo& decorationInfo) const
1737 	{
1738 		// write 'extern "C"'
1739 //		if (fIsExternC)
1740 //			buffer.Append("extern \"C\"");
1741 
1742 		// write the return type
1743 		Node* child = fFirstTypeNode;
1744 		if (_HasReturnType() && child != NULL) {
1745 			if (!child->GetName(buffer))
1746 				return false;
1747 			child = child->Next();
1748 
1749 			buffer.Append(" ", 1);
1750 		}
1751 
1752 		// write the function name
1753 		if (fName == NULL)
1754 			buffer.Append("(", 1);
1755 
1756 		CVQualifierInfo info;
1757 		if (fName != NULL) {
1758 			// skip CV qualifiers on our name -- we'll add them later
1759 			fName->GetCVQualifierInfo(info);
1760 			if (info.firstNonCVQualifier != NULL
1761 				&& !info.firstNonCVQualifier->GetName(buffer)) {
1762 				return false;
1763 			}
1764 		}
1765 
1766 		// add non-CV qualifier decorations
1767 		if (decorationInfo.firstDecorator != NULL) {
1768 			if (!decorationInfo.firstDecorator->AddDecoration(buffer,
1769 				decorationInfo.closestCVDecoratorList)) {
1770 				return false;
1771 			}
1772 		}
1773 
1774 		if (fName == NULL)
1775 			buffer.Append(")", 1);
1776 
1777 		// add the parameter types
1778 		buffer.Append("(");
1779 
1780 		// don't add a single "void" parameter
1781 		if (child != NULL && child->Next() == NULL
1782 			&& child->IsTypeName("void", 4)) {
1783 			child = NULL;
1784 		}
1785 
1786 		Node* firstParam = child;
1787 		while (child != NULL) {
1788 			if (child != firstParam)
1789 				buffer.Append(", ");
1790 
1791 			if (!child->GetName(buffer))
1792 				return false;
1793 
1794 			child = child->Next();
1795 		}
1796 
1797 		buffer.Append(")");
1798 
1799 		// add CV qualifiers on our name
1800 		if (info.firstCVQualifier != NULL) {
1801 			if (!info.firstCVQualifier->AddDecoration(buffer,
1802 					info.firstNonCVQualifier)) {
1803 				return false;
1804 			}
1805 		}
1806 
1807 		// add CV qualifiers on us
1808 		if (decorationInfo.closestCVDecoratorList != NULL)
1809 			decorationInfo.closestCVDecoratorList->AddDecoration(buffer, NULL);
1810 
1811 		return true;
1812 	}
1813 
ObjectType() const1814 	virtual object_type ObjectType() const
1815 	{
1816 		// no name, no fun
1817 		if (fName == NULL)
1818 			return OBJECT_TYPE_FUNCTION;
1819 
1820 		// check our name's prefix
1821 		switch (fName->PrefixType()) {
1822 			case PREFIX_NONE:
1823 			case PREFIX_NAMESPACE:
1824 				return OBJECT_TYPE_FUNCTION;
1825 			case PREFIX_CLASS:
1826 			case PREFIX_UNKNOWN:
1827 				break;
1828 		}
1829 
1830 		// Our name has a prefix, but we don't know, whether it is a class or
1831 		// namespace. Let's ask our name what it thinks it is.
1832 		object_type type = fName->ObjectType();
1833 		switch (type) {
1834 			case OBJECT_TYPE_FUNCTION:
1835 			case OBJECT_TYPE_METHOD_CLASS:
1836 			case OBJECT_TYPE_METHOD_OBJECT:
1837 			case OBJECT_TYPE_METHOD_UNKNOWN:
1838 				// That's as good as it gets.
1839 				return type;
1840 			case OBJECT_TYPE_UNKNOWN:
1841 			case OBJECT_TYPE_DATA:
1842 			default:
1843 				// Obviously our name doesn't have a clue.
1844 				return OBJECT_TYPE_METHOD_UNKNOWN;
1845 		}
1846 	}
1847 
ParameterAt(uint32 index) const1848 	virtual Node* ParameterAt(uint32 index) const
1849 	{
1850 		// skip return type
1851 		Node* child = fFirstTypeNode;
1852 		if (_HasReturnType() && child != NULL)
1853 			child = child->Next();
1854 
1855 		// ignore a single "void" parameter
1856 		if (child != NULL && child->Next() == NULL
1857 			&& child->IsTypeName("void", 4)) {
1858 			return NULL;
1859 		}
1860 
1861 		// get the type at the index
1862 		while (child != NULL && index > 0) {
1863 			child = child->Next();
1864 			index--;
1865 		}
1866 
1867 		return child;
1868 	}
1869 
1870 private:
_HasReturnType() const1871 	bool _HasReturnType() const
1872 	{
1873 		return fHasReturnType
1874 			|| fName == NULL
1875 			|| (fName->IsTemplatized() && !fName->IsNoReturnValueFunction());
1876 	}
1877 
1878 private:
1879 	Node*		fFirstTypeNode;
1880 	Node*		fLastTypeNode;
1881 	bool		fHasReturnType;
1882 	bool		fIsExternC;
1883 };
1884 
1885 
1886 // #pragma mark - Demangler
1887 
1888 
1889 class Demangler {
1890 public:
1891 								Demangler();
1892 
1893 			int					Demangle(const char* mangledName, char* buffer,
1894 									size_t size,
1895 									DemanglingInfo& demanglingInfo);
1896 			int					GetParameterInfo(const char* mangledName,
1897 									uint32 index, char* buffer, size_t size,
1898 									ParameterInfo& info);
1899 
1900 	// actually private, but public to make gcc 2 happy
1901 	inline	bool				_SetError(int error);
1902 	inline	void				_AddAllocatedNode(Node* node);
1903 
1904 private:
1905 	template<typename NodeType> struct NodeCreator;
1906 
1907 	inline	bool				_SkipExpected(char c);
1908 	inline	bool				_SkipExpected(const char* string);
1909 
1910 			void				_Init();
1911 			void				_Cleanup();
1912 
1913 			int					_Demangle(const char* mangledName, char* buffer,
1914 									size_t size,
1915 									DemanglingInfo& demanglingInfo);
1916 			int					_GetParameterInfo(const char* mangledName,
1917 									uint32 index, char* buffer, size_t size,
1918 									ParameterInfo& info);
1919 
1920 			int					_Parse(const char* mangledName,
1921 									const char*& versionSuffix,
1922 									ObjectNode*& _node);
1923 
1924 			bool				_ParseClone(ObjectNode*& _node);
1925 			bool				_ParseEncoding(ObjectNode*& _node);
1926 			bool				_ParseSpecialName(Node*& _node);
1927 			bool				_ParseCallOffset(bool& nonVirtual,
1928 									number_type& offset1, number_type& offset2);
1929 			bool				_ParseName(Node*& _node);
1930 			bool				_ParseNestedName(Node*& _node);
1931 			bool				_ParseNestedNameInternal(Node*& _node);
1932 			bool				_ParseLocalName(Node*& _node);
1933 			bool				_ParseUnqualifiedName(Node*& _node);
1934 			bool				_ParseSourceName(Node*& _node);
1935 			bool				_ParseOperatorName(Node*& _node);
1936 			bool				_ParseType(Node*& _node);
1937 			bool				_ParseTypeInternal(Node*& _node);
1938 			void				_ParseCVQualifiers(int& qualifiers);
1939 			bool				_ParseTypeWithModifier(type_modifier modifier,
1940 									int toSkip, Node*& _node);
1941 			bool				_TryParseBuiltinType(Node*& _node);
1942 			bool				_ParseFunctionType(FunctionNode*& _node);;
1943 			bool				_ParseArrayType(Node*& _node);
1944 			bool				_ParsePointerToMemberType(Node*& _node);
1945 			bool				_ParseTemplateParam(Node*& _node);
1946 			bool				_ParseSubstitution(Node*& _node);
1947 			bool				_ParseSubstitutionInternal(Node*& _node);
1948 			bool				_ParseBareFunctionType(FunctionNode* node);
1949 			bool				_ParseTemplateArgs(Node* node, Node*& _node);
1950 			bool				_ParseTemplateArg(Node*& _node);
1951 			bool				_ParseExpression(Node*& _node);
1952 			bool				_ParseExpressionPrimary(Node*& _node);
1953 			bool				_ParseNumber(number_type& number);
1954 
1955 			bool				_CreateNodeAndSkip(const char* name,
1956 									size_t length, int toSkip, Node*& _node);
1957 			bool				_CreateNodeAndSkip(const char* name, int toSkip,
1958 									Node*& _node);
1959 			bool				_CreateTypeNodeAndSkip(type_type type,
1960 									int toSkip, Node*& _node);
1961 			bool				_CreateTypeNodeAndSkip(const char* name,
1962 									const char* prefix,
1963 									const char* templateArgs, int toSkip,
1964 									Node*& _node);
1965 
1966 			void				_RegisterReferenceableNode(Node* node);
1967 			bool				_CreateSubstitutionNode(int index,
1968 									Node*& _node);
1969 
1970 private:
1971 			Input				fInput;
1972 			int					fError;
1973 			Node*				fAllocatedNodes;
1974 			Node*				fFirstReferenceableNode;
1975 			Node*				fLastReferenceableNode;
1976 			Node*				fTemplatizedNode;
1977 };
1978 
1979 
1980 template<typename NodeType>
1981 struct Demangler::NodeCreator {
NodeCreatorDemangler::NodeCreator1982 	NodeCreator(Demangler* demangler)
1983 		:
1984 		fDemangler(demangler)
1985 	{
1986 	}
1987 
1988 	template<typename ReturnType>
operator ()Demangler::NodeCreator1989 	inline bool operator()(ReturnType*& _node) const
1990 	{
1991 		_node = NEW(NodeType);
1992 		if (_node == NULL)
1993 			return fDemangler->_SetError(ERROR_NO_MEMORY);
1994 
1995 		fDemangler->_AddAllocatedNode(_node);
1996 		return true;
1997 	}
1998 
1999 	template<typename ParameterType1, typename ReturnType>
operator ()Demangler::NodeCreator2000 	inline bool operator()(ParameterType1 arg1, ReturnType*& _node) const
2001 	{
2002 		_node = NEW(NodeType(arg1));
2003 		if (_node == NULL)
2004 			return fDemangler->_SetError(ERROR_NO_MEMORY);
2005 
2006 		fDemangler->_AddAllocatedNode(_node);
2007 		return true;
2008 	}
2009 
2010 	template<typename ParameterType1, typename ParameterType2,
2011 		typename ReturnType>
operator ()Demangler::NodeCreator2012 	inline bool operator()(ParameterType1 arg1, ParameterType2 arg2,
2013 		ReturnType*& _node) const
2014 	{
2015 		_node = NEW(NodeType(arg1, arg2));
2016 		if (_node == NULL)
2017 			return fDemangler->_SetError(ERROR_NO_MEMORY);
2018 
2019 		fDemangler->_AddAllocatedNode(_node);
2020 		return true;
2021 	}
2022 
2023 	template<typename ParameterType1, typename ParameterType2,
2024 		typename ParameterType3, typename ReturnType>
operator ()Demangler::NodeCreator2025 	inline bool operator()(ParameterType1 arg1, ParameterType2 arg2,
2026 		ParameterType3 arg3, ReturnType*& _node) const
2027 	{
2028 		_node = NEW(NodeType(arg1, arg2, arg3));
2029 		if (_node == NULL)
2030 			return fDemangler->_SetError(ERROR_NO_MEMORY);
2031 
2032 		fDemangler->_AddAllocatedNode(_node);
2033 		return true;
2034 	}
2035 
2036 private:
2037 		Demangler*	fDemangler;
2038 };
2039 
2040 
2041 inline bool
_SetError(int error)2042 Demangler::_SetError(int error)
2043 {
2044 	if (fError == ERROR_OK) {
2045 		fError = error;
2046 #ifdef TRACE_GCC3_DEMANGLER
2047 		DebugScope::Print("_SetError(): %d, remaining input: \"%s\"\n",
2048 			error, fInput.String());
2049 #endif
2050 	}
2051 	return false;
2052 }
2053 
2054 
2055 inline void
_AddAllocatedNode(Node * node)2056 Demangler::_AddAllocatedNode(Node* node)
2057 {
2058 	node->SetNextAllocated(fAllocatedNodes);
2059 	fAllocatedNodes = node;
2060 }
2061 
2062 
2063 inline bool
_SkipExpected(char c)2064 Demangler::_SkipExpected(char c)
2065 {
2066 	return fInput.SkipPrefix(c) || _SetError(ERROR_INVALID);
2067 }
2068 
2069 
2070 inline bool
_SkipExpected(const char * string)2071 Demangler::_SkipExpected(const char* string)
2072 {
2073 	return fInput.SkipPrefix(string) || _SetError(ERROR_INVALID);
2074 }
2075 
2076 
Demangler()2077 Demangler::Demangler()
2078 	:
2079 	fInput(),
2080 	fAllocatedNodes(NULL)
2081 {
2082 }
2083 
2084 
2085 int
Demangle(const char * mangledName,char * buffer,size_t size,DemanglingInfo & demanglingInfo)2086 Demangler::Demangle(const char* mangledName, char* buffer, size_t size,
2087 	DemanglingInfo& demanglingInfo)
2088 {
2089 	DEBUG_SCOPE("Demangle");
2090 
2091 	_Init();
2092 
2093 	int result = _Demangle(mangledName, buffer, size, demanglingInfo);
2094 
2095 	_Cleanup();
2096 
2097 	return result;
2098 }
2099 
2100 
2101 int
GetParameterInfo(const char * mangledName,uint32 index,char * buffer,size_t size,ParameterInfo & info)2102 Demangler::GetParameterInfo(const char* mangledName, uint32 index, char* buffer,
2103 	size_t size, ParameterInfo& info)
2104 {
2105 	DEBUG_SCOPE("GetParameterInfo");
2106 
2107 	_Init();
2108 
2109 	int result = _GetParameterInfo(mangledName, index, buffer, size, info);
2110 
2111 	_Cleanup();
2112 
2113 	return result;
2114 }
2115 
2116 
2117 void
_Init()2118 Demangler::_Init()
2119 {
2120 	fError = ERROR_OK;
2121 
2122 	fFirstReferenceableNode = NULL;
2123 	fLastReferenceableNode = NULL;
2124 	fAllocatedNodes = NULL;
2125 	fTemplatizedNode = NULL;
2126 }
2127 
2128 
2129 void
_Cleanup()2130 Demangler::_Cleanup()
2131 {
2132 	while (fAllocatedNodes != NULL) {
2133 		Node* node = fAllocatedNodes;
2134 		fAllocatedNodes = node->NextAllocated();
2135 		DELETE(node);
2136 	}
2137 }
2138 
2139 
2140 int
_Demangle(const char * mangledName,char * buffer,size_t size,DemanglingInfo & demanglingInfo)2141 Demangler::_Demangle(const char* mangledName, char* buffer, size_t size,
2142 	DemanglingInfo& demanglingInfo)
2143 {
2144 	// parse the name
2145 	const char* versionSuffix;
2146 	ObjectNode* node;
2147 	int error = _Parse(mangledName, versionSuffix, node);
2148 	if (error != ERROR_OK)
2149 		return error;
2150 
2151 	NameBuffer nameBuffer(buffer, size);
2152 	bool success = node->GetObjectName(nameBuffer, demanglingInfo);
2153 
2154 	// If versioned, append the unmodified version string
2155 	if (success && versionSuffix != NULL)
2156 		nameBuffer.Append(versionSuffix);
2157 
2158 	if (nameBuffer.HadOverflow())
2159 		return ERROR_BUFFER_TOO_SMALL;
2160 
2161 	if (!success)
2162 		return ERROR_INTERNAL;
2163 
2164 	demanglingInfo.objectType = node->ObjectType();
2165 
2166 	nameBuffer.Terminate();
2167 	return ERROR_OK;
2168 }
2169 
2170 
2171 int
_GetParameterInfo(const char * mangledName,uint32 index,char * buffer,size_t size,ParameterInfo & info)2172 Demangler::_GetParameterInfo(const char* mangledName, uint32 index,
2173 	char* buffer, size_t size, ParameterInfo& info)
2174 {
2175 	// parse the name
2176 	const char* versionSuffix;
2177 	ObjectNode* node;
2178 	int error = _Parse(mangledName, versionSuffix, node);
2179 	if (error != ERROR_OK)
2180 		return error;
2181 
2182 	// get the parameter node
2183 	Node* parameter = node->ParameterAt(index);
2184 	if (parameter == NULL)
2185 		return ERROR_INVALID_PARAMETER_INDEX;
2186 
2187 	// get the parameter name
2188 	NameBuffer nameBuffer(buffer, size);
2189 	bool success = parameter->GetName(nameBuffer);
2190 
2191 	if (nameBuffer.HadOverflow())
2192 		return ERROR_BUFFER_TOO_SMALL;
2193 
2194 	if (!success)
2195 		return ERROR_INTERNAL;
2196 
2197 	nameBuffer.Terminate();
2198 
2199 	// get the type
2200 	info.type = parameter->Type();
2201 
2202 	return ERROR_OK;
2203 }
2204 
2205 
2206 int
_Parse(const char * mangledName,const char * & versionSuffix,ObjectNode * & _node)2207 Demangler::_Parse(const char* mangledName, const char*& versionSuffix,
2208 	ObjectNode*& _node)
2209 {
2210 	// To support versioned symbols, we ignore the version suffix when
2211 	// demangling.
2212 	versionSuffix = strchr(mangledName, '@');
2213 	fInput.SetTo(mangledName,
2214 		versionSuffix != NULL
2215 			? versionSuffix - mangledName : strlen(mangledName));
2216 
2217 	// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
2218 
2219 	if (!fInput.SkipPrefix("_Z"))
2220 		return ERROR_NOT_MANGLED;
2221 
2222 	if (!_ParseEncoding(_node) || !_ParseClone(_node))
2223 		return fError;
2224 
2225 	if (fInput.CharsRemaining() != 0) {
2226 		// bogus at end of input
2227 		return ERROR_INVALID;
2228 	}
2229 
2230 	return ERROR_OK;
2231 }
2232 
2233 
2234 bool
_ParseClone(ObjectNode * & _node)2235 Demangler::_ParseClone(ObjectNode*& _node)
2236 {
2237 	DEBUG_SCOPE("_ParseClone");
2238 
2239 	while (fInput.HasPrefix('.')) {
2240 		int count = fInput.CharsRemaining();
2241 		int i = 1;
2242 		while (true) {
2243 			for (; i < count && fInput[i] != '.'; i++)
2244 				;
2245 			if (i + 1 >= count || fInput[i + 1] < '0' || fInput[i + 1] > '9')
2246 				break;
2247 			i++;
2248 		}
2249 		if (i == 1)
2250 			break;
2251 		Node* clone;
2252 		if (!_CreateNodeAndSkip(fInput.String(), i, i, clone))
2253 			return false;
2254 
2255 		if (!NodeCreator<ClonedNode>(this)(clone, _node, _node))
2256 			return false;
2257 	}
2258 	return true;
2259 }
2260 
2261 
2262 bool
_ParseEncoding(ObjectNode * & _node)2263 Demangler::_ParseEncoding(ObjectNode*& _node)
2264 {
2265 	DEBUG_SCOPE("_ParseEncoding");
2266 
2267 	// <encoding> ::= <function name> <bare-function-type>
2268 	//	          ::= <data name>
2269 	//	          ::= <special-name>
2270 
2271 	// NOTE: This is not in the specs: Local entities seem to be prefixed
2272 	// by an 'L'.
2273 	fInput.SkipPrefix('L');
2274 
2275 	// parse <special-name>, if it is one
2276 	Node* name;
2277 	if (fInput.HasPrefix('T') || fInput.HasPrefix("GV")) {
2278 		return _ParseSpecialName(name)
2279 			&& NodeCreator<ObjectNode>(this)(name, _node);
2280 	}
2281 
2282 	// either <data name> or <function name>
2283 	if (!_ParseName(name))
2284 		return false;
2285 
2286 	if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')
2287 		|| fInput.HasPrefix('.')) {
2288 		// <data name>
2289 		return NodeCreator<ObjectNode>(this)(name, _node);
2290 	}
2291 
2292 	// <function name> -- parse remaining <bare-function-type>
2293 	FunctionNode* functionNode;
2294 	if (!NodeCreator<FunctionNode>(this)(name, false, false, functionNode))
2295 		return false;
2296 	_node = functionNode;
2297 
2298 	// If our name is templatized, we push it onto the templatized node
2299 	// stack while parsing the function parameters.
2300 	Node* previousTemplatizedNode = fTemplatizedNode;
2301 	if (name->IsTemplatized())
2302 		fTemplatizedNode = name;
2303 
2304 	if (!_ParseBareFunctionType(functionNode))
2305 		return false;
2306 
2307 	fTemplatizedNode = previousTemplatizedNode;
2308 
2309 	return true;
2310 }
2311 
2312 
2313 bool
_ParseSpecialName(Node * & _node)2314 Demangler::_ParseSpecialName(Node*& _node)
2315 {
2316 	DEBUG_SCOPE("_ParseSpecialName");
2317 
2318 	if (fInput.CharsRemaining() == 0)
2319 		return _SetError(ERROR_INVALID);
2320 
2321 	// <special-name> ::= GV <object name>	# Guard variable for one-time
2322 	//                                      # initialization
2323 	//                    # No <type>
2324 	if (!fInput.SkipPrefix('T')) {
2325 		Node* name;
2326 		return _SkipExpected("GV")
2327 			&& _ParseName(name)
2328 			&& NodeCreator<SpecialNameNode>(this)("guard variable for ",
2329 				name, _node);
2330 	}
2331 
2332 	// <special-name> ::= TV <type>	# virtual table
2333 	//                ::= TT <type>	# VTT structure (construction vtable
2334 	//                              # index)
2335 	//                ::= TI <type>	# typeinfo structure
2336 	//                ::= TS <type>	# typeinfo name (null-terminated byte
2337 	//                              # string)
2338 	const char* prefix = NULL;
2339 	switch (fInput[0]) {
2340 		case 'V':
2341 			prefix = "vtable for ";
2342 			break;
2343 		case 'T':
2344 			prefix = "VTT for ";
2345 			break;
2346 		case 'I':
2347 			prefix = "typeinfo for ";
2348 			break;
2349 		case 'S':
2350 			prefix = "typeinfo name for ";
2351 			break;
2352 	}
2353 
2354 	if (prefix != NULL) {
2355 		fInput.Skip(1);
2356 		Node* type;
2357 		return _ParseType(type)
2358 			&& NodeCreator<SpecialNameNode>(this)(prefix, type, _node);
2359 	}
2360 
2361 	// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
2362 	//                    # base is the nominal target function of thunk
2363 	//                    # first call-offset is 'this' adjustment
2364 	//                    # second call-offset is result adjustment
2365 	if (fInput.SkipPrefix('c')) {
2366 		bool nonVirtual;
2367 		number_type offset1;
2368 		number_type offset2;
2369 		ObjectNode* name;
2370 		return _ParseCallOffset(nonVirtual, offset1, offset2)
2371 			&& _ParseCallOffset(nonVirtual, offset1, offset2)
2372 			&& _ParseEncoding(name)
2373 			&& NodeCreator<SpecialNameNode>(this)(
2374 				"covariant return thunk to ", name, _node);
2375 	}
2376 
2377 	// <special-name> ::= T <call-offset> <base encoding>
2378 	//                    # base is the nominal target function of thunk
2379 	bool nonVirtual;
2380 	number_type offset1;
2381 	number_type offset2;
2382 	ObjectNode* name;
2383 	return _ParseCallOffset(nonVirtual, offset1, offset2)
2384 		&& _ParseEncoding(name)
2385 		&& NodeCreator<SpecialNameNode>(this)(
2386 			nonVirtual ? "non-virtual thunk to " : "virtual thunk to ",
2387 			name, _node);
2388 }
2389 
2390 
2391 bool
_ParseCallOffset(bool & nonVirtual,number_type & offset1,number_type & offset2)2392 Demangler::_ParseCallOffset(bool& nonVirtual, number_type& offset1,
2393 	number_type& offset2)
2394 {
2395 	// <call-offset> ::= h <nv-offset> _
2396 	//               ::= v <v-offset> _
2397 	// <nv-offset> ::= <offset number>
2398 	//                 # non-virtual base override
2399 	// <v-offset>  ::= <offset number> _ <virtual offset number>
2400 	//                 # virtual base override, with vcall offset
2401 
2402 	// non-virtual
2403 	if (fInput.SkipPrefix('h')) {
2404 		nonVirtual = true;
2405 		return _ParseNumber(offset1) && _SkipExpected('_');
2406 	}
2407 
2408 	// virtual
2409 	nonVirtual = false;
2410 	return _SkipExpected('v')
2411 		&& _ParseNumber(offset1)
2412 		&& _SkipExpected('_')
2413 		&& _ParseNumber(offset2)
2414 		&& _SkipExpected('_');
2415 }
2416 
2417 bool
_ParseName(Node * & _node)2418 Demangler::_ParseName(Node*& _node)
2419 {
2420 	DEBUG_SCOPE("_ParseName");
2421 
2422 	if (fInput.CharsRemaining() == 0)
2423 		return _SetError(ERROR_INVALID);
2424 
2425 	// <name> ::= <nested-name>
2426 	//        ::= <unscoped-name>
2427 	//        ::= <unscoped-template-name> <template-args>
2428 	//        ::= <local-name>	# See Scope Encoding below
2429 	//
2430 	// <unscoped-name> ::= <unqualified-name>
2431 	//                 ::= St <unqualified-name>   # ::std::
2432 	//
2433 	// <unscoped-template-name> ::= <unscoped-name>
2434 	//                          ::= <substitution>
2435 
2436 	switch (fInput[0]) {
2437 		case 'N':
2438 			// <nested-name>
2439 			return _ParseNestedName(_node);
2440 		case 'Z':
2441 			// <local-name>
2442 			return _ParseLocalName(_node);
2443 		case 'S':
2444 		{
2445 			// <substitution>
2446 			if (!fInput.HasPrefix("St")) {
2447 				if (!_ParseSubstitution(_node))
2448 					return false;
2449 				break;
2450 			}
2451 
2452 			// std:: namespace
2453 			fInput.Skip(2);
2454 
2455 			Node* prefix;
2456 			if (!NodeCreator<SimpleNameNode>(this)("std", prefix))
2457 				return false;
2458 
2459 			// <unqualified-name>
2460 			Node* node;
2461 			if (!_ParseUnqualifiedName(node)
2462 				|| !NodeCreator<PrefixedNode>(this)(prefix, node, _node)) {
2463 				return false;
2464 			}
2465 
2466 			break;
2467 		}
2468 		default:
2469 			// <unqualified-name>
2470 			if (!_ParseUnqualifiedName(_node))
2471 				return false;
2472 			break;
2473 	}
2474 
2475 	// We get here for the names that might be an <unscoped-template-name>.
2476 	// Check whether <template-args> are following.
2477 	if (!fInput.HasPrefix('I'))
2478 		return true;
2479 
2480 	// <unscoped-template-name> is referenceable
2481 	_RegisterReferenceableNode(_node);
2482 
2483 	return _ParseTemplateArgs(_node, _node);
2484 }
2485 
2486 
2487 bool
_ParseNestedName(Node * & _node)2488 Demangler::_ParseNestedName(Node*& _node)
2489 {
2490 	DEBUG_SCOPE("_ParseNestedName");
2491 
2492 	// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
2493 	//               ::= N [<CV-qualifiers>] <template-prefix>
2494 	//                   <template-args> E
2495 	//
2496 	// <CV-qualifiers> ::= [r] [V] [K] 	# restrict (C99), volatile, const
2497 	//
2498 	// <prefix> ::= <prefix> <unqualified-name>
2499 	//          ::= <template-prefix> <template-args>
2500 	//          ::= <template-param>
2501 	//          ::= # empty
2502 	//          ::= <substitution>
2503 	//
2504 	// <template-prefix> ::= <prefix> <template unqualified-name>
2505 	//                   ::= <template-param>
2506 	//                   ::= <substitution>
2507 
2508 	if (!_SkipExpected('N'))
2509 		return false;
2510 
2511 	// parse CV qualifiers
2512 	int qualifiers;
2513 	_ParseCVQualifiers(qualifiers);
2514 
2515 	// parse the main part
2516 	if (!_ParseNestedNameInternal(_node))
2517 		return false;
2518 
2519 	// create a CV qualifiers wrapper node, if necessary
2520 	if (qualifiers != 0) {
2521 		return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node,
2522 			_node);
2523 	}
2524 
2525 	return true;
2526 }
2527 
2528 
2529 bool
_ParseNestedNameInternal(Node * & _node)2530 Demangler::_ParseNestedNameInternal(Node*& _node)
2531 {
2532 	DEBUG_SCOPE("_ParseNestedNameMain");
2533 
2534 	if (fInput.CharsRemaining() == 0)
2535 		return _SetError(ERROR_INVALID);
2536 
2537 	// the initial prefix might be a template param or a substitution
2538 	Node* initialPrefixNode = NULL;
2539 	Node* prefixNode = NULL;
2540 	switch (fInput[0]) {
2541 		case 'T':	// <template-param>
2542 			if (!_ParseTemplateParam(initialPrefixNode))
2543 				return false;
2544 
2545 			// a <prefix> or <template-prefix> and as such referenceable
2546 			_RegisterReferenceableNode(initialPrefixNode);
2547 			break;
2548 
2549 		case 'S':	// <substitution>
2550 			if (!_ParseSubstitution(initialPrefixNode))
2551 				return false;
2552 			break;
2553 	}
2554 
2555 	while (true) {
2556 		bool canTerminate = false;
2557 		Node* node;
2558 
2559 		if (initialPrefixNode != NULL) {
2560 			node = initialPrefixNode;
2561 			initialPrefixNode = NULL;
2562 		} else {
2563 			if (!_ParseUnqualifiedName(node))
2564 				return false;
2565 			canTerminate = true;
2566 		}
2567 
2568 		// join prefix and the new node
2569 		if (prefixNode != NULL) {
2570 			if (!NodeCreator<PrefixedNode>(this)(prefixNode, node, node))
2571 				return false;
2572 		}
2573 
2574 		// template arguments?
2575 		if (fInput.HasPrefix('I')) {
2576 			// <template-prefix> is referenceable
2577 			_RegisterReferenceableNode(node);
2578 
2579 			// parse the template arguments
2580 			if (!_ParseTemplateArgs(node, node))
2581 				return false;
2582 			canTerminate = true;
2583 		}
2584 
2585 		if (fInput.CharsRemaining() == 0)
2586 			return _SetError(ERROR_INVALID);
2587 
2588 		// end of nested name?
2589 		if (fInput.SkipPrefix('E')) {
2590 			// If it doesn't have template args, it must end in an
2591 			// unqualified name.
2592 			if (!canTerminate)
2593 				return _SetError(ERROR_INVALID);
2594 
2595 			_node = node;
2596 			return true;
2597 		}
2598 
2599 		// The fun continues, so this is a <prefix> or <template-prefix>
2600 		// and as such referenceable.
2601 		prefixNode = node;
2602 		_RegisterReferenceableNode(node);
2603 	}
2604 }
2605 
2606 
2607 bool
_ParseLocalName(Node * & _node)2608 Demangler::_ParseLocalName(Node*& _node)
2609 {
2610 	DEBUG_SCOPE("_ParseLocalName");
2611 
2612 	// <local-name> := Z <function encoding> E <entity name>
2613 	//                 [<discriminator>]
2614 	//              := Z <function encoding> E s [<discriminator>]
2615 	// <discriminator> := _ <non-negative number>
2616 
2617 	// parse the function name
2618 	ObjectNode* functionName;
2619 	if (!_SkipExpected('Z')
2620 		|| !_ParseEncoding(functionName)
2621 		|| !_SkipExpected('E')) {
2622 		return false;
2623 	}
2624 
2625 	Node* entityName;
2626 	if (fInput.SkipPrefix('s')) {
2627 		// string literal
2628 		if (!NodeCreator<SimpleNameNode>(this)("string literal",
2629 				entityName)) {
2630 			return false;
2631 		}
2632 	} else {
2633 		// local type or object
2634 		if (!_ParseName(entityName))
2635 			return false;
2636 	}
2637 
2638 	// parse discriminator
2639 	number_type discriminator = 0;
2640 	if (fInput.SkipPrefix('_')) {
2641 		if (!_ParseNumber(discriminator))
2642 			return false;
2643 		if (discriminator < 0)
2644 			return _SetError(ERROR_INVALID);
2645 		discriminator++;
2646 	}
2647 
2648 	return NodeCreator<PrefixedNode>(this)(functionName, entityName, _node);
2649 }
2650 
2651 
2652 bool
_ParseUnqualifiedName(Node * & _node)2653 Demangler::_ParseUnqualifiedName(Node*& _node)
2654 {
2655 	DEBUG_SCOPE("_ParseUnqualifiedName");
2656 
2657 	// <unqualified-name> ::= <operator-name>
2658 	//                    ::= <ctor-dtor-name>
2659 	//                    ::= <source-name>
2660 	//
2661 	// <source-name> ::= <positive length number> <identifier>
2662 	// <number> ::= [n] <non-negative decimal integer>
2663 	// <identifier> ::= <unqualified source code identifier>
2664 	//
2665 	// <ctor-dtor-name> ::= C1	# complete object constructor
2666 	//                  ::= C2	# base object constructor
2667 	//                  ::= C3	# complete object allocating constructor
2668 	//                  ::= D0	# deleting destructor
2669 	//                  ::= D1	# complete object destructor
2670 	//                  ::= D2	# base object destructor
2671 
2672 	// we need at least 2 chars
2673 	if (fInput.CharsRemaining() < 2)
2674 		return _SetError(ERROR_INVALID);
2675 
2676 	if (isdigit(fInput[0]) || (fInput[0] == 'n' && isdigit(fInput[1]))) {
2677 		// <source-name>
2678 		return _ParseSourceName(_node);
2679 	}
2680 
2681 	if (fInput[0] == 'C') {
2682 		// <ctor-dtor-name> -- constructors
2683 		switch (fInput[1]) {
2684 			case '1':
2685 			case '2':
2686 			case '3':
2687 				if (!NodeCreator<XtructorNode>(this)(true, fInput[1] - '1',
2688 						_node)) {
2689 					return false;
2690 				}
2691 
2692 				fInput.Skip(2);
2693 				return true;
2694 			default:
2695 				return _SetError(ERROR_INVALID);
2696 		}
2697 	}
2698 
2699 	if (fInput[0] == 'D') {
2700 		// <ctor-dtor-name> -- destructors
2701 		switch (fInput[1]) {
2702 			case '0':
2703 			case '1':
2704 			case '2':
2705 				if (!NodeCreator<XtructorNode>(this)(false, fInput[1] - '0',
2706 						_node)) {
2707 					return false;
2708 				}
2709 
2710 				fInput.Skip(2);
2711 				return true;
2712 			default:
2713 				return _SetError(ERROR_INVALID);
2714 		}
2715 	}
2716 
2717 	// must be an <operator-name>
2718 	return _ParseOperatorName(_node);
2719 }
2720 
2721 
2722 bool
_ParseSourceName(Node * & _node)2723 Demangler::_ParseSourceName(Node*& _node)
2724 {
2725 	DEBUG_SCOPE("_ParseSourceName");
2726 
2727 	if (fInput.CharsRemaining() == 0)
2728 		return _SetError(ERROR_INVALID);
2729 
2730 	number_type number;
2731 	if (!_ParseNumber(number))
2732 		return false;
2733 
2734 	if (number <= 0 || number > fInput.CharsRemaining())
2735 		return _SetError(ERROR_INVALID);
2736 
2737 	return _CreateNodeAndSkip(fInput.String(), number, number, _node);
2738 }
2739 
2740 
2741 bool
_ParseOperatorName(Node * & _node)2742 Demangler::_ParseOperatorName(Node*& _node)
2743 {
2744 	DEBUG_SCOPE("_ParseOperatorName");
2745 
2746 	if (fInput.CharsRemaining() < 2)
2747 		return _SetError(ERROR_INVALID);
2748 
2749 	const operator_info* info = NULL;
2750 	for (int i = 0; kOperatorInfos[i].name != NULL; i++) {
2751 		if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) {
2752 			info = &kOperatorInfos[i];
2753 			break;
2754 		}
2755 	}
2756 
2757 	if (info != NULL)
2758 		return NodeCreator<OperatorNode>(this)(info, _node);
2759 
2760 	// <operator-name> ::= cv <type>	# (cast)
2761 	if (fInput.SkipPrefix("cv")) {
2762 		Node* typeNode;
2763 		if (!_ParseType(typeNode))
2764 			return false;
2765 
2766 		return NodeCreator<CastOperatorNode>(this)(typeNode, _node);
2767 	}
2768 
2769 	//  <operator-name> ::= v <digit> <source-name>	# vendor extended
2770 	//                                                operator
2771 	if (fInput.SkipPrefix('v')) {
2772 		if (fInput.CharsRemaining() == 0 || !isdigit(fInput[0]))
2773 			return _SetError(ERROR_INVALID);
2774 		fInput.Skip(1);
2775 
2776 		Node* name;
2777 		return _ParseSourceName(name)
2778 			&& NodeCreator<VendorOperatorNode>(this)(name, _node);
2779 	}
2780 
2781 	return _SetError(ERROR_INVALID);
2782 }
2783 
2784 
2785 bool
_ParseType(Node * & _node)2786 Demangler::_ParseType(Node*& _node)
2787 {
2788 	DEBUG_SCOPE("_ParseType");
2789 
2790 	if (!_ParseTypeInternal(_node))
2791 		return false;
2792 
2793 	_RegisterReferenceableNode(_node);
2794 	return true;
2795 }
2796 
2797 
2798 bool
_ParseTypeInternal(Node * & _node)2799 Demangler::_ParseTypeInternal(Node*& _node)
2800 {
2801 	DEBUG_SCOPE("_ParseTypeInternal");
2802 
2803 	// <type> ::= <builtin-type>
2804 	//        ::= <function-type>
2805 	//        ::= <class-enum-type>
2806 	//        ::= <array-type>
2807 	//        ::= <pointer-to-member-type>
2808 	//        ::= <template-param>
2809 	//        ::= <template-template-param> <template-args>
2810 	//        ::= <substitution> # See Compression below
2811 	//
2812 	// <template-template-param> ::= <template-param>
2813 	//                           ::= <substitution>
2814 	//
2815 	// <type> ::= <CV-qualifiers> <type>
2816 	//        ::= P <type>	# pointer-to
2817 	//        ::= R <type>	# reference-to
2818 	//        ::= O <type>	# rvalue reference-to (C++0x)
2819 	//        ::= C <type>	# complex pair (C 2000)
2820 	//        ::= G <type>	# imaginary (C 2000)
2821 	//        ::= U <source-name> <type>	# vendor extended type qualifier
2822 	//
2823 	// <CV-qualifiers> ::= [r] [V] [K] 	# restrict (C99), volatile, const
2824 	//
2825 	// <type>  ::= Dp <type>          # pack expansion of (C++0x)
2826 	//         ::= Dt <expression> E  # decltype of an id-expression or
2827 	//                                # class member access (C++0x)
2828 	//         ::= DT <expression> E  # decltype of an expression (C++0x)
2829 
2830 	if (_TryParseBuiltinType(_node)) {
2831 		_node->SetReferenceable(false);
2832 		return true;
2833 	}
2834 	if (fError != ERROR_OK)
2835 		return false;
2836 
2837 	if (fInput.CharsRemaining() == 0)
2838 		return _SetError(ERROR_INVALID);
2839 
2840 	switch (fInput[0]) {
2841 		// function type
2842 		case 'F':
2843 		{
2844 			FunctionNode* functionNode;
2845 			if (!_ParseFunctionType(functionNode))
2846 				return false;
2847 			_node = functionNode;
2848 			return true;
2849 		}
2850 
2851 		// array type
2852 		case 'A':
2853 			return _ParseArrayType(_node);
2854 
2855 		// pointer to member type
2856 		case 'M':
2857 			return _ParsePointerToMemberType(_node);
2858 
2859 		// template param
2860 		case 'T':
2861 			if (!_ParseTemplateParam(_node))
2862 				return false;
2863 			break;
2864 
2865 		// CV qualifiers
2866 		case 'r':
2867 		case 'V':
2868 		case 'K':
2869 		{
2870 			// parse CV qualifiers
2871 			int qualifiers;
2872 			_ParseCVQualifiers(qualifiers);
2873 
2874 			// parse the type
2875 			if (!_ParseType(_node))
2876 				return false;
2877 
2878 			// create the wrapper node
2879 			return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node,
2880 				_node);
2881 		}
2882 
2883 		// pointer, reference, etc.
2884 		case 'P':
2885 			return _ParseTypeWithModifier(TYPE_QUALIFIER_POINTER, 1, _node);
2886 		case 'R':
2887 			return _ParseTypeWithModifier(TYPE_QUALIFIER_REFERENCE, 1,
2888 				_node);
2889 		case 'O':
2890 			return _ParseTypeWithModifier(
2891 				TYPE_QUALIFIER_RVALUE_REFERENCE, 1, _node);
2892 		case 'C':
2893 			return _ParseTypeWithModifier(TYPE_QUALIFIER_COMPLEX, 1, _node);
2894 		case 'G':
2895 			return _ParseTypeWithModifier(TYPE_QUALIFIER_IMAGINARY, 1,
2896 				_node);
2897 
2898 		// pack and decltype
2899 		case 'D':
2900 #if 0
2901 			if (fInput.CharsRemaining() < 2)
2902 				return _SetError(ERROR_INVALID);
2903 
2904 			switch(fInput[1]) {
2905 				case 'p':
2906 					fInput.Skip(2);
2907 					return _ParseType(_node);
2908 				case 't':
2909 				case 'T':
2910 				{
2911 					fInput.Skip(2);
2912 					Node* nameNode;
2913 					if (!_ParseExpression(nameNode))
2914 						return false;
2915 					if (!fInput.SkipPrefix('E'))
2916 						return ERROR_INVALID;
2917 				}
2918 			}
2919 #endif
2920 			// NOTE: Unsupported by the GNU demangler.
2921 			return _SetError(ERROR_UNSUPPORTED);
2922 
2923 		// vendor extended type qualifier
2924 		case 'U':
2925 			fInput.Skip(1);
2926 			Node* name;
2927 			Node* type;
2928 			return _ParseSourceName(name) && _ParseType(type)
2929 				&& NodeCreator<VendorTypeModifierNode>(this)(name, type,
2930 					_node);
2931 
2932 		// substitution
2933 		case 'S':
2934 			if (!fInput.HasPrefix("St")) {
2935 				if (!_ParseSubstitution(_node))
2936 					return false;
2937 				break;
2938 			}
2939 
2940 			// "St" -- the "std" namespace. The grammar is ambiguous here,
2941 			// since we could parse that as <substitution> or as
2942 			// <class-enum-type>. We assume the latter and fall through.
2943 
2944 		default:
2945 		{
2946 			// <class-enum-type> ::= <name>
2947 			Node* nameNode;
2948 			return _ParseName(nameNode)
2949 				&& NodeCreator<NamedTypeNode>(this)(nameNode, _node);
2950 		}
2951 	}
2952 
2953 	// We get here for the types that might be a <template-template-param>.
2954 	// Check whether <template-args> are following.
2955 	if (!fInput.HasPrefix('I'))
2956 		return true;
2957 
2958 	// <template-template-param> is referenceable
2959 	_RegisterReferenceableNode(_node);
2960 
2961 	return _ParseTemplateArgs(_node, _node);
2962 }
2963 
2964 
2965 void
_ParseCVQualifiers(int & qualifiers)2966 Demangler::_ParseCVQualifiers(int& qualifiers)
2967 {
2968 	qualifiers = 0;
2969 
2970 	if (fInput.SkipPrefix('r'))
2971 		qualifiers |= CV_QUALIFIER_RESTRICT;
2972 	if (fInput.SkipPrefix('V'))
2973 		qualifiers |= CV_QUALIFIER_VOLATILE;
2974 	if (fInput.SkipPrefix('K'))
2975 		qualifiers |= CV_QUALIFIER_CONST;
2976 }
2977 
2978 
2979 bool
_ParseTypeWithModifier(type_modifier modifier,int toSkip,Node * & _node)2980 Demangler::_ParseTypeWithModifier(type_modifier modifier, int toSkip,
2981 	Node*& _node)
2982 {
2983 	if (toSkip > 0)
2984 		fInput.Skip(toSkip);
2985 
2986 	Node* node;
2987 	if (!_ParseType(node))
2988 		return false;
2989 
2990 	return NodeCreator<TypeModifierNode>(this)(modifier, node, _node);
2991 }
2992 
2993 
2994 bool
_TryParseBuiltinType(Node * & _node)2995 Demangler::_TryParseBuiltinType(Node*& _node)
2996 {
2997 	DEBUG_SCOPE("_TryParseBuiltinType");
2998 
2999 	// <builtin-type> ::= v	# void
3000 	//                ::= w	# wchar_t
3001 	//                ::= b	# bool
3002 	//                ::= c	# char
3003 	//                ::= a	# signed char
3004 	//                ::= h	# unsigned char
3005 	//                ::= s	# short
3006 	//                ::= t	# unsigned short
3007 	//                ::= i	# int
3008 	//                ::= j	# unsigned int
3009 	//                ::= l	# long
3010 	//                ::= m	# unsigned long
3011 	//                ::= x	# long long, __int64
3012 	//                ::= y	# unsigned long long, __int64
3013 	//                ::= n	# __int128
3014 	//                ::= o	# unsigned __int128
3015 	//                ::= f	# float
3016 	//                ::= d	# double
3017 	//                ::= e	# long double, __float80
3018 	//                ::= g	# __float128
3019 	//                ::= z	# ellipsis
3020 	//                ::= Dd # IEEE 754r decimal floating point (64 bits)
3021 	//                ::= De # IEEE 754r decimal floating point (128 bits)
3022 	//                ::= Df # IEEE 754r decimal floating point (32 bits)
3023 	//                ::= Dh # IEEE 754r half-precision floating point
3024 	//                       # (16 bits)
3025 	//                ::= Di # char32_t
3026 	//                ::= Ds # char16_t
3027 	//                ::= u <source-name>	# vendor extended type
3028 
3029 	if (fInput.CharsRemaining() == 0)
3030 		return false;
3031 
3032 	switch (fInput[0]) {
3033 		case 'v':
3034 			return _CreateTypeNodeAndSkip(TYPE_VOID, 1, _node);
3035 		case 'w':
3036 			return _CreateTypeNodeAndSkip(TYPE_WCHAR_T, 1, _node);
3037 		case 'b':
3038 			return _CreateTypeNodeAndSkip(TYPE_BOOL, 1, _node);
3039 		case 'c':
3040 			return _CreateTypeNodeAndSkip(TYPE_CHAR, 1, _node);
3041 		case 'a':
3042 			return _CreateTypeNodeAndSkip(TYPE_SIGNED_CHAR, 1, _node);
3043 		case 'h':
3044 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_CHAR, 1, _node);
3045 		case 's':
3046 			return _CreateTypeNodeAndSkip(TYPE_SHORT, 1, _node);
3047 		case 't':
3048 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_SHORT, 1,
3049 				_node);
3050 		case 'i':
3051 			return _CreateTypeNodeAndSkip(TYPE_INT, 1, _node);
3052 		case 'j':
3053 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT, 1, _node);
3054 		case 'l':
3055 			return _CreateTypeNodeAndSkip(TYPE_LONG, 1, _node);
3056 		case 'm':
3057 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG, 1, _node);
3058 		case 'x':
3059 			return _CreateTypeNodeAndSkip(TYPE_LONG_LONG, 1, _node);
3060 		case 'y':
3061 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG_LONG, 1, _node);
3062 		case 'n':
3063 			return _CreateTypeNodeAndSkip(TYPE_INT128, 1, _node);
3064 		case 'o':
3065 			return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT128, 1, _node);
3066 		case 'f':
3067 			return _CreateTypeNodeAndSkip(TYPE_FLOAT, 1, _node);
3068 		case 'd':
3069 			return _CreateTypeNodeAndSkip(TYPE_DOUBLE, 1, _node);
3070 		case 'e':
3071 			return _CreateTypeNodeAndSkip(TYPE_LONG_DOUBLE, 1, _node);
3072 		case 'g':
3073 			return _CreateTypeNodeAndSkip(TYPE_FLOAT128, 1, _node);
3074 		case 'z':
3075 			return _CreateTypeNodeAndSkip(TYPE_ELLIPSIS, 1, _node);
3076 
3077 		case 'D':
3078 			if (fInput.CharsRemaining() < 2)
3079 				return false;
3080 
3081 			// TODO: Official names for the __dfloat*!
3082 			switch (fInput[1]) {
3083 				case 'd':
3084 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT64, 2, _node);
3085 				case 'e':
3086 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT128, 2, _node);
3087 				case 'f':
3088 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT32, 2, _node);
3089 				case 'h':
3090 					return _CreateTypeNodeAndSkip(TYPE_DFLOAT16, 2, _node);
3091 				case 'i':
3092 					return _CreateTypeNodeAndSkip(TYPE_CHAR16_T, 2, _node);
3093 				case 's':
3094 					return _CreateTypeNodeAndSkip(TYPE_CHAR32_T, 2, _node);
3095 				default:
3096 					return false;
3097 			}
3098 
3099 		case 'u':
3100 		{
3101 			fInput.Skip(1);
3102 			Node* nameNode;
3103 			return _ParseSourceName(nameNode)
3104 				&& NodeCreator<NamedTypeNode>(this)(nameNode, _node);
3105 		}
3106 
3107 		default:
3108 			return false;
3109 	}
3110 }
3111 
3112 
3113 bool
_ParseFunctionType(FunctionNode * & _node)3114 Demangler::_ParseFunctionType(FunctionNode*& _node)
3115 {
3116 	DEBUG_SCOPE("_ParseFunctionType");
3117 
3118 	// <function-type> ::= F [Y] <bare-function-type> E
3119 
3120 	if (!_SkipExpected('F'))
3121 		return false;
3122 
3123 	// is 'extern "C"'?
3124 	bool isExternC = fInput.SkipPrefix('Y');
3125 
3126 	// create function and parse function type
3127 	if (!NodeCreator<FunctionNode>(this)((Node*)NULL, true, isExternC,
3128 			_node)
3129 		|| !_ParseBareFunctionType(_node)) {
3130 		return false;
3131 	}
3132 
3133 	// skip terminating 'E'
3134 	return _SkipExpected('E');
3135 }
3136 
3137 
3138 bool
_ParseArrayType(Node * & _node)3139 Demangler::_ParseArrayType(Node*& _node)
3140 {
3141 	DEBUG_SCOPE("_ParseArrayType");
3142 
3143 	// <array-type> ::= A <positive dimension number> _ <element type>
3144 	//              ::= A [<dimension expression>] _ <element type>
3145 
3146 	if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('A'))
3147 		return _SetError(ERROR_INVALID);
3148 
3149 	number_type dimensionNumber;
3150 	Node* dimensionExpression = NULL;
3151 
3152 	// If it looks like a number, it must be the first production, otherwise
3153 	// the second one.
3154 	if (isdigit(fInput[0])
3155 		|| (fInput[0] == 'n' && fInput.CharsRemaining() >= 2
3156 			&& isdigit(fInput[1]))) {
3157 		if (!_ParseNumber(dimensionNumber))
3158 			return false;
3159 	} else {
3160 		if (!_ParseExpression(dimensionExpression))
3161 			return false;
3162 	}
3163 
3164 	// parse the type
3165 	Node* type;
3166 	if (!_SkipExpected('_') || !_ParseType(type))
3167 		return false;
3168 
3169 	// create the array node
3170 	return dimensionExpression != NULL
3171 		? NodeCreator<ArrayNode>(this)(type, dimensionExpression, _node)
3172 		: NodeCreator<ArrayNode>(this)(type, dimensionNumber, _node);
3173 }
3174 
3175 
3176 bool
_ParsePointerToMemberType(Node * & _node)3177 Demangler::_ParsePointerToMemberType(Node*& _node)
3178 {
3179 	DEBUG_SCOPE("_ParsePointerToMemberType");
3180 
3181 	// <pointer-to-member-type> ::= M <class type> <member type>
3182 	Node* classType;
3183 	Node* memberType;
3184 	return _SkipExpected('M')
3185 		&& _ParseType(classType)
3186 		&& _ParseType(memberType)
3187 		&& NodeCreator<PointerToMemberNode>(this)(classType, memberType,
3188 			_node);
3189 }
3190 
3191 
3192 bool
_ParseTemplateParam(Node * & _node)3193 Demangler::_ParseTemplateParam(Node*& _node)
3194 {
3195 	DEBUG_SCOPE("_ParseTemplateParam");
3196 
3197 	// <template-param> ::= T_	# first template parameter
3198 	//                  ::= T <parameter-2 non-negative number> _
3199 
3200 	if (!_SkipExpected('T'))
3201 		return false;
3202 	if (fTemplatizedNode == NULL)
3203 		return _SetError(ERROR_INVALID);
3204 
3205 	// get the index;
3206 	number_type index = 0;
3207 	if (!fInput.HasPrefix('_')) {
3208 		if (!_ParseNumber(index))
3209 			return false;
3210 
3211 		if (index < 0)
3212 			return _SetError(ERROR_INVALID);
3213 		index++;
3214 	}
3215 
3216 	if (!_SkipExpected('_'))
3217 		return false;
3218 
3219 	// get the parameter
3220 	Node* parameter = fTemplatizedNode->TemplateParameterAt(index);
3221 	if (parameter == NULL)
3222 		return _SetError(ERROR_INVALID);
3223 
3224 	// create a substitution node
3225 	return NodeCreator<SubstitutionNode>(this)(parameter, _node);
3226 }
3227 
3228 
3229 bool
_ParseSubstitution(Node * & _node)3230 Demangler::_ParseSubstitution(Node*& _node)
3231 {
3232 	DEBUG_SCOPE("_ParseSubstitution");
3233 
3234 	if (!_ParseSubstitutionInternal(_node))
3235 		return false;
3236 
3237 	// substitutions are never referenceable
3238 	_node->SetReferenceable(false);
3239 
3240 	return true;
3241 }
3242 
3243 
3244 bool
_ParseSubstitutionInternal(Node * & _node)3245 Demangler::_ParseSubstitutionInternal(Node*& _node)
3246 {
3247 	DEBUG_SCOPE("_ParseSubstitutionInternal");
3248 
3249 	// <substitution> ::= S <seq-id> _
3250 	//                ::= S_
3251 	//
3252 	// <substitution> ::= St # ::std::
3253 	// <substitution> ::= Sa # ::std::allocator
3254 	// <substitution> ::= Sb # ::std::basic_string
3255 	// <substitution> ::= Ss # ::std::basic_string < char,
3256 	//                         ::std::char_traits<char>,
3257 	//                         ::std::allocator<char> >
3258 	// <substitution> ::= Si # ::std::basic_istream<char,
3259 	//                             std::char_traits<char> >
3260 	// <substitution> ::= So # ::std::basic_ostream<char,
3261 	//                             std::char_traits<char> >
3262 	// <substitution> ::= Sd # ::std::basic_iostream<char,
3263 	//                             std::char_traits<char> >
3264 
3265 	if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('S'))
3266 		return _SetError(ERROR_INVALID);
3267 
3268 	switch (fInput[0]) {
3269 		case 't':
3270 			return _CreateNodeAndSkip("std", 1, _node);
3271 		case 'a':
3272 			return _CreateTypeNodeAndSkip("allocator", "std", NULL, 1,
3273 				_node);
3274 		case 'b':
3275 			return _CreateTypeNodeAndSkip("basic_string", "std", NULL, 1,
3276 				_node);
3277 		case 's':
3278 			return _CreateTypeNodeAndSkip("basic_string", "std",
3279 				"char, std::char_traits<char>, std::allocator<char>", 1,
3280 				_node);
3281 		case 'i':
3282 			return _CreateTypeNodeAndSkip("basic_istream", "std",
3283 				"char, std::char_traits<char>", 1, _node);
3284 		case 'o':
3285 			return _CreateTypeNodeAndSkip("basic_ostream", "std",
3286 				"char, std::char_traits<char>", 1, _node);
3287 		case 'd':
3288 			return _CreateTypeNodeAndSkip("basic_iostream", "std",
3289 				"char, std::char_traits<char>", 1, _node);
3290 		case '_':
3291 			fInput.Skip(1);
3292 			return _CreateSubstitutionNode(0, _node);
3293 	}
3294 
3295 	// parse <seq-id>
3296 	int seqID = 0;
3297 	int count = fInput.CharsRemaining();
3298 	int i = 0;
3299 	for (; i < count && fInput[i] != '_'; i++) {
3300 		char c = fInput[i];
3301 		if (isdigit(c))
3302 			seqID = seqID * 36 + (c - '0');
3303 		else if (c >= 'A' && c <= 'Z')
3304 			seqID = seqID * 36 + 10 + (c - 'A');
3305 		else
3306 			return _SetError(ERROR_INVALID);
3307 	}
3308 
3309 	if (i == count)
3310 		return _SetError(ERROR_INVALID);
3311 
3312 	// skip digits and '_'
3313 	fInput.Skip(i + 1);
3314 
3315 	return _CreateSubstitutionNode(seqID + 1, _node);
3316 }
3317 
3318 
3319 bool
_ParseBareFunctionType(FunctionNode * node)3320 Demangler::_ParseBareFunctionType(FunctionNode* node)
3321 {
3322 	DEBUG_SCOPE("_ParseBareFunctionType");
3323 
3324 	// <bare-function-type> ::= <signature type>+
3325 	//     # types are possible return type, then parameter types
3326 
3327 	if (fInput.CharsRemaining() == 0)
3328 		return _SetError(ERROR_INVALID);
3329 
3330 	do {
3331 		Node* typeNode;
3332 		if (!_ParseType(typeNode))
3333 			return false;
3334 
3335 		node->AddType(typeNode);
3336 	} while (fInput.CharsRemaining() > 0 && fInput[0] != 'E'
3337 		&& fInput[0] != '.');
3338 		// 'E' und '.' delimit <function-type>
3339 
3340 	return true;
3341 }
3342 
3343 
3344 bool
_ParseTemplateArgs(Node * node,Node * & _node)3345 Demangler::_ParseTemplateArgs(Node* node, Node*& _node)
3346 {
3347 	DEBUG_SCOPE("_ParseTemplateArgs");
3348 
3349 	// <template-args> ::= I <template-arg>+ E
3350 
3351 	if (!_SkipExpected('I'))
3352 		return false;
3353 
3354 	// we need at least one <template-arg>
3355 	if (fInput.CharsRemaining() == 0 || fInput[0] == 'E')
3356 		return _SetError(ERROR_INVALID);
3357 
3358 	// create the node
3359 	TemplateNode* templateNode;
3360 	if (!NodeCreator<TemplateNode>(this)(node, templateNode))
3361 		return false;
3362 	_node = templateNode;
3363 
3364 	// parse the args
3365 	while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3366 		Node* arg;
3367 		if (!_ParseTemplateArg(arg))
3368 			return false;
3369 		templateNode->AddArgument(arg);
3370 	}
3371 
3372 	// skip the trailing 'E'
3373 	return _SkipExpected('E');
3374 }
3375 
3376 
3377 bool
_ParseTemplateArg(Node * & _node)3378 Demangler::_ParseTemplateArg(Node*& _node)
3379 {
3380 	DEBUG_SCOPE("_ParseTemplateArg");
3381 
3382 	// <template-arg> ::= <type>			   # type or template
3383 	//                ::= X <expression> E	   # expression
3384 	//                ::= <expr-primary>       # simple expressions
3385 	//                ::= I <template-arg>* E  # argument pack
3386 	//                ::= sp <expression>      # pack expansion of (C++0x)
3387 
3388 	if (fInput.CharsRemaining() == 0)
3389 		return _SetError(ERROR_INVALID);
3390 
3391 	switch (fInput[0]) {
3392 		case 'X':	// X <expression> E
3393 			fInput.Skip(1);
3394 			return _ParseExpression(_node) && _SkipExpected('E');
3395 
3396 		case 'L':	// <expr-primary>
3397 			return _ParseExpressionPrimary(_node);
3398 
3399 		case 'I':	// I <template-arg>* E
3400 		{
3401 #if 0
3402 			fInput.Skip(1);
3403 
3404 			while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3405 				Node* arg;
3406 				if (!_ParseTemplateArg(arg))
3407 					return false;
3408 			}
3409 
3410 			if (!fInput.SkipPrefix('E'))
3411 				return _SetError(ERROR_INVALID);
3412 			return true;
3413 #endif
3414 			// NOTE: Unsupported by the GNU demangler.
3415 			return _SetError(ERROR_UNSUPPORTED);
3416 		}
3417 
3418 		case 's':
3419 			if (fInput.SkipPrefix("sp")) {
3420 				// sp <expression>
3421 #if 0
3422 				return _ParseExpression(_node);
3423 #endif
3424 				// NOTE: Unsupported by the GNU demangler.
3425 				return _SetError(ERROR_UNSUPPORTED);
3426 			}
3427 
3428 			// fall through...
3429 
3430 		default:	// <type>
3431 			return _ParseType(_node);
3432 	}
3433 }
3434 
3435 
3436 bool
_ParseExpression(Node * & _node)3437 Demangler::_ParseExpression(Node*& _node)
3438 {
3439 	DEBUG_SCOPE("_ParseExpression");
3440 
3441 	// <expression> ::= <unary operator-name> <expression>
3442 	//              ::= <binary operator-name> <expression> <expression>
3443 	//              ::= <trinary operator-name> <expression> <expression>
3444 	//                  <expression>
3445 	//              ::= cl <expression>* E          # call
3446 	//              ::= cv <type> expression        # conversion with one
3447 	//                                                argument
3448 	//              ::= cv <type> _ <expression>* E # conversion with a
3449 	//                                                different number of
3450 	//                                                arguments
3451 	//              ::= st <type>		            # sizeof (a type)
3452 	//              ::= at <type>                   # alignof (a type)
3453 	//              ::= <template-param>
3454 	//              ::= <function-param>
3455 	//              ::= sr <type> <unqualified-name>
3456 	//                    # dependent name
3457 	//              ::= sr <type> <unqualified-name> <template-args>
3458 	//                    # dependent template-id
3459 	//              ::= sZ <template-param>
3460 	//                    # size of a parameter pack
3461 	//              ::= <expr-primary>
3462 	//
3463 	// <expr-primary> ::= L <type> <value number> E  # integer literal
3464 	//                ::= L <type <value float> E    # floating literal
3465 	//                ::= L <mangled-name> E         # external name
3466 
3467 	if (fInput.CharsRemaining() == 0)
3468 		return _SetError(ERROR_INVALID);
3469 
3470 	switch (fInput[0]) {
3471 		case 'L':
3472 			return _ParseExpressionPrimary(_node);
3473 		case 'T':
3474 			return _ParseTemplateParam(_node);
3475 		// NOTE: <function-param> is not defined in the specs!
3476 	}
3477 
3478 	// must be an operator
3479 	if (fInput.CharsRemaining() < 2)
3480 		return _SetError(ERROR_INVALID);
3481 
3482 	// some operators need special handling
3483 
3484 	if (fInput.SkipPrefix("cl")) {
3485 		// cl <expression>* E          # call
3486 		CallNode* callNode;
3487 		if (!NodeCreator<CallNode>(this)(callNode))
3488 			return false;
3489 
3490 		while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3491 			Node* subExpression;
3492 			if (!_ParseExpression(subExpression))
3493 				return false;
3494 			callNode->AddSubExpression(subExpression);
3495 		}
3496 
3497 		_node = callNode;
3498 		return _SkipExpected('E');
3499 	}
3500 
3501 	if (fInput.SkipPrefix("cv")) {
3502 		// cv <type> expression        # conversion with one argument
3503 		// cv <type> _ <expression>* E # conversion with a different number
3504 		//                               of arguments
3505 
3506 		// parse the type
3507 		Node* type;
3508 		if (!_ParseType(type))
3509 			return false;
3510 
3511 		// create a conversion expression node
3512 		ConversionExpressionNode* expression;
3513 		if (!NodeCreator<ConversionExpressionNode>(this)(type, expression))
3514 			return false;
3515 		_node = expression;
3516 
3517 		if (fInput.SkipPrefix('_')) {
3518 			// multi argument conversion
3519 			while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') {
3520 				Node* subExpression;
3521 				if (!_ParseExpression(subExpression))
3522 					return false;
3523 				expression->AddSubExpression(subExpression);
3524 			}
3525 
3526 			return _SkipExpected('E');
3527 		}
3528 
3529 		// single argument conversion
3530 		Node* subExpression;
3531 		if (!_ParseExpression(subExpression))
3532 			return false;
3533 		expression->AddSubExpression(subExpression);
3534 
3535 		return true;
3536 	}
3537 
3538 	if (fInput.SkipPrefix("sr")) {
3539 		// sr <type> <unqualified-name>
3540 		// sr <type> <unqualified-name> <template-args>
3541 
3542 		// parse type and unqualified name and create the node
3543 		Node* type;
3544 		Node* name;
3545 		if (!_ParseType(type) || !_ParseUnqualifiedName(name)
3546 			|| !NodeCreator<DependentNameNode>(this)(type, name, _node)) {
3547 			return false;
3548 		}
3549 
3550 		// If there are template arguments left, add them.
3551 		if (!fInput.HasPrefix('I'))
3552 			return true;
3553 
3554 		return _ParseTemplateArgs(_node, _node);
3555 	}
3556 
3557 	if (fInput.SkipPrefix("sZ")) {
3558 		// sZ <template-param>
3559 
3560 		// NOTE: Unsupported by the GNU demangler.
3561 		return _SetError(ERROR_UNSUPPORTED);
3562 	}
3563 
3564 	// no special operator, so have a look for the others
3565 
3566 	const operator_info* info = NULL;
3567 	for (int i = 0; kOperatorInfos[i].name != NULL; i++) {
3568 		if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) {
3569 			info = &kOperatorInfos[i];
3570 			break;
3571 		}
3572 	}
3573 
3574 	// We can only deal with operators with a fixed argument count at this
3575 	// point.
3576 	if (info == NULL || info->argument_count < 0)
3577 		return _SetError(ERROR_INVALID);
3578 
3579 	// create an operator node
3580 	OperatorExpressionNode* operatorNode;
3581 	if (!NodeCreator<OperatorExpressionNode>(this)(info, operatorNode))
3582 		return false;
3583 
3584 	// parse the arguments
3585 	int i = 0;
3586 
3587 	// the first one might be a type
3588 	if ((info->flags & OPERATOR_TYPE_PARAM) != 0) {
3589 		Node* type;
3590 		if (!_ParseType(type))
3591 			return false;
3592 
3593 		operatorNode->AddSubExpression(type);
3594 		i++;
3595 	}
3596 
3597 	// the others are expressions
3598 	for (; i < info->argument_count; i++) {
3599 		Node* subExpression;
3600 		if (!_ParseExpression(subExpression))
3601 			return false;
3602 		operatorNode->AddSubExpression(subExpression);
3603 	}
3604 
3605 	_node = operatorNode;
3606 	return true;
3607 }
3608 
3609 
3610 bool
_ParseExpressionPrimary(Node * & _node)3611 Demangler::_ParseExpressionPrimary(Node*& _node)
3612 {
3613 	DEBUG_SCOPE("_ParseExpressionPrimary");
3614 
3615 	// <expr-primary> ::= L <type> <value number> E  # integer literal
3616 	//                ::= L <type <value float> E    # floating literal
3617 	//                ::= L <mangled-name> E         # external name
3618 
3619 	if (!_SkipExpected('L'))
3620 		return false;
3621 
3622 	if (fInput.SkipPrefix("_Z")) {
3623 		ObjectNode* node;
3624 		if (!_ParseEncoding(node))
3625 			return false;
3626 		_node = node;
3627 	} else {
3628 		// number or float literal
3629 		Node* type;
3630 		if (!_ParseType(type))
3631 			return false;
3632 
3633 		// GNU's demangler doesn't really seem to parse the integer/float,
3634 		// but only replaces a leading 'n' by '-'. Good enough for us, too.
3635 
3636 		// determine the length
3637 		int maxLength = fInput.CharsRemaining();
3638 		int length = 0;
3639 		while (length < maxLength && fInput[length] != 'E')
3640 			length++;
3641 
3642 		if (length == 0)
3643 			return _SetError(ERROR_INVALID);
3644 
3645 		if (!NodeCreator<TypedNumberLiteralNode>(this)(type,
3646 				fInput.String(), length, _node)) {
3647 			return false;
3648 		}
3649 
3650 		fInput.Skip(length);
3651 	}
3652 
3653 	return _SkipExpected('E');
3654 }
3655 
3656 
3657 bool
_ParseNumber(number_type & number)3658 Demangler::_ParseNumber(number_type& number)
3659 {
3660 	DEBUG_SCOPE("_ParseNumber");
3661 
3662 	bool negative = fInput.SkipPrefix('n');
3663 
3664 	if (fInput.CharsRemaining() == 0)
3665 		return _SetError(ERROR_INVALID);
3666 
3667 	number = 0;
3668 	int count = fInput.CharsRemaining();
3669 	int i = 0;
3670 	for (; i < count && isdigit(fInput[i]); i++)
3671 		number = number * 10 + (fInput[i] - '0');
3672 
3673 	fInput.Skip(i);
3674 
3675 	if (negative)
3676 		number =-number;
3677 	return true;
3678 }
3679 
3680 
3681 bool
_CreateNodeAndSkip(const char * name,size_t length,int toSkip,Node * & _node)3682 Demangler::_CreateNodeAndSkip(const char* name, size_t length, int toSkip,
3683 	Node*& _node)
3684 {
3685 	if (toSkip > 0)
3686 		fInput.Skip(toSkip);
3687 
3688 	return NodeCreator<SimpleNameNode>(this)(name, length, _node);
3689 }
3690 
3691 
3692 bool
_CreateNodeAndSkip(const char * name,int toSkip,Node * & _node)3693 Demangler::_CreateNodeAndSkip(const char* name, int toSkip, Node*& _node)
3694 {
3695 	return _CreateNodeAndSkip(name, strlen(name), toSkip, _node);
3696 }
3697 
3698 
3699 bool
_CreateTypeNodeAndSkip(type_type type,int toSkip,Node * & _node)3700 Demangler::_CreateTypeNodeAndSkip(type_type type, int toSkip, Node*& _node)
3701 {
3702 	if (toSkip > 0)
3703 		fInput.Skip(toSkip);
3704 
3705 	return NodeCreator<SimpleTypeNode>(this)(type, _node);
3706 }
3707 
3708 
3709 bool
_CreateTypeNodeAndSkip(const char * name,const char * prefix,const char * templateArgs,int toSkip,Node * & _node)3710 Demangler::_CreateTypeNodeAndSkip(const char* name, const char* prefix,
3711 	const char* templateArgs, int toSkip, Node*& _node)
3712 {
3713 	if (toSkip > 0)
3714 		fInput.Skip(toSkip);
3715 
3716 	// create the name node
3717 	if (!NodeCreator<SimpleTypeNode>(this)(name, _node))
3718 		return false;
3719 
3720 	// add the prefix
3721 	if (prefix != NULL) {
3722 		Node* prefixNode;
3723 		if (!NodeCreator<SimpleTypeNode>(this)(prefix, prefixNode)
3724 			|| !NodeCreator<PrefixedNode>(this)(prefixNode, _node, _node)) {
3725 			return false;
3726 		}
3727 	}
3728 
3729 	// wrap the node to add the template args
3730 	if (templateArgs != NULL) {
3731 		TemplateNode* templateNode;
3732 		Node* argsNode;
3733 		if (!NodeCreator<TemplateNode>(this)(_node, templateNode)
3734 			|| !NodeCreator<SimpleTypeNode>(this)(templateArgs, argsNode)) {
3735 			return false;
3736 		}
3737 		templateNode->AddArgument(argsNode);
3738 		_node = templateNode;
3739 	}
3740 
3741 	return true;
3742 }
3743 
3744 
3745 void
_RegisterReferenceableNode(Node * node)3746 Demangler::_RegisterReferenceableNode(Node* node)
3747 {
3748 	// check, if not referenceable or already registered
3749 	if (!node->IsReferenceable() || node == fLastReferenceableNode
3750 		|| node->NextReferenceable() != NULL) {
3751 		return;
3752 	}
3753 
3754 	if (fFirstReferenceableNode == NULL) {
3755 		fFirstReferenceableNode = node;
3756 		fLastReferenceableNode = node;
3757 	} else {
3758 		fLastReferenceableNode->SetNextReferenceable(node);
3759 		fLastReferenceableNode = node;
3760 	}
3761 }
3762 
3763 
3764 bool
_CreateSubstitutionNode(int index,Node * & _node)3765 Demangler::_CreateSubstitutionNode(int index, Node*& _node)
3766 {
3767 	Node* node = fFirstReferenceableNode;
3768 	while (node != NULL && index > 0) {
3769 		node = node->NextReferenceable();
3770 		index--;
3771 	}
3772 
3773 	if (node == NULL)
3774 		return _SetError(ERROR_INVALID);
3775 
3776 	// create a substitution node
3777 	return NodeCreator<SubstitutionNode>(this)(node, _node);
3778 }
3779 
3780 
3781 // #pragma mark -
3782 
3783 
3784 const char*
demangle_symbol_gcc3(const char * mangledName,char * buffer,size_t bufferSize,bool * _isObjectMethod)3785 demangle_symbol_gcc3(const char* mangledName, char* buffer, size_t bufferSize,
3786 	bool* _isObjectMethod)
3787 {
3788 	bool isObjectMethod;
3789 	if (_isObjectMethod == NULL)
3790 		_isObjectMethod = &isObjectMethod;
3791 
3792 	Demangler demangler;
3793 	DemanglingInfo info(true);
3794 	if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK)
3795 		return NULL;
3796 
3797 	// Set the object method return value. Unless we know for sure that it isn't
3798 	// an object method, we assume that it is.
3799 	switch (info.objectType) {
3800 		case OBJECT_TYPE_DATA:
3801 		case OBJECT_TYPE_FUNCTION:
3802 		case OBJECT_TYPE_METHOD_CLASS:
3803 			*_isObjectMethod = false;
3804 			break;
3805 		case OBJECT_TYPE_METHOD_OBJECT:
3806 			*_isObjectMethod = true;
3807 			break;
3808 		case OBJECT_TYPE_UNKNOWN:
3809 		case OBJECT_TYPE_METHOD_UNKNOWN:
3810 			*_isObjectMethod = strstr(buffer, "::") != NULL;
3811 			break;
3812 	}
3813 
3814 	return buffer;
3815 }
3816 
3817 
3818 status_t
get_next_argument_gcc3(uint32 * _cookie,const char * mangledName,char * name,size_t nameSize,int32 * _type,size_t * _argumentLength)3819 get_next_argument_gcc3(uint32* _cookie, const char* mangledName, char* name,
3820 	size_t nameSize, int32* _type, size_t* _argumentLength)
3821 {
3822 	Demangler demangler;
3823 	ParameterInfo info;
3824 	int result = demangler.GetParameterInfo(mangledName, *_cookie, name,
3825 		nameSize, info);
3826 	if (result != ERROR_OK) {
3827 		switch (result) {
3828 			case ERROR_NOT_MANGLED:
3829 				return B_BAD_VALUE;
3830 			case ERROR_UNSUPPORTED:
3831 				return B_BAD_VALUE;
3832 			case ERROR_INVALID:
3833 				return B_BAD_VALUE;
3834 			case ERROR_BUFFER_TOO_SMALL:
3835 				return B_BUFFER_OVERFLOW;
3836 			case ERROR_NO_MEMORY:
3837 				return B_NO_MEMORY;
3838 			case ERROR_INVALID_PARAMETER_INDEX:
3839 				return B_BAD_INDEX;
3840 			case ERROR_INTERNAL:
3841 			default:
3842 				return B_ERROR;
3843 		}
3844 	}
3845 
3846 	// translate the type
3847 	switch (info.type.type) {
3848 		case TYPE_BOOL:
3849 			*_type = B_BOOL_TYPE;
3850 			*_argumentLength = 1;
3851 			break;
3852 
3853 		case TYPE_CHAR:
3854 			*_type = B_CHAR_TYPE;
3855 			*_argumentLength = 1;
3856 			break;
3857 
3858 		case TYPE_SIGNED_CHAR:
3859 			*_type = B_INT8_TYPE;
3860 			*_argumentLength = 1;
3861 			break;
3862 		case TYPE_UNSIGNED_CHAR:
3863 			*_type = B_UINT8_TYPE;
3864 			*_argumentLength = 1;
3865 			break;
3866 
3867 		case TYPE_SHORT:
3868 			*_type = B_INT16_TYPE;
3869 			*_argumentLength = 2;
3870 			break;
3871 		case TYPE_UNSIGNED_SHORT:
3872 			*_type = B_UINT16_TYPE;
3873 			*_argumentLength = 2;
3874 			break;
3875 
3876 		case TYPE_INT:
3877 			*_type = B_INT32_TYPE;
3878 			*_argumentLength = 4;
3879 			break;
3880 		case TYPE_UNSIGNED_INT:
3881 			*_type = B_UINT32_TYPE;
3882 			*_argumentLength = 4;
3883 			break;
3884 
3885 		case TYPE_LONG:
3886 			*_type = sizeof(long) == 4 ? B_INT32_TYPE : B_INT64_TYPE;
3887 			*_argumentLength = sizeof(long);
3888 			break;
3889 		case TYPE_UNSIGNED_LONG:
3890 			*_type = sizeof(long) == 4 ? B_UINT32_TYPE : B_UINT64_TYPE;
3891 			*_argumentLength = sizeof(long);
3892 			break;
3893 
3894 		case TYPE_LONG_LONG:
3895 			*_type = B_INT64_TYPE;
3896 			*_argumentLength = 8;
3897 			break;
3898 		case TYPE_UNSIGNED_LONG_LONG:
3899 			*_type = B_INT64_TYPE;
3900 			*_argumentLength = 8;
3901 			break;
3902 
3903 		case TYPE_INT128:
3904 			*_type = 0;
3905 			*_argumentLength = 16;
3906 			break;
3907 		case TYPE_UNSIGNED_INT128:
3908 			*_type = 0;
3909 			*_argumentLength = 16;
3910 			break;
3911 
3912 		case TYPE_FLOAT:
3913 			*_type = B_FLOAT_TYPE;
3914 			*_argumentLength = sizeof(float);
3915 			break;
3916 		case TYPE_DOUBLE:
3917 			*_type = B_DOUBLE_TYPE;
3918 			*_argumentLength = sizeof(double);
3919 			break;
3920 
3921 		case TYPE_LONG_DOUBLE:
3922 			*_type = 0;
3923 			*_argumentLength = sizeof(long double);
3924 			break;
3925 
3926 		case TYPE_FLOAT128:
3927 			*_type = 0;
3928 			*_argumentLength = 16;
3929 			break;
3930 
3931 		case TYPE_DFLOAT16:
3932 			*_argumentLength = 2;
3933 		case TYPE_DFLOAT32:
3934 			*_argumentLength *= 2;
3935 		case TYPE_DFLOAT64:
3936 			*_argumentLength *= 2;
3937 		case TYPE_DFLOAT128:
3938 			*_argumentLength *= 2;
3939 			*_type = 0;
3940 			break;
3941 
3942 		case TYPE_CHAR16_T:
3943 			*_type = B_UINT16_TYPE;
3944 			*_argumentLength = 2;
3945 			break;
3946 
3947 		case TYPE_CHAR32_T:
3948 			*_type = B_UINT32_TYPE;
3949 			*_argumentLength = 2;
3950 			break;
3951 
3952 		case TYPE_CONST_CHAR_POINTER:
3953 			*_type = B_STRING_TYPE;
3954 			*_argumentLength = sizeof(void*);
3955 			break;
3956 
3957 		case TYPE_POINTER:
3958 			*_type = B_POINTER_TYPE;
3959 			*_argumentLength = sizeof(void*);
3960 			break;
3961 
3962 		case TYPE_REFERENCE:
3963 			*_type = B_REF_TYPE;
3964 				// TODO: That's actually entry_ref!
3965 			*_argumentLength = sizeof(void*);
3966 			break;
3967 
3968 		case TYPE_WCHAR_T:
3969 			// TODO: Type/size might change!
3970 			*_type = B_UINT16_TYPE;
3971 			*_argumentLength = 2;
3972 			break;
3973 
3974 		case TYPE_UNKNOWN:
3975 		case TYPE_ELLIPSIS:
3976 		case TYPE_VOID:
3977 		default:
3978 			// Well, tell our caller *something*.
3979 			*_type = 0;
3980 			*_argumentLength = sizeof(int);
3981 	}
3982 
3983 	// assume sizeof(int) argument alignment
3984 	if (*_argumentLength < sizeof(int))
3985 		*_argumentLength = sizeof(int);
3986 
3987 	++*_cookie;
3988 	return B_OK;
3989 }
3990 
3991 
3992 #ifndef _KERNEL_MODE
3993 
3994 const char*
demangle_name_gcc3(const char * mangledName,char * buffer,size_t bufferSize)3995 demangle_name_gcc3(const char* mangledName, char* buffer, size_t bufferSize)
3996 {
3997 	Demangler demangler;
3998 	DemanglingInfo info(false);
3999 	if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK)
4000 		return NULL;
4001 	return buffer;
4002 }
4003 
4004 #endif
4005