[Haiku-commits] r30954 - in haiku/trunk: build/jam src/add-ons/kernel/debugger/demangle

bonefish at mail.berlios.de bonefish at mail.berlios.de
Thu Jun 4 03:47:10 CEST 2009


Author: bonefish
Date: 2009-06-04 03:47:05 +0200 (Thu, 04 Jun 2009)
New Revision: 30954
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=30954&view=rev

Added:
   haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.cpp
   haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.h
Modified:
   haiku/trunk/build/jam/HaikuImage
   haiku/trunk/src/add-ons/kernel/debugger/demangle/Jamfile
   haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc2.cpp
   haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc3+.cpp
Log:
* Implemented demangling support for the current gcc ABI. Looks good so far
  save for the additional '&'/'*' print_demangled_call() is printing for
  reference/pointer arguments.
* Moved the new demangler and the gcc 2 demangler into the same module
  always supporting both (the right one is chosen). In mixed gcc 2/gcc 4
  environments we obviously need both of them.


Modified: haiku/trunk/build/jam/HaikuImage
===================================================================
--- haiku/trunk/build/jam/HaikuImage	2009-06-03 21:05:29 UTC (rev 30953)
+++ haiku/trunk/build/jam/HaikuImage	2009-06-04 01:47:05 UTC (rev 30954)
@@ -183,8 +183,8 @@
 	: <usb>uhci <usb>ohci <usb>ehci ;
 AddFilesToHaikuImage system add-ons kernel console : vga_text ;
 AddFilesToHaikuImage system add-ons kernel debugger
-	: $(X86_ONLY)<kdebug>disasm <kdebug>hangman <kdebug>invalidate_on_exit
-	<kdebug>usb_keyboard <kdebug>run_on_exit ;
+	: <kdebug>demangle $(X86_ONLY)<kdebug>disasm <kdebug>hangman
+	  <kdebug>invalidate_on_exit <kdebug>usb_keyboard <kdebug>run_on_exit ;
 AddFilesToHaikuImage system add-ons kernel file_systems
 	: $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ;
 AddFilesToHaikuImage system add-ons kernel generic
@@ -197,11 +197,6 @@
 
 if $(TARGET_ARCH) = x86 {
 	AddFilesToHaikuImage system add-ons kernel cpu : generic_x86 ;
-
-	if $(HAIKU_GCC_VERSION[1]) = 2 {
-		AddFilesToHaikuImage system add-ons kernel debugger demangle :
-			<kdebug>gcc2 ;
-	}
 }
 
 # drivers

Modified: haiku/trunk/src/add-ons/kernel/debugger/demangle/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/debugger/demangle/Jamfile	2009-06-03 21:05:29 UTC (rev 30953)
+++ haiku/trunk/src/add-ons/kernel/debugger/demangle/Jamfile	2009-06-04 01:47:05 UTC (rev 30954)
@@ -2,34 +2,8 @@
 
 UsePrivateHeaders kernel ;
 
-# GCC3/4 only solution (using parts of libsubc++)
-if $(HAIKU_GCC_VERSION[1]) >= 3 {
-	rule ExtractObject
-	{
-		SetupKernel $(2) ;
-		Depends $(1) : $(2) ;
-		Objects $(1) ;
-
-		MakeLocateDebug $(1) ;
-	}
-
-	actions ExtractObject
-	{
-		#$(TARGET_AR) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
-		pwd
-		echo $(TARGET_AR) -x "$(2)" "$(1)"
-	}
-
-	ExtractObject cp-demangle.o : $(TARGET_STATIC_LIBSUPC++) foo ;
-
-	KernelAddon <kdebug>gcc3+ :
-		gcc3+.cpp
-		cp-demangle.o
-	;
-}
-
-# GCC2 solution
-
-KernelAddon <kdebug>gcc2 :
+KernelAddon <kdebug>demangle :
+	demangle.cpp
 	gcc2.cpp
+	gcc3+.cpp
 ;

Added: haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.cpp	2009-06-03 21:05:29 UTC (rev 30953)
+++ haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.cpp	2009-06-04 01:47:05 UTC (rev 30954)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "demangle.h"
+
+#include <string.h>
+
+#include <debug.h>
+
+
+static inline bool
+looks_like_gcc3_symbol(const char* symbol)
+{
+	return strncmp(symbol, "_Z", 2) == 0;
+}
+
+
+static const char*
+demangle_symbol(const char* mangledName, char* buffer, size_t bufferSize,
+	bool* _isObjectMethod)
+{
+	// try the gcc3 demangler, if it looks like a gcc3 symbol
+	const char* demangled = NULL;
+	if (looks_like_gcc3_symbol(mangledName)) {
+		demangled = demangle_symbol_gcc3(mangledName, buffer, bufferSize,
+			_isObjectMethod);
+		if (demangled != NULL)
+			return demangled;
+	}
+
+	// fallback is gcc2
+	return demangle_symbol_gcc2(mangledName, buffer, bufferSize,
+		_isObjectMethod);
+}
+
+
+static status_t
+get_next_argument(uint32* _cookie, const char* mangledName, char* name,
+	size_t nameSize, int32* _type, size_t* _argumentLength)
+{
+	// try the gcc3 demangler, if it looks like a gcc3 symbol
+	if (looks_like_gcc3_symbol(mangledName)) {
+		status_t error = get_next_argument_gcc3(_cookie, mangledName, name,
+			nameSize, _type, _argumentLength);
+		if (error == B_OK)
+			return B_OK;
+	}
+
+	// fallback is gcc2
+	return get_next_argument_gcc2(_cookie, mangledName, name, nameSize, _type,
+		_argumentLength);
+}
+
+
+static status_t
+std_ops(int32 op, ...)
+{
+	switch (op) {
+		case B_MODULE_INIT:
+		case B_MODULE_UNINIT:
+			return B_OK;
+	}
+
+	return B_BAD_VALUE;
+}
+
+
+static struct debugger_demangle_module_info sModuleInfo = {
+	{
+		"debugger/demangle/v1",
+		0,
+		std_ops
+	},
+
+	demangle_symbol,
+	get_next_argument,
+};
+
+module_info* modules[] = {
+	(module_info*)&sModuleInfo,
+	NULL
+};

Added: haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.h	2009-06-03 21:05:29 UTC (rev 30953)
+++ haiku/trunk/src/add-ons/kernel/debugger/demangle/demangle.h	2009-06-04 01:47:05 UTC (rev 30954)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef DEMANGLE_H
+#define DEMANGLE_H
+
+#include <SupportDefs.h>
+
+
+// gcc 2
+const char*	demangle_symbol_gcc2(const char* name, char* buffer,
+				size_t bufferSize, bool* _isObjectMethod);
+status_t	get_next_argument_gcc2(uint32* _cookie, const char* symbol,
+				char* name, size_t nameSize, int32* _type,
+				size_t* _argumentLength);
+
+
+// gcc 3+
+const char*	demangle_symbol_gcc3(const char* name, char* buffer,
+				size_t bufferSize, bool* _isObjectMethod);
+status_t	get_next_argument_gcc3(uint32* _cookie, const char* symbol,
+				char* name, size_t nameSize, int32* _type,
+				size_t* _argumentLength);
+
+
+#endif	// DEMANGLE_H

Modified: haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc2.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc2.cpp	2009-06-03 21:05:29 UTC (rev 30953)
+++ haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc2.cpp	2009-06-04 01:47:05 UTC (rev 30954)
@@ -12,7 +12,9 @@
 
 #include <debug.h>
 
+#include "demangle.h"
 
+
 //#define TRACE_GCC2_DEMANGLER
 #ifdef TRACE_GCC2_DEMANGLER
 #	define TRACE(x...) kprintf(x)
@@ -420,7 +422,7 @@
 
 
 const char*
-demangle_symbol(const char* name, char* buffer, size_t bufferSize,
+demangle_symbol_gcc2(const char* name, char* buffer, size_t bufferSize,
 	bool* _isObjectMethod)
 {
 	size_t nameLength;
@@ -467,44 +469,9 @@
 
 
 status_t
-get_next_argument(uint32* _cookie, const char* symbol, char* name,
+get_next_argument_gcc2(uint32* _cookie, const char* symbol, char* name,
 	size_t nameSize, int32* _type, size_t* _argumentLength)
 {
 	return get_next_argument_internal(_cookie, symbol, name, nameSize, _type,
 		_argumentLength, false);
 }
-
-
-static status_t
-std_ops(int32 op, ...)
-{
-#if __GNUC__ != 2
-	return B_NOT_SUPPORTED;
-#else
-	switch (op) {
-		case B_MODULE_INIT:
-		case B_MODULE_UNINIT:
-			return B_OK;
-	}
-
-	return B_BAD_VALUE;
-#endif
-}
-
-
-static struct debugger_demangle_module_info sModuleInfo = {
-	{
-		"debugger/demangle/gcc2/v1",
-		0,
-		std_ops
-	},
-
-	demangle_symbol,
-	get_next_argument,
-};
-
-module_info *modules[] = {
-	(module_info *)&sModuleInfo,
-	NULL
-};
-

Modified: haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc3+.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc3+.cpp	2009-06-03 21:05:29 UTC (rev 30953)
+++ haiku/trunk/src/add-ons/kernel/debugger/demangle/gcc3+.cpp	2009-06-04 01:47:05 UTC (rev 30954)
@@ -1,174 +1,3872 @@
 /*
- * Copyright 2008, François Revol, revol at free.fr
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
  * Distributed under the terms of the MIT License.
  */
 
 #include <ctype.h>
-#include <cxxabi.h>
+#include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include <debug.h>
+#include <new>
 
-#define DEMANGLE_BUFFER_SIZE (16*1024)
-static char sDemangleBuffer[DEMANGLE_BUFFER_SIZE];
+#include <TypeConstants.h>
 
-extern "C" void set_debug_demangle_hook(const char *(*demangle_hook)(const char *));
+#include <debug_heap.h>
 
-/* gcc's __cxa_demangle calls malloc and friends...
- * we don't want to let it call the real one from inside the kernel debugger...
- * instead we just return it a static buffer.
- */
+#include "demangle.h"
 
-void *
-malloc(size_t len)
+
+// C++ ABI: http://www.codesourcery.com/public/cxx-abi/abi.html
+
+
+//#define TRACE_GCC3_DEMANGLER
+#ifdef TRACE_GCC3_DEMANGLER
+#	define TRACE(x...) PRINT(x)
+#	define DEBUG_SCOPE(name)	DebugScope debug(name, fInput.String())
+#else
+#	define TRACE(x...) ;
+#	define DEBUG_SCOPE(name)	do {} while (false)
+#endif
+
+#ifdef _KERNEL_MODE
+#	define PRINT(format...)		kprintf(format)
+#	define VPRINT(format, args)	PRINT("%s", format)
+									// no vkprintf()
+#	define NEW(constructor) new(kdebug_alloc) constructor
+#	define DELETE(object)	DebugAlloc::destroy(object)
+#else
+#	define PRINT(format...)		printf(format)
+#	define VPRINT(format, args)	vprintf(format, args)
+#	define NEW(constructor) new(std::nothrow) constructor
+#	define DELETE(object)	delete object
+#endif
+
+
+typedef long number_type;
+
+enum {
+	ERROR_OK = 0,
+	ERROR_NOT_MANGLED,
+	ERROR_UNSUPPORTED,
+	ERROR_INVALID,
+	ERROR_BUFFER_TOO_SMALL,
+	ERROR_NO_MEMORY,
+	ERROR_INTERNAL,
+	ERROR_INVALID_PARAMETER_INDEX
+};
+
+// object classification
+enum object_type {
+	OBJECT_TYPE_UNKNOWN,
+	OBJECT_TYPE_DATA,
+	OBJECT_TYPE_FUNCTION,
+	OBJECT_TYPE_METHOD_CLASS,
+	OBJECT_TYPE_METHOD_OBJECT,
+	OBJECT_TYPE_METHOD_UNKNOWN
+};
+
+// prefix classification
+enum prefix_type {
+	PREFIX_NONE,
+	PREFIX_NAMESPACE,
+	PREFIX_CLASS,
+	PREFIX_UNKNOWN
+};
+
+// type classification
+enum type_type {
+	TYPE_ELLIPSIS,
+	TYPE_VOID,
+	TYPE_WCHAR_T,
+	TYPE_BOOL,
+	TYPE_CHAR,
+	TYPE_SIGNED_CHAR,
+	TYPE_UNSIGNED_CHAR,
+	TYPE_SHORT,
+	TYPE_UNSIGNED_SHORT,
+	TYPE_INT,
+	TYPE_UNSIGNED_INT,
+	TYPE_LONG,
+	TYPE_UNSIGNED_LONG,
+	TYPE_LONG_LONG,
+	TYPE_UNSIGNED_LONG_LONG,
+	TYPE_INT128,
+	TYPE_UNSIGNED_INT128,
+	TYPE_FLOAT,
+	TYPE_DOUBLE,
+	TYPE_LONG_DOUBLE,
+	TYPE_FLOAT128,
+	TYPE_DFLOAT16,
+	TYPE_DFLOAT32,
+	TYPE_DFLOAT64,
+	TYPE_DFLOAT128,
+	TYPE_CHAR16_T,
+	TYPE_CHAR32_T,
+
+	TYPE_UNKNOWN,
+	TYPE_CONST_CHAR_POINTER,
+	TYPE_POINTER,
+	TYPE_REFERENCE
+};
+
+const char* const kTypeNames[] = {
+	"...",
+	"void",
+	"wchar_t",
+	"bool",
+	"char",
+	"signed char",
+	"unsigned char",
+	"short",
+	"unsigned short",
+	"int",
+	"unsigned int",
+	"long",
+	"unsigned long",
+	"long long",
+	"unsigned long long",
+	"__int128",
+	"unsigned __int128",
+	"float",
+	"double",
+	"long double",
+	"__float128",
+	"__dfloat16",	// TODO: Official names for the __dfloat*!
+	"__dfloat32",
+	"__dfloat64",
+	"__dfloat64",
+	"char16_t",
+	"char32_t",
+
+	"?",
+	"char const*",
+	"void*",
+	"void&"
+};
+
+
+// CV qualifier flags
+enum {
+	CV_QUALIFIER_RESTRICT	= 0x1,
+	CV_QUALIFIER_VOLATILE	= 0x2,
+	CV_QUALIFIER_CONST		= 0x4
+};
+
+enum type_modifier {
+	TYPE_QUALIFIER_POINTER = 0,
+	TYPE_QUALIFIER_REFERENCE,
+	TYPE_QUALIFIER_RVALUE_REFERENCE,
+	TYPE_QUALIFIER_COMPLEX,
+	TYPE_QUALIFIER_IMAGINARY
+};
+
+static const char* const kTypeModifierSuffixes[] = {
+	"*",
+	"&",
+	"&&",
+	" complex",
+	" imaginary"
+};
+
+struct operator_info {
+	const char*	mangled_name;
+	const char*	name;
+	int			argument_count;
+	int			flags;
+};
+
+// operator flags
+enum {
+	OPERATOR_TYPE_PARAM		= 0x01,
+	OPERATOR_IS_MEMBER		= 0x02
+};
+
+
+static const operator_info kOperatorInfos[] = {
+	{ "nw", "new", -1, OPERATOR_IS_MEMBER },
+	{ "na", "new[]", -1, OPERATOR_IS_MEMBER },
+	{ "dl", "delete", -1, OPERATOR_IS_MEMBER },
+	{ "da", "delete[]", -1, OPERATOR_IS_MEMBER },
+	{ "ps", "+", 1, 0 },		// unary
+	{ "ng", "-", 1, 0 },		// unary
+	{ "ad", "&", 1, 0 },		// unary
+	{ "de", "*", 1, 0 },		// unary
+	{ "co", "~", 1, 0 },
+	{ "pl", "+", 2, 0 },
+	{ "mi", "-", 2, 0 },
+	{ "ml", "*", 2, 0 },
+	{ "dv", "/", 2, 0 },
+	{ "rm", "%", 2, 0 },
+	{ "an", "&", 2, 0 },
+	{ "or", "|", 2, 0 },
+	{ "eo", "^", 2, 0 },
+	{ "aS", "=", 2, 0 },
+	{ "pL", "+=", 2, 0 },
+	{ "mI", "-=", 2, 0 },
+	{ "mL", "*=", 2, 0 },
+	{ "dV", "/=", 2, 0 },
+	{ "rM", "%=", 2, 0 },
+	{ "aN", "&=", 2, 0 },
+	{ "oR", "|=", 2, 0 },
+	{ "eO", "^=", 2, 0 },
+	{ "ls", "<<", 2, 0 },
+	{ "rs", ">>", 2, 0 },
+	{ "lS", "<<=", 2, 0 },
+	{ "rS", ">>=", 2, 0 },
+	{ "eq", "==", 2, 0 },
+	{ "ne", "!=", 2, 0 },
+	{ "lt", "<", 2, 0 },
+	{ "gt", ">", 2, 0 },
+	{ "le", "<=", 2, 0 },
+	{ "ge", ">=", 2, 0 },
+	{ "nt", "!", 1, 0 },
+	{ "aa", "&&", 2, 0 },
+	{ "oo", "||", 2, 0 },
+	{ "pp", "++", 1, 0 },
+	{ "mm", "--", 1, 0 },
+	{ "cm", ",", -1, 0 },
+	{ "pm", "->*", 2, 0 },
+	{ "pt", "->", 2, 0 },
+	{ "cl", "()", -1, 0 },
+	{ "ix", "[]", -1, 0 },
+	{ "qu", "?", 3, 0 },
+	{ "st", "sizeof", 1, OPERATOR_TYPE_PARAM },		// type
+	{ "sz", "sizeof", 1, 0 },						// expression
+	{ "at", "alignof", 1, OPERATOR_TYPE_PARAM },	// type
+	{ "az", "alignof", 1, 0 },						// expression
+	{}
+};
+
+
+#ifdef TRACE_GCC3_DEMANGLER
+
+struct DebugScope {
+	DebugScope(const char* functionName, const char* remainingString = NULL)
+		:
+		fParent(sGlobalScope),
+		fFunctionName(functionName),
+		fLevel(fParent != NULL ? fParent->fLevel + 1 : 0)
+	{
+		sGlobalScope = this;
+		if (remainingString != NULL) {
+			PRINT("%*s%s(): \"%s\"\n", fLevel * 2, "", fFunctionName,
+				remainingString);
+		} else
+			PRINT("%*s%s()\n", fLevel * 2, "", fFunctionName);
+	}
+
+	~DebugScope()
+	{
+		sGlobalScope = fParent;
+		PRINT("%*s%s() done\n", fLevel * 2, "", fFunctionName);
+	}
+
+	static void Print(const char* format,...)
+	{
+		int level = sGlobalScope != NULL ? sGlobalScope->fLevel : 0;
+
+		va_list args;
+		va_start(args, format);
+		PRINT("%*s", (level + 1) * 2, "");
+		VPRINT(format, args);
+		va_end(args);
+	}
+
+private:
+	DebugScope*	fParent;
+	const char*	fFunctionName;
+	int			fLevel;
+
+	static DebugScope* sGlobalScope;
+};
+
+DebugScope* DebugScope::sGlobalScope = NULL;
+
+#endif	// TRACE_GCC3_DEMANGLER
+
+
+class Input {
+public:
+	Input()
+		:
+		fString(NULL),
+		fLength(0)
+	{
+	}
+
+	void SetTo(const char* string, size_t length)
+	{
+		fString = string;
+		fLength = length;
+	}
+
+	const char* String() const
+	{
+		return fString;
+	}
+
+	int CharsRemaining() const
+	{
+		return fLength;
+	}
+
+	void Skip(size_t count)
+	{
+		if (count > fLength) {
+			PRINT("Input::Skip(): fOffset > fLength\n");
+			return;
+		}
+
+		fString += count;
+		fLength -= count;
+	}
+
+	bool HasPrefix(char prefix) const
+	{
+		return fLength > 0 && fString[0] == prefix;
+	}
+
+	bool HasPrefix(const char* prefix) const
+	{
+		size_t prefixLen = strlen(prefix);
+		return prefixLen <= fLength
+			&& strncmp(fString, prefix, strlen(prefix)) == 0;
+	}
+
+	bool SkipPrefix(char prefix)
+	{
+		if (!HasPrefix(prefix))
+			return false;
+
+		fString++;
+		fLength--;
+		return true;
+	}
+
+	bool SkipPrefix(const char* prefix)
+	{
+		size_t prefixLen = strlen(prefix);
+		if (prefixLen <= fLength && strncmp(fString, prefix, prefixLen) != 0)
+			return false;
+
+		fString += prefixLen;
+		fLength -= prefixLen;
+		return true;
+	}
+
+	char operator[](size_t index) const
+	{
+		if (index >= fLength) {
+			PRINT("Input::operator[](): fOffset + index >= fLength\n");
+			return '\0';
+		}
+
+		return fString[index];
+	}
+
+private:
+	const char*	fString;
+	size_t		fLength;
+};
+
+
+class NameBuffer {
+public:
+	NameBuffer(char* buffer, size_t size)
+		:
+		fBuffer(buffer),
+		fSize(size),
+		fLength(0),
+		fOverflow(false)
+	{
+	}
+
+	bool IsEmpty() const
+	{
+		return fLength == 0;
+	}
+
+	char LastChar() const
+	{
+		return fLength > 0 ? fBuffer[fLength - 1] : '\0';
+	}
+
+	bool HadOverflow() const
+	{
+		return fOverflow;
+	}
+
+	char* Terminate()
+	{
+		fBuffer[fLength] = '\0';
+		return fBuffer;
+	}
+
+	bool Append(const char* string, size_t length)
+	{
+		if (fLength + length >= fSize) {
+			fOverflow = true;
+			return false;
+		}
+
+		memcpy(fBuffer + fLength, string, length);
+		fLength += length;
+		return true;
+	}
+
+	bool Append(const char* string)
+	{
+		return Append(string, strlen(string));
+	}
+
+private:
+	char*	fBuffer;
+	size_t	fSize;
+	size_t	fLength;
+	bool	fOverflow;
+};
+
+
+struct TypeInfo {
+	type_type	type;
+	int			cvQualifiers;
+
+	TypeInfo()
+		:
+		type(TYPE_UNKNOWN),
+		cvQualifiers(0)
+	{
+	}
+
+	TypeInfo(type_type type)
+		:
+		type(type),
+		cvQualifiers(0)
+	{
+	}
+
+	TypeInfo(const TypeInfo& other, int cvQualifiers = 0)
+		:
+		type(other.type),
+		cvQualifiers(other.cvQualifiers | cvQualifiers)
+	{
+	}
+
+	TypeInfo& operator=(const TypeInfo& other)
+	{
+		type = other.type;
+		cvQualifiers = other.cvQualifiers;
+		return *this;
+	}
+};
+
+
+struct DemanglingParameters {
+	bool	objectNameOnly;
+
+	DemanglingParameters(bool objectNameOnly)
+		:
+		objectNameOnly(objectNameOnly)
+	{
+	}
+};
+
+
+struct DemanglingInfo : DemanglingParameters {
+	object_type	objectType;
+
+	DemanglingInfo(bool objectNameOnly)
+		:
+		DemanglingParameters(objectNameOnly),
+		objectType(OBJECT_TYPE_UNKNOWN)
+	{
+	}
+};
+
+
+struct ParameterInfo {
+	TypeInfo	type;
+
+	ParameterInfo()
+	{
+	}
+};
+
+
+class Node;
+
+struct NameDecorationInfo {
+	const Node*	firstDecorator;
+	const Node*	closestCVDecoratorList;
+
+	NameDecorationInfo(const Node* decorator)
+		:
+		firstDecorator(decorator),
+		closestCVDecoratorList(NULL)
+	{
+	}
+};
+
+struct CVQualifierInfo {
+	const Node*	firstCVQualifier;
+	const Node*	firstNonCVQualifier;
+
+	CVQualifierInfo()
+		:
+		firstCVQualifier(NULL),
+		firstNonCVQualifier(NULL)
+	{
+	}
+};
+
+
+class Node {
+public:
+	Node()
+		:
+		fNextAllocated(NULL),
+		fParent(NULL),
+		fNext(NULL),
+		fNextReferenceable(NULL),
+		fReferenceable(true)
+	{
+	}
+
+	virtual ~Node()
+	{
+	}
+
+	Node* NextAllocated() const			{ return fNextAllocated; }
+	void SetNextAllocated(Node* node)	{ fNextAllocated = node; }
+
+	Node* Parent() const				{ return fParent; }
+	virtual void SetParent(Node* node)	{ fParent = node; }
+
+	Node* Next() const			{ return fNext; }
+	void SetNext(Node* node)	{ fNext = node; }
+
+	bool IsReferenceable() const		{ return fReferenceable; }
+	void SetReferenceable(bool flag)	{ fReferenceable = flag; }
+
+	Node* NextReferenceable() const			{ return fNextReferenceable; }
+	void SetNextReferenceable(Node* node)	{ fNextReferenceable = node; }
+
+	virtual bool GetName(NameBuffer& buffer) const = 0;
+
+	virtual bool GetDecoratedName(NameBuffer& buffer,
+		NameDecorationInfo& decorationInfo) const
+	{
+		if (!GetName(buffer))
+			return false;
+
+		return decorationInfo.firstDecorator == NULL
+			|| decorationInfo.firstDecorator->AddDecoration(buffer, NULL);
+	}
+
+	virtual bool AddDecoration(NameBuffer& buffer,
+		const Node* stopDecorator) const
+	{
+		return true;
+	}
+
+	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
+	{
+		info.firstNonCVQualifier = this;
+	}
+
+	virtual Node* GetUnqualifiedNode(Node* beforeNode)
+	{
+		return this;
+	}
+
+	virtual bool IsTemplatized() const
+	{
+		return false;
+	}
+
+	virtual Node* TemplateParameterAt(int index) const
+	{
+		return NULL;
+	}
+
+	virtual bool IsNoReturnValueFunction() const
+	{
+		return false;
+	}
+
+	virtual bool IsTypeName(const char* name, size_t length) const
+	{
+		return false;
+	}
+
+	virtual object_type ObjectType() const
+	{
+		return OBJECT_TYPE_UNKNOWN;
+	}
+
+	virtual prefix_type PrefixType() const
+	{
+		return PREFIX_NONE;
+	}
+
+	virtual TypeInfo Type() const
+	{
+		return TypeInfo();
+	}
+
+private:
+	Node*	fNextAllocated;
+	Node*	fParent;
+	Node*	fNext;
+	Node*	fNextReferenceable;
+	bool	fReferenceable;
+};
+
+
+class NamedTypeNode : public Node {
+public:
+	NamedTypeNode(Node* name)
+		:
+		fName(name)
+	{
+		if (fName != NULL)
+			fName->SetParent(this);
+	}
+
+	virtual bool GetName(NameBuffer& buffer) const
+	{
+		return fName == NULL || fName->GetName(buffer);
+	}
+
+	virtual bool IsNoReturnValueFunction() const
+	{
+		return fName != NULL && fName->IsNoReturnValueFunction();
+	}
+
+	virtual TypeInfo Type() const
+	{
+		return fName != NULL ? fName->Type() : TypeInfo();
+	}
+
+protected:
+	Node*	fName;
+};
+
+
+class SubstitutionNode : public Node {
+public:
+	SubstitutionNode(Node* node)
+		:
+		fNode(node)
+	{
+	}
+
+	virtual bool GetName(NameBuffer& buffer) const
+	{
+		return fNode->GetName(buffer);
+	}
+
+	virtual bool GetDecoratedName(NameBuffer& buffer,
+		NameDecorationInfo& decorationInfo) const
+	{
+		return fNode->GetDecoratedName(buffer, decorationInfo);
+	}
+
+	virtual bool AddDecoration(NameBuffer& buffer,
+		const Node* stopDecorator) const
+	{
+		return fNode->AddDecoration(buffer, stopDecorator);
+	}
+
+	virtual void GetCVQualifierInfo(CVQualifierInfo& info) const
+	{
+		fNode->GetCVQualifierInfo(info);
+	}
+
+	virtual bool IsTemplatized() const
+	{
+		return fNode->IsTemplatized();
+	}
+
+	virtual Node* TemplateParameterAt(int index) const
+	{
+		return fNode->TemplateParameterAt(index);
+	}
+
+	virtual bool IsNoReturnValueFunction() const
+	{
+		return fNode->IsNoReturnValueFunction();
+	}
+
+	virtual bool IsTypeName(const char* name, size_t length) const
+	{
+		return fNode->IsTypeName(name, length);
+	}
+
+	virtual object_type ObjectType() const
+	{
+		return fNode->ObjectType();
+	}
+
+	virtual prefix_type PrefixType() const
+	{
+		return fNode->PrefixType();
+	}
+
+	virtual TypeInfo Type() const
+	{

[... truncated: 3248 lines follow ...]



More information about the Haiku-commits mailing list