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
50typedef long number_type;
51
52enum {
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
64enum 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
74enum prefix_type {
75	PREFIX_NONE,
76	PREFIX_NAMESPACE,
77	PREFIX_CLASS,
78	PREFIX_UNKNOWN
79};
80
81// type classification
82enum 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
117const 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
154enum {
155	CV_QUALIFIER_RESTRICT	= 0x1,
156	CV_QUALIFIER_VOLATILE	= 0x2,
157	CV_QUALIFIER_CONST		= 0x4
158};
159
160enum 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
168static const char* const kTypeModifierSuffixes[] = {
169	"*",
170	"&",
171	"&&",
172	" complex",
173	" imaginary"
174};
175
176struct operator_info {
177	const char*	mangled_name;
178	const char*	name;
179	int			argument_count;
180	int			flags;
181};
182
183// operator flags
184enum {
185	OPERATOR_TYPE_PARAM		= 0x01,
186	OPERATOR_IS_MEMBER		= 0x02
187};
188
189
190static 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
248struct DebugScope {
249	DebugScope(const char* functionName, const char* remainingString = NULL)
250		:
251		fParent(sGlobalScope),
252		fFunctionName(functionName),
253		fLevel(fParent != NULL ? fParent->fLevel + 1 : 0)
254	{
255		sGlobalScope = this;
256		if (remainingString != NULL) {
257			PRINT("%*s%s(): \"%s\"\n", fLevel * 2, "", fFunctionName,
258				remainingString);
259		} else
260			PRINT("%*s%s()\n", fLevel * 2, "", fFunctionName);
261	}
262
263	~DebugScope()
264	{
265		sGlobalScope = fParent;
266		PRINT("%*s%s() done\n", fLevel * 2, "", fFunctionName);
267	}
268
269	static void Print(const char* format,...)
270	{
271		int level = sGlobalScope != NULL ? sGlobalScope->fLevel : 0;
272
273		va_list args;
274		va_start(args, format);
275		PRINT("%*s", (level + 1) * 2, "");
276		VPRINT(format, args);
277		va_end(args);
278	}
279
280private:
281	DebugScope*	fParent;
282	const char*	fFunctionName;
283	int			fLevel;
284
285	static DebugScope* sGlobalScope;
286};
287
288DebugScope* DebugScope::sGlobalScope = NULL;
289
290#endif	// TRACE_GCC3_DEMANGLER
291
292
293class Input {
294public:
295	Input()
296		:
297		fString(NULL),
298		fLength(0)
299	{
300	}
301
302	void SetTo(const char* string, size_t length)
303	{
304		fString = string;
305		fLength = length;
306	}
307
308	const char* String() const
309	{
310		return fString;
311	}
312
313	int CharsRemaining() const
314	{
315		return fLength;
316	}
317
318	void Skip(size_t count)
319	{
320		if (count > fLength) {
321			PRINT("Input::Skip(): fOffset > fLength\n");
322			return;
323		}
324
325		fString += count;
326		fLength -= count;
327	}
328
329	bool HasPrefix(char prefix) const
330	{
331		return fLength > 0 && fString[0] == prefix;
332	}
333
334	bool HasPrefix(const char* prefix) const
335	{
336		size_t prefixLen = strlen(prefix);
337		return prefixLen <= fLength
338			&& strncmp(fString, prefix, strlen(prefix)) == 0;
339	}
340
341	bool SkipPrefix(char prefix)
342	{
343		if (!HasPrefix(prefix))
344			return false;
345
346		fString++;
347		fLength--;
348		return true;
349	}
350
351	bool SkipPrefix(const char* prefix)
352	{
353		size_t prefixLen = strlen(prefix);
354		if (prefixLen <= fLength && strncmp(fString, prefix, prefixLen) != 0)
355			return false;
356
357		fString += prefixLen;
358		fLength -= prefixLen;
359		return true;
360	}
361
362	char operator[](size_t index) const
363	{
364		if (index >= fLength) {
365			PRINT("Input::operator[](): fOffset + index >= fLength\n");
366			return '\0';
367		}
368
369		return fString[index];
370	}
371
372private:
373	const char*	fString;
374	size_t		fLength;
375};
376
377
378class NameBuffer {
379public:
380	NameBuffer(char* buffer, size_t size)
381		:
382		fBuffer(buffer),
383		fSize(size),
384		fLength(0),
385		fOverflow(false)
386	{
387	}
388
389	bool IsEmpty() const
390	{
391		return fLength == 0;
392	}
393
394	char LastChar() const
395	{
396		return fLength > 0 ? fBuffer[fLength - 1] : '\0';
397	}
398
399	bool HadOverflow() const
400	{
401		return fOverflow;
402	}
403
404	char* Terminate()
405	{
406		fBuffer[fLength] = '\0';
407		return fBuffer;
408	}
409
410	bool Append(const char* string, size_t length)
411	{
412		if (fLength + length >= fSize) {
413			fOverflow = true;
414			return false;
415		}
416
417		memcpy(fBuffer + fLength, string, length);
418		fLength += length;
419		return true;
420	}
421
422	bool Append(const char* string)
423	{
424		return Append(string, strlen(string));
425	}
426
427private:
428	char*	fBuffer;
429	size_t	fSize;
430	size_t	fLength;
431	bool	fOverflow;
432};
433
434
435struct TypeInfo {
436	type_type	type;
437	int			cvQualifiers;
438
439	TypeInfo()
440		:
441		type(TYPE_UNKNOWN),
442		cvQualifiers(0)
443	{
444	}
445
446	TypeInfo(type_type type)
447		:
448		type(type),
449		cvQualifiers(0)
450	{
451	}
452
453	TypeInfo(const TypeInfo& other, int cvQualifiers = 0)
454		:
455		type(other.type),
456		cvQualifiers(other.cvQualifiers | cvQualifiers)
457	{
458	}
459
460	TypeInfo& operator=(const TypeInfo& other)
461	{
462		type = other.type;
463		cvQualifiers = other.cvQualifiers;
464		return *this;
465	}
466};
467
468
469struct DemanglingParameters {
470	bool	objectNameOnly;
471
472	DemanglingParameters(bool objectNameOnly)
473		:
474		objectNameOnly(objectNameOnly)
475	{
476	}
477};
478
479
480struct DemanglingInfo : DemanglingParameters {
481	object_type	objectType;
482
483	DemanglingInfo(bool objectNameOnly)
484		:
485		DemanglingParameters(objectNameOnly),
486		objectType(OBJECT_TYPE_UNKNOWN)
487	{
488	}
489};
490
491
492struct ParameterInfo {
493	TypeInfo	type;
494
495	ParameterInfo()
496	{
497	}
498};
499
500
501class Node;
502
503struct NameDecorationInfo {
504	const Node*	firstDecorator;
505	const Node*	closestCVDecoratorList;
506
507	NameDecorationInfo(const Node* decorator)
508		:
509		firstDecorator(decorator),
510		closestCVDecoratorList(NULL)
511	{
512	}
513};
514
515struct CVQualifierInfo {
516	const Node*	firstCVQualifier;
517	const Node*	firstNonCVQualifier;
518
519	CVQualifierInfo()
520		:
521		firstCVQualifier(NULL),
522		firstNonCVQualifier(NULL)
523	{
524	}
525};
526
527
528class Node {
529public:
530	Node()
531		:
532		fNextAllocated(NULL),
533		fParent(NULL),
534		fNext(NULL),
535		fNextReferenceable(NULL),
536		fReferenceable(true)
537	{
538	}
539
540	virtual ~Node()
541	{
542	}
543
544	Node* NextAllocated() const			{ return fNextAllocated; }
545	void SetNextAllocated(Node* node)	{ fNextAllocated = node; }
546
547	Node* Parent() const				{ return fParent; }
548	virtual void SetParent(Node* node)	{ fParent = node; }
549
550	Node* Next() const			{ return fNext; }
551	void SetNext(Node* node)	{ fNext = node; }
552
553	bool IsReferenceable() const		{ return fReferenceable; }
554	void SetReferenceable(bool flag)	{ fReferenceable = flag; }
555
556	Node* NextReferenceable() const			{ return fNextReferenceable; }
557	void SetNextReferenceable(Node* node)	{ fNextReferenceable = node; }
558
559	virtual bool GetName(NameBuffer& buffer) const = 0;
560
561	virtual bool GetDecoratedName(NameBuffer& buffer,
562		NameDecorationInfo& decorationInfo) const
563	{
564		if (!GetName(buffer))
565			return false;
566
567		return decorationInfo.firstDecorator == NULL
568			|| decorationInfo.firstDecorator->AddDecoration(buffer, NULL);
569	}
570
571	virtual bool AddDecoration(NameBuffer& buffer,
572		const Node* stopDecorator) const
573	{
574		return true;
575	}
576
577	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
578	{
579		info.firstNonCVQualifier = this;
580	}
581
582	virtual Node* GetUnqualifiedNode(Node* beforeNode)
583	{
584		return this;
585	}
586
587	virtual bool IsTemplatized() const
588	{
589		return false;
590	}
591
592	virtual Node* TemplateParameterAt(int index) const
593	{
594		return NULL;
595	}
596
597	virtual bool IsNoReturnValueFunction() const
598	{
599		return false;
600	}
601
602	virtual bool IsTypeName(const char* name, size_t length) const
603	{
604		return false;
605	}
606
607	virtual object_type ObjectType() const
608	{
609		return OBJECT_TYPE_UNKNOWN;
610	}
611
612	virtual prefix_type PrefixType() const
613	{
614		return PREFIX_NONE;
615	}
616
617	virtual TypeInfo Type() const
618	{
619		return TypeInfo();
620	}
621
622private:
623	Node*	fNextAllocated;
624	Node*	fParent;
625	Node*	fNext;
626	Node*	fNextReferenceable;
627	bool	fReferenceable;
628};
629
630
631class NamedTypeNode : public Node {
632public:
633	NamedTypeNode(Node* name)
634		:
635		fName(name)
636	{
637		if (fName != NULL)
638			fName->SetParent(this);
639	}
640
641	virtual bool GetName(NameBuffer& buffer) const
642	{
643		return fName == NULL || fName->GetName(buffer);
644	}
645
646	virtual bool IsNoReturnValueFunction() const
647	{
648		return fName != NULL && fName->IsNoReturnValueFunction();
649	}
650
651	virtual TypeInfo Type() const
652	{
653		return fName != NULL ? fName->Type() : TypeInfo();
654	}
655
656protected:
657	Node*	fName;
658};
659
660
661class SubstitutionNode : public Node {
662public:
663	SubstitutionNode(Node* node)
664		:
665		fNode(node)
666	{
667	}
668
669	virtual bool GetName(NameBuffer& buffer) const
670	{
671		return fNode->GetName(buffer);
672	}
673
674	virtual bool GetDecoratedName(NameBuffer& buffer,
675		NameDecorationInfo& decorationInfo) const
676	{
677		return fNode->GetDecoratedName(buffer, decorationInfo);
678	}
679
680	virtual bool AddDecoration(NameBuffer& buffer,
681		const Node* stopDecorator) const
682	{
683		return fNode->AddDecoration(buffer, stopDecorator);
684	}
685
686	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
687	{
688		fNode->GetCVQualifierInfo(info);
689	}
690
691	virtual bool IsTemplatized() const
692	{
693		return fNode->IsTemplatized();
694	}
695
696	virtual Node* TemplateParameterAt(int index) const
697	{
698		return fNode->TemplateParameterAt(index);
699	}
700
701	virtual bool IsNoReturnValueFunction() const
702	{
703		return fNode->IsNoReturnValueFunction();
704	}
705
706	virtual bool IsTypeName(const char* name, size_t length) const
707	{
708		return fNode->IsTypeName(name, length);
709	}
710
711	virtual object_type ObjectType() const
712	{
713		return fNode->ObjectType();
714	}
715
716	virtual prefix_type PrefixType() const
717	{
718		return fNode->PrefixType();
719	}
720
721	virtual TypeInfo Type() const
722	{
723		return fNode->Type();
724	}
725
726private:
727	Node*	fNode;
728};
729
730
731class ArrayNode : public NamedTypeNode {
732public:
733	ArrayNode(Node* type, int dimension)
734		:
735		NamedTypeNode(type),
736		fDimensionExpression(NULL),
737		fDimensionNumber(dimension)
738	{
739	}
740
741	ArrayNode(Node* type, Node* dimension)
742		:
743		NamedTypeNode(type),
744		fDimensionExpression(dimension),
745		fDimensionNumber(0)
746	{
747		fDimensionExpression->SetParent(this);
748	}
749
750	virtual bool GetName(NameBuffer& buffer) const
751	{
752		if (!fName->GetName(buffer))
753			return false;
754
755		buffer.Append("[", 1);
756
757		if (fDimensionExpression != NULL) {
758			if (!fDimensionExpression->GetName(buffer))
759				return false;
760		} else {
761			char stringBuffer[16];
762			snprintf(stringBuffer, sizeof(stringBuffer), "%d",
763				fDimensionNumber);
764			buffer.Append(stringBuffer);
765		}
766
767		return buffer.Append("]", 1);
768	}
769
770	virtual object_type ObjectType() const
771	{
772		return OBJECT_TYPE_DATA;
773	}
774
775	virtual TypeInfo Type() const
776	{
777// TODO: Check!
778		return TypeInfo(TYPE_POINTER);
779	}
780
781
782private:
783	Node*	fDimensionExpression;
784	int		fDimensionNumber;
785};
786
787
788class ObjectNode : public NamedTypeNode {
789public:
790	ObjectNode(Node* name)
791		:
792		NamedTypeNode(name)
793	{
794	}
795
796	virtual bool GetObjectName(NameBuffer& buffer,
797		const DemanglingParameters& parameters)
798	{
799		if (parameters.objectNameOnly)
800			return fName != NULL ? fName->GetName(buffer) : true;
801
802		return GetName(buffer);
803	}
804
805	virtual object_type ObjectType() const
806	{
807		return OBJECT_TYPE_DATA;
808	}
809
810	virtual Node* ParameterAt(uint32 index) const
811	{
812		return NULL;
813	}
814};
815
816
817class SimpleNameNode : public Node {
818public:
819	SimpleNameNode(const char* name)
820		:
821		fName(name),
822		fLength(strlen(name))
823	{
824	}
825
826	SimpleNameNode(const char* name, size_t length)
827		:
828		fName(name),
829		fLength(length)
830	{
831	}
832
833	virtual bool GetName(NameBuffer& buffer) const
834	{
835		return buffer.Append(fName, fLength);
836	}
837
838protected:
839	const char*	fName;
840	size_t		fLength;
841};
842
843
844class SimpleTypeNode : public SimpleNameNode {
845public:
846	SimpleTypeNode(const char* name)
847		:
848		SimpleNameNode(name),
849		fType(TYPE_UNKNOWN)
850	{
851	}
852
853	SimpleTypeNode(type_type type)
854		:
855		SimpleNameNode(kTypeNames[type]),
856		fType(type)
857	{
858	}
859
860	virtual bool IsTypeName(const char* name, size_t length) const
861	{
862		return fLength == length && strcmp(fName, name) == 0;
863	}
864
865	virtual object_type ObjectType() const
866	{
867		return OBJECT_TYPE_DATA;
868	}
869
870	virtual TypeInfo Type() const
871	{
872		return TypeInfo(fType);
873	}
874
875private:
876	type_type	fType;
877};
878
879
880class TypedNumberLiteralNode : public Node {
881public:
882	TypedNumberLiteralNode(Node* type, const char* number, size_t length)
883		:
884		fType(type),
885		fNumber(number),
886		fLength(length)
887	{
888		fType->SetParent(this);
889	}
890
891	virtual bool GetName(NameBuffer& buffer) const
892	{
893		// If the type is bool and the number is 0 or 1, we use "false" or
894		// "true" respectively.
895		if (fType->IsTypeName("bool", 4) && fLength == 1
896			&& (fNumber[0] == '0' || fNumber[0] == '1')) {
897			return buffer.Append(fNumber[0] == '0' ? "false" : "true");
898		}
899
900		// Add the type in parentheses. The GNU demangler omits "int", so do we.
901		if (!fType->IsTypeName("int", 3)) {
902			buffer.Append("(");
903			if (!fType->GetName(buffer))
904				return false;
905			buffer.Append(")");
906		}
907
908		// add the number -- replace a leading 'n' by '-', if necessary
909		if (fLength > 0 && fNumber[0] == 'n') {
910			buffer.Append("-");
911			return buffer.Append(fNumber + 1, fLength - 1);
912		}
913
914		return buffer.Append(fNumber, fLength);
915	}
916
917	virtual object_type ObjectType() const
918	{
919		return OBJECT_TYPE_DATA;
920	}
921
922private:
923	Node*		fType;
924	const char*	fNumber;
925	size_t		fLength;
926};
927
928
929class XtructorNode : public Node {
930public:
931	XtructorNode(bool constructor, char type)
932		:
933		fConstructor(constructor),
934		fType(type)
935	{
936	}
937
938	virtual void SetParent(Node* node)
939	{
940		fUnqualifiedNode = node->GetUnqualifiedNode(this);
941		Node::SetParent(node);
942	}
943
944	virtual bool GetName(NameBuffer& buffer) const
945	{
946		if (fUnqualifiedNode == NULL)
947			return false;
948
949		if (!fConstructor)
950			buffer.Append("~");
951
952		return fUnqualifiedNode->GetName(buffer);
953	}
954
955	virtual bool IsNoReturnValueFunction() const
956	{
957		return true;
958	}
959
960	virtual object_type ObjectType() const
961	{
962		return OBJECT_TYPE_METHOD_CLASS;
963	}
964
965private:
966	bool		fConstructor;
967	char		fType;
968	Node*		fUnqualifiedNode;
969};
970
971
972class SpecialNameNode : public Node {
973public:
974	SpecialNameNode(const char* name, Node* child)
975		:
976		fName(name),
977		fChild(child)
978	{
979		fChild->SetParent(this);
980	}
981
982	virtual bool GetName(NameBuffer& buffer) const
983	{
984		return buffer.Append(fName) && fChild->GetName(buffer);
985	}
986
987protected:
988	const char*	fName;
989	Node*		fChild;
990};
991
992
993class DecoratingNode : public Node {
994public:
995	DecoratingNode(Node* child)
996		:
997		fChildNode(child)
998	{
999		fChildNode->SetParent(this);
1000	}
1001
1002	virtual bool GetName(NameBuffer& buffer) const
1003	{
1004		NameDecorationInfo decorationInfo(this);
1005		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1006	}
1007
1008	virtual bool GetDecoratedName(NameBuffer& buffer,
1009		NameDecorationInfo& decorationInfo) const
1010	{
1011		decorationInfo.closestCVDecoratorList = NULL;
1012		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1013	}
1014
1015protected:
1016	Node*	fChildNode;
1017};
1018
1019
1020class CVQualifiersNode : public DecoratingNode {
1021public:
1022	CVQualifiersNode(int qualifiers, Node* child)
1023		:
1024		DecoratingNode(child),
1025		fCVQualifiers(qualifiers)
1026	{
1027	}
1028
1029	virtual bool GetDecoratedName(NameBuffer& buffer,
1030		NameDecorationInfo& decorationInfo) const
1031	{
1032		if (decorationInfo.closestCVDecoratorList == NULL)
1033			decorationInfo.closestCVDecoratorList = this;
1034		return fChildNode->GetDecoratedName(buffer, decorationInfo);
1035	}
1036
1037	virtual bool AddDecoration(NameBuffer& buffer,
1038		const Node* stopDecorator) const
1039	{
1040		if (this == stopDecorator)
1041			return true;
1042
1043		if (!fChildNode->AddDecoration(buffer, stopDecorator))
1044			return false;
1045
1046		if ((fCVQualifiers & CV_QUALIFIER_RESTRICT) != 0)
1047			buffer.Append(" restrict");
1048		if ((fCVQualifiers & CV_QUALIFIER_VOLATILE) != 0)
1049			buffer.Append(" volatile");
1050		if ((fCVQualifiers & CV_QUALIFIER_CONST) != 0)
1051			buffer.Append(" const");
1052
1053		return true;
1054	}
1055
1056	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
1057	{
1058		if (info.firstCVQualifier == NULL)
1059			info.firstCVQualifier = this;
1060		fChildNode->GetCVQualifierInfo(info);
1061	}
1062
1063	virtual bool IsTemplatized() const
1064	{
1065		return fChildNode->IsTemplatized();
1066	}
1067
1068	virtual Node* TemplateParameterAt(int index) const
1069	{
1070		return fChildNode->TemplateParameterAt(index);
1071	}
1072
1073	virtual bool IsNoReturnValueFunction() const
1074	{
1075		return fChildNode->IsNoReturnValueFunction();
1076	}
1077
1078	virtual object_type ObjectType() const
1079	{
1080		return fChildNode->ObjectType();
1081	}
1082
1083	virtual prefix_type PrefixType() const
1084	{
1085		return fChildNode->PrefixType();
1086	}
1087
1088	virtual TypeInfo Type() const
1089	{
1090		return TypeInfo(fChildNode->Type(), fCVQualifiers);
1091	}
1092
1093private:
1094	int		fCVQualifiers;
1095};
1096
1097
1098class TypeModifierNode : public DecoratingNode {
1099public:
1100	TypeModifierNode(type_modifier modifier, Node* child)
1101		:
1102		DecoratingNode(child),
1103		fModifier(modifier)
1104	{
1105	}
1106
1107	virtual bool AddDecoration(NameBuffer& buffer,
1108		const Node* stopDecorator) const
1109	{
1110		if (this == stopDecorator)
1111			return true;
1112
1113		return fChildNode->AddDecoration(buffer, stopDecorator)
1114			&& buffer.Append(kTypeModifierSuffixes[fModifier]);
1115	}
1116
1117	virtual object_type ObjectType() const
1118	{
1119		return OBJECT_TYPE_DATA;
1120	}
1121
1122	virtual TypeInfo Type() const
1123	{
1124		TypeInfo type = fChildNode->Type();
1125		if (type.type == TYPE_CHAR
1126			&& (type.cvQualifiers & CV_QUALIFIER_CONST) != 0) {
1127			return TypeInfo(TYPE_CONST_CHAR_POINTER);
1128		}
1129
1130		switch (fModifier) {
1131			case TYPE_QUALIFIER_POINTER:
1132				return TypeInfo(TYPE_POINTER);
1133			case TYPE_QUALIFIER_REFERENCE:
1134				return TypeInfo(TYPE_REFERENCE);
1135			default:
1136				return TypeInfo();
1137		}
1138	}
1139
1140private:
1141	type_modifier	fModifier;
1142};
1143
1144
1145class VendorTypeModifierNode : public DecoratingNode {
1146public:
1147	VendorTypeModifierNode(Node* name, Node* child)
1148		:
1149		DecoratingNode(child),
1150		fName(name)
1151	{
1152		fName->SetParent(this);
1153	}
1154
1155	virtual bool AddDecoration(NameBuffer& buffer,
1156		const Node* stopDecorator) const
1157	{
1158		if (this == stopDecorator)
1159			return true;
1160
1161		return fChildNode->AddDecoration(buffer, stopDecorator)
1162			&& buffer.Append(" ")
1163			&& fName->GetName(buffer);
1164	}
1165
1166	virtual object_type ObjectType() const
1167	{
1168		return OBJECT_TYPE_DATA;
1169	}
1170
1171private:
1172	Node*	fName;
1173};
1174
1175
1176class OperatorNode : public Node {
1177public:
1178	OperatorNode(const operator_info* info)
1179		:
1180		fInfo(info)
1181	{
1182		SetReferenceable(false);
1183	}
1184
1185	virtual bool GetName(NameBuffer& buffer) const
1186	{
1187		return buffer.Append(
1188				isalpha(fInfo->name[0]) ?  "operator " : "operator")
1189			&& buffer.Append(fInfo->name);
1190	}
1191
1192	virtual object_type ObjectType() const
1193	{
1194		return (fInfo->flags & OPERATOR_IS_MEMBER) != 0
1195			? OBJECT_TYPE_METHOD_CLASS : OBJECT_TYPE_UNKNOWN;
1196	}
1197
1198private:
1199	const operator_info*	fInfo;
1200};
1201
1202
1203class VendorOperatorNode : public Node {
1204public:
1205	VendorOperatorNode(Node* name)
1206		:
1207		fName(name)
1208	{
1209		fName->SetParent(this);
1210		SetReferenceable(false);
1211	}
1212
1213	virtual bool GetName(NameBuffer& buffer) const
1214	{
1215		return buffer.Append("operator ")
1216			&& fName->GetName(buffer);
1217	}
1218
1219private:
1220	Node*	fName;
1221};
1222
1223
1224class CastOperatorNode : public Node {
1225public:
1226	CastOperatorNode(Node* child)
1227		:
1228		fChildNode(child)
1229	{
1230		fChildNode->SetParent(this);
1231	}
1232
1233	virtual bool GetName(NameBuffer& buffer) const
1234	{
1235		return buffer.Append("operator ") && fChildNode->GetName(buffer);
1236	}
1237
1238	virtual bool IsNoReturnValueFunction() const
1239	{
1240		return true;
1241	}
1242
1243	virtual object_type ObjectType() const
1244	{
1245		return OBJECT_TYPE_METHOD_OBJECT;
1246	}
1247
1248private:
1249	Node*	fChildNode;
1250};
1251
1252
1253class PrefixedNode : public Node {
1254public:
1255	PrefixedNode(Node* prefix, Node* node)
1256		:
1257		fPrefixNode(prefix),
1258		fNode(node)
1259	{
1260		fPrefixNode->SetParent(this);
1261		fNode->SetParent(this);
1262	}
1263
1264	virtual bool GetName(NameBuffer& buffer) const
1265	{
1266		if (!fPrefixNode->GetName(buffer))
1267			return false;
1268
1269		buffer.Append("::");
1270		return fNode->GetName(buffer);
1271	}
1272
1273	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1274	{
1275		return beforeNode == fNode
1276			? fPrefixNode->GetUnqualifiedNode(beforeNode)
1277			: fNode->GetUnqualifiedNode(beforeNode);
1278	}
1279
1280	virtual bool IsNoReturnValueFunction() const
1281	{
1282		return fNode->IsNoReturnValueFunction();
1283	}
1284
1285	virtual object_type ObjectType() const
1286	{
1287		return fNode->ObjectType();
1288	}
1289
1290	virtual prefix_type PrefixType() const
1291	{
1292		return PREFIX_UNKNOWN;
1293	}
1294
1295private:
1296	Node*	fPrefixNode;
1297	Node*	fNode;
1298};
1299
1300
1301class ClonedNode : public ObjectNode {
1302public:
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
1313	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
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
1335	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1336	{
1337		return beforeNode == fCloneNode
1338			? fNode->GetUnqualifiedNode(beforeNode)
1339			: fCloneNode->GetUnqualifiedNode(beforeNode);
1340	}
1341
1342	virtual bool IsNoReturnValueFunction() const
1343	{
1344		return fNode->IsNoReturnValueFunction();
1345	}
1346
1347	virtual object_type ObjectType() const
1348	{
1349		return fNode->ObjectType();
1350	}
1351
1352	virtual prefix_type PrefixType() const
1353	{
1354		return PREFIX_UNKNOWN;
1355	}
1356
1357	virtual Node* ParameterAt(uint32 index) const
1358	{
1359		return fNode->ParameterAt(index);
1360	}
1361
1362private:
1363	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
1372private:
1373	ObjectNode*	fNode;
1374	Node*		fCloneNode;
1375};
1376
1377
1378typedef PrefixedNode DependentNameNode;
1379
1380
1381class TemplateNode : public Node {
1382public:
1383	TemplateNode(Node* base)
1384		:
1385		fBase(base),
1386		fFirstArgument(NULL),
1387		fLastArgument(NULL)
1388	{
1389		fBase->SetParent(this);
1390	}
1391
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
1405	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
1430	virtual Node* GetUnqualifiedNode(Node* beforeNode)
1431	{
1432		return fBase != beforeNode
1433			? fBase->GetUnqualifiedNode(beforeNode) : this;
1434	}
1435
1436	virtual bool IsTemplatized() const
1437	{
1438		return true;
1439	}
1440
1441	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
1454	virtual bool IsNoReturnValueFunction() const
1455	{
1456		return fBase->IsNoReturnValueFunction();
1457	}
1458
1459	virtual object_type ObjectType() const
1460	{
1461		return fBase->ObjectType();
1462	}
1463
1464	virtual prefix_type PrefixType() const
1465	{
1466		return fBase->PrefixType();
1467	}
1468
1469protected:
1470	Node*	fBase;
1471	Node*	fFirstArgument;
1472	Node*	fLastArgument;
1473};
1474
1475
1476class MultiSubExpressionsNode : public Node {
1477public:
1478	MultiSubExpressionsNode()
1479		:
1480		fFirstSubExpression(NULL),
1481		fLastSubExpression(NULL)
1482	{
1483	}
1484
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
1498protected:
1499	Node*		fFirstSubExpression;
1500	Node*		fLastSubExpression;
1501};
1502
1503
1504class CallNode : public MultiSubExpressionsNode {
1505public:
1506	CallNode()
1507	{
1508	}
1509
1510	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
1533class OperatorExpressionNode : public MultiSubExpressionsNode {
1534public:
1535	OperatorExpressionNode(const operator_info* info)
1536		:
1537		fInfo(info)
1538	{
1539	}
1540
1541	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
1614private:
1615	const operator_info*	fInfo;
1616};
1617
1618
1619class ConversionExpressionNode : public MultiSubExpressionsNode {
1620public:
1621	ConversionExpressionNode(Node* type)
1622		:
1623		fType(type)
1624	{
1625		fType->SetParent(this);
1626	}
1627
1628	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
1651private:
1652	Node*	fType;
1653};
1654
1655
1656class PointerToMemberNode : public DecoratingNode {
1657public:
1658	PointerToMemberNode(Node* classType, Node* memberType)
1659		:
1660		DecoratingNode(memberType),
1661		fClassType(classType)
1662	{
1663		fClassType->SetParent(this);
1664	}
1665
1666	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
1686	virtual object_type ObjectType() const
1687	{
1688		return OBJECT_TYPE_DATA;
1689	}
1690
1691	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
1699private:
1700	Node*	fClassType;
1701};
1702
1703
1704class FunctionNode : public ObjectNode {
1705public:
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
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
1729	virtual bool GetName(NameBuffer& buffer) const
1730	{
1731		NameDecorationInfo decorationInfo(NULL);
1732		return GetDecoratedName(buffer, decorationInfo);
1733	}
1734
1735	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
1814	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
1848	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
1870private:
1871	bool _HasReturnType() const
1872	{
1873		return fHasReturnType
1874			|| fName == NULL
1875			|| (fName->IsTemplatized() && !fName->IsNoReturnValueFunction());
1876	}
1877
1878private:
1879	Node*		fFirstTypeNode;
1880	Node*		fLastTypeNode;
1881	bool		fHasReturnType;
1882	bool		fIsExternC;
1883};
1884
1885
1886// #pragma mark - Demangler
1887
1888
1889class Demangler {
1890public:
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
1904private:
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
1970private:
1971			Input				fInput;
1972			int					fError;
1973			Node*				fAllocatedNodes;
1974			Node*				fFirstReferenceableNode;
1975			Node*				fLastReferenceableNode;
1976			Node*				fTemplatizedNode;
1977};
1978
1979
1980template<typename NodeType>
1981struct Demangler::NodeCreator {
1982	NodeCreator(Demangler* demangler)
1983		:
1984		fDemangler(demangler)
1985	{
1986	}
1987
1988	template<typename ReturnType>
1989	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>
2000	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>
2012	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>
2025	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
2036private:
2037		Demangler*	fDemangler;
2038};
2039
2040
2041inline bool
2042Demangler::_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
2055inline void
2056Demangler::_AddAllocatedNode(Node* node)
2057{
2058	node->SetNextAllocated(fAllocatedNodes);
2059	fAllocatedNodes = node;
2060}
2061
2062
2063inline bool
2064Demangler::_SkipExpected(char c)
2065{
2066	return fInput.SkipPrefix(c) || _SetError(ERROR_INVALID);
2067}
2068
2069
2070inline bool
2071Demangler::_SkipExpected(const char* string)
2072{
2073	return fInput.SkipPrefix(string) || _SetError(ERROR_INVALID);
2074}
2075
2076
2077Demangler::Demangler()
2078	:
2079	fInput(),
2080	fAllocatedNodes(NULL)
2081{
2082}
2083
2084
2085int
2086Demangler::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
2101int
2102Demangler::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
2117void
2118Demangler::_Init()
2119{
2120	fError = ERROR_OK;
2121
2122	fFirstReferenceableNode = NULL;
2123	fLastReferenceableNode = NULL;
2124	fAllocatedNodes = NULL;
2125	fTemplatizedNode = NULL;
2126}
2127
2128
2129void
2130Demangler::_Cleanup()
2131{
2132	while (fAllocatedNodes != NULL) {
2133		Node* node = fAllocatedNodes;
2134		fAllocatedNodes = node->NextAllocated();
2135		DELETE(node);
2136	}
2137}
2138
2139
2140int
2141Demangler::_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
2171int
2172Demangler::_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
2206int
2207Demangler::_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
2234bool
2235Demangler::_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
2262bool
2263Demangler::_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
2313bool
2314Demangler::_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
2391bool
2392Demangler::_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
2417bool
2418Demangler::_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
2487bool
2488Demangler::_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
2529bool
2530Demangler::_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
2607bool
2608Demangler::_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
2652bool
2653Demangler::_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
2722bool
2723Demangler::_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
2741bool
2742Demangler::_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
2785bool
2786Demangler::_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
2798bool
2799Demangler::_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
2965void
2966Demangler::_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
2979bool
2980Demangler::_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
2994bool
2995Demangler::_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
3113bool
3114Demangler::_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
3138bool
3139Demangler::_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
3176bool
3177Demangler::_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
3192bool
3193Demangler::_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
3229bool
3230Demangler::_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
3244bool
3245Demangler::_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
3319bool
3320Demangler::_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
3344bool
3345Demangler::_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
3377bool
3378Demangler::_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
3436bool
3437Demangler::_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
3610bool
3611Demangler::_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
3657bool
3658Demangler::_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
3681bool
3682Demangler::_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
3692bool
3693Demangler::_CreateNodeAndSkip(const char* name, int toSkip, Node*& _node)
3694{
3695	return _CreateNodeAndSkip(name, strlen(name), toSkip, _node);
3696}
3697
3698
3699bool
3700Demangler::_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
3709bool
3710Demangler::_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
3745void
3746Demangler::_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
3764bool
3765Demangler::_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
3784const char*
3785demangle_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
3818status_t
3819get_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
3994const char*
3995demangle_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