⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 undname.cpp

📁 不错的东西 请查看 WINCE OS
💻 CPP
📖 第 1 页 / 共 5 页
字号:
											int maxStringLength,	// Note, COMMA is leading following optional arguments
											Alloc_t pAlloc,
											Free_t pFree,
											GetParameter_t pGetParameter,
											unsigned long disableFlags

										)
/*
 *	This function will undecorate a name, returning the string corresponding to
 *	the C++ declaration needed to produce the name.  Its has a similar interface
 *	to 'strncpy'.
 *
 *	If the target string 'outputString' is specified to be NULL, a string of
 *	suitable length will be allocated and its address returned.  If the returned
 *	string is allocated by 'unDName', then it is the programmers responsibility
 *	to deallocate it.  It will have been allocated on the far heap.
 *
 *	If the target string is not NULL, then the parameter 'maxStringLength' will
 *	specify the maximum number of characters which may be placed in the string.
 *	In this case, the returned value is the same as 'outputString'.
 *
 *	Both the input parameter 'name' and the returned string are NULL terminated
 *	strings of characters.
 *
 *	If the returned value is NULL, it indicates that the undecorator ran out of
 *	memory, or an internal error occurred, and was unable to complete its task.
 */

{
	//	Must have an allocator and a deallocator (and we MUST trust them)

	if	( !( pAlloc ))
		return	0;
	else
		heap.Constructor ( pAlloc, pFree );

	//	Create the undecorator object, and get the result

	UnDecorator	unDecorate (	outputString,
								name,
								maxStringLength,
								pGetParameter,
								disableFlags
							);
	pchar_t		unDecoratedName	= unDecorate;


	// Destruct the heap (would use a destructor, but that causes DLL problems)

	heap.Destructor ();

	//	And return the composed name

	return	unDecoratedName;

}	// End of FUNCTION "unDName"

//	The 'UnDecorator' member functions

inline	__near	UnDecorator::UnDecorator	(	pchar_t output,
												pcchar_t dName,
												int maxLen,
												GetParameter_t pGetParameter,
												unsigned long disable
									)
{
	name			= dName;
	gName			= name;

	if	( output ) {
		maxStringLength	= maxLen - 1;	// The algorithm in getString doesn't leave room
										// for terminating NULL; be paranoid and leave one
										// extra char.
										// It's a lot easier to fix this here....
		outputString	= output;	
	}
	else {
		outputString	= 0;
		maxStringLength	= 0;
	}

	pZNameList		= &ZNameList;
	pArgList		= &ArgList;
	disableFlags	= disable;
	m_pGetParameter	= pGetParameter;

}	// End of "UnDecorator" CONSTRUCTOR '()'


inline	__near	UnDecorator::operator pchar_t ()
{
	DName		result;
	DName		unDName;


	//	Find out if the name is a decorated name or not.  Could be a reserved
	//	CodeView variant of a decorated name

	if	( name )
	{
		if	(( *name == '?' ) && ( name[ 1 ] == '@' ))
		{
#if	( !NO_COMPILER_NAMES )
			gName	+= 2;
			result	= "CV: " + getDecoratedName ();
#else	// } elif NO_COMPILER_NAMES
			result	= DN_invalid;
#endif	// NO_COMPILER_NAMES

		}	// End of IF then
		elif	(( *name == '?' ) && ( name[1] == '$' ))
			result	= getTemplateName ();
		else
			result	= getDecoratedName ();

	}	// End of IF then

	//	If the name was not a valid name, then make the name the same as the original
	//	It is also invalid if there are any remaining characters in the name (except when
	//	we're giving the name only)

	if		( result.status () == DN_error )
		return	0;
	elif	( (*gName && !doNameOnly ()) || ( result.status () == DN_invalid ))
		unDName	= name;	// Return the original name
	else
		unDName	= result;

	//	Construct the return string

	if	( !outputString )
	{
		maxStringLength	= unDName.length () + 1;
		outputString 	= rnew char[ maxStringLength ];

	}	// End of IF

	if	( outputString )
		unDName.getString ( outputString, maxStringLength );

	//	Return the result

	return	outputString;

}	// End of "UnDecorator" OPERATOR 'pchar_t'



DName	__near	UnDecorator::getDecoratedName ( void )
{
	//	Ensure that it is intended to be a decorated name

	if		( doTypeOnly() )
	{
		// Disable the type-only flag, so that if we get here recursively, eg.
		// in a template tag, we do full name undecoration.
		disableFlags &= ~UNDNAME_TYPE_ONLY;

		// If we're decoding just a type, process it as the type for an abstract
		// declarator, by giving an empty symbol name.

		DName	result = getDataType ( NULL );
		disableFlags |= UNDNAME_TYPE_ONLY;

		return result;
	}
	elif	( *gName == '?' )
	{
		//	Extract the basic symbol name

		gName++;	// Advance the original name pointer


		DName	symbolName	= getSymbolName ();
		int		udcSeen		= symbolName.isUDC ();

		//	Abort if the symbol name is invalid

		if	( !symbolName.isValid ())
			return	symbolName;

		//	Extract, and prefix the scope qualifiers

		if	( *gName && ( *gName != '@' )) {
			DName	scope = getScope ();
			
			if	( !scope.isEmpty() )
				symbolName	= scope + "::" + symbolName;
			}

		if	( udcSeen )
			symbolName.setIsUDC ();

		//	Now compose declaration

		if	( symbolName.isEmpty () || symbolName.isNoTE() )
		{
			return	symbolName;
		}
		elif	( !*gName || ( *gName == '@' ) )
		{
			if	( *gName )
				gName++;

			if	(doNameOnly () && !udcSeen) {
				// Eat the rest of the dname, in case this is a recursive invocation,
				// such as for a template argument.
				(void)composeDeclaration( DName() );
				return symbolName;
			}
			else {
				return	composeDeclaration ( symbolName );
			}

		}	// End of ELIF then
		else
			return	DN_invalid;

	}	// End of IF then
	elif	( *gName )
		return	DN_invalid;
	else
		return	DN_truncated;

}	// End of "UnDecorator" FUNCTION "getDecoratedName"



inline	DName	__near	UnDecorator::getSymbolName ( void )
{
	if	( *gName == '?' )
	{
		gName++;

		return	getOperatorName ();

	}	// End of IF then
	else
		return	getZName ();

}	// End of "UnDecorator" FUNCTION "getSymbolName"



DName	__near	UnDecorator::getZName ( void )
{
	int		zNameIndex	= *gName - '0';


	//	Handle 'zname-replicators', otherwise an actual name

	if	(( zNameIndex >= 0 ) && ( zNameIndex <= 9 ))
	{
		gName++;	// Skip past the replicator

		//	And return the indexed name

		return	( *pZNameList )[ zNameIndex ];

	}	// End of IF then
	else
	{
		DName	zName;

		if	( *gName == '?' )
		{
			zName	= getTemplateName ();

			if	( *gName++ != '@' )
				zName	= *--gName ? DN_invalid : DN_truncated;
		}
		else
			//	Extract the 'zname' to the terminator

			zName	= DName( gName, '@' );	// This constructor updates 'name'


		//	Add it to the current list of 'zname's

		if	( !pZNameList->isFull ())
			*pZNameList	+= zName;

		//	And return the symbol name
		return	zName;

	}	// End of IF else
}	// End of "UnDecorator" FUNCTION "getZName"



inline	DName	__near	UnDecorator::getOperatorName ( void )
{
	DName	operatorName;
	DName	tmpName;
	int		udcSeen	= FALSE;


	//	So what type of operator is it ?

	switch	( *gName++ )
	{
	case 0:
		gName--;		// End of string, better back-track

		return	DN_truncated;

	case OC_ctor:
	case OC_dtor:
		//
		// The constructor and destructor are special:
		// Their operator name is the name of their first enclosing scope, which
		// will always be a tag, which may be a template specialization!
		//
		{
			//	Use a temporary.  Don't want to advance the name pointer

			pcchar_t	pName	= gName;


			operatorName		= getZName ();


			gName = pName;		// Undo our lookahead

			if	( !operatorName.isEmpty () && ( gName[ -1 ] == OC_dtor ))
				operatorName	= '~' + operatorName;

			return	operatorName;

		}	// End of CASE 'OC_ctor,OC_dtor'
		break;

	case OC_new:
	case OC_delete:
	case OC_assign:
	case OC_rshift:
	case OC_lshift:
	case OC_not:
	case OC_equal:
	case OC_unequal:
			operatorName	= nameTable[ gName[ -1 ] - OC_new ];
		break;

	case OC_udc:
			udcSeen	= TRUE;

		//	No break

	case OC_index:
	case OC_pointer:
	case OC_star:
	case OC_incr:
	case OC_decr:
	case OC_minus:
	case OC_plus:
	case OC_amper:
	case OC_ptrmem:
	case OC_divide:
	case OC_modulo:
	case OC_less:
	case OC_leq:
	case OC_greater:
	case OC_geq:
	case OC_comma:
	case OC_call:
	case OC_compl:
	case OC_xor:
	case OC_or:
	case OC_land:
	case OC_lor:
	case OC_asmul:
	case OC_asadd:
	case OC_assub:			// Regular operators from the first group
			operatorName	= nameTable[ gName[ -1 ] - OC_index + ( OC_unequal - OC_new + 1 )];
		break;

	case '_':
			switch	( *gName++ )
			{
			case 0:
				gName--;		// End of string, better back-track

				return	DN_truncated;

			case OC_asdiv:
			case OC_asmod:
			case OC_asrshift:
			case OC_aslshift:
			case OC_asand:
			case OC_asor:
			case OC_asxor:	// Regular operators from the extended group
					operatorName	= nameTable[ gName[ -1 ] - OC_asdiv + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
				break;

#if	( !NO_COMPILER_NAMES )
			case OC_vftable:
			case OC_vbtable:
			case OC_vcall:
				return	nameTable[ gName[ -1 ] - OC_asdiv + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];

			case OC_string:
				{
				DName result = getStringEncoding( "`string'", TRUE );
				result.setIsNoTE();
				return result;
				}

			case OC_metatype:
			case OC_guard:
			case OC_vbdtor:
			case OC_vdeldtor:
			case OC_defctor:
			case OC_sdeldtor:
			case OC_vctor:
			case OC_vdtor:
			case OC_vallctor:
			case OC_ehvctor:
			case OC_ehvdtor:
			case OC_ehvctorvb:
			case OC_copyctorclosure:
			case OC_locvfctorclosure:
			case OC_locvftable:	// Special purpose names
			case OC_placementDeleteClosure:
			case OC_placementArrayDeleteClosure:
				return	nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];

			case OC_udtthunk:
				operatorName	= nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
				tmpName 		= getOperatorName();
				if ( !tmpName.isEmpty() && tmpName.isUDTThunk() )
					return	DN_invalid;
				return operatorName + tmpName;
				break;
			case OC_eh_init:
				break;
			case OC_rtti_init:
				operatorName	= nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
				tmpName = rttiTable[ gName[0] - OC_rtti_TD ];
				switch	( *gName++ )
				{
				case OC_rtti_TD:
					{
					DName	result = getDataType ( NULL );
					return result + ' ' + operatorName + tmpName;
					}
					break;
				case OC_rtti_BCD:
					{
					DName	result = operatorName + tmpName;
					result += getSignedDimension() + ',';
					result += getSignedDimension() + ',';
					result += getSignedDimension() + ',';
					result += getDimension() + ')';
					return result + '\'';
					}
					break;
				case OC_rtti_BCA:
				case OC_rtti_CHD:
				case OC_rtti_COL:
					return operatorName + tmpName;
					break;
				default:
					gName--;
					return DN_truncated;
					break;
				}
				break;

#endif	// !NO_COMPILER_NAMES

			case OC_arrayNew:
			case OC_arrayDelete:
				operatorName	= nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )
#if NO_COMPILER_NAMES
											- ( OC_locvfctorclosure - OC_vftable + 1 )	// discount names not in table
#endif
									];
				break;

			// Yet another level of nested encodings....
			case '?':
				switch( *gName++ ) {

					case 0:
						gName--;		// End of string, better back-track

						return	DN_truncated;

					case OC_anonymousNamespace:
						//
						// Anonymous namespace (new-style) is a string encoding of the
						// machine name and the translation unit name.  Since the remainder
						// of the name doesn't really fit the dname grammar, skip it.
						// There are two '@' markers in the name....
						//
						{
						DName result = getStringEncoding( "`anonymous namespace'", FALSE );
						result.setIsNoTE();
						return result;
						}

					default:
						return	DN_invalid;
				}
				break;

			default:
				return	DN_invalid;

			}	// End of SWITCH
		break;

	default:
		return	DN_invalid;

	}	// End of SWITCH

	//	This really is an operator name, so prefix it with 'operator'

	if	( udcSeen )
		operatorName.setIsUDC ();
	elif	( !operatorName.isEmpty ())
		operatorName	= "operator" + operatorName;

	return	operatorName;

}	// End of "UnDecorator" FUNCTION "getOperatorName"

DName	UnDecorator::getStringEncoding ( char *prefix, int wantBody )
{
	DName result = prefix;

	// First @ comes right after operator code
	if	( *gName++ != '@' || *gName++ != '_' ) {
		return DN_invalid;
	}

	// Skip the string kind
	*gName++;

	// Get (& discard) the length
	getDimension();

	// Get (& discart) the checksum
	getDimension();

	while ( *gName && *gName != '@' ) {
		// For now, we'll just skip it
		gName++;
	}

	if	( !*gName ) {
		gName--;
		return DN_truncated;
	}

	// Eat the terminating '@'
	gName++;

	return result;
}


DName	__near	UnDecorator::getScope ( void )
{
	DName	scope;
	bool	fNeedBracket = false;


	//	Get the list of scopes

	while	(( scope.status () == DN_valid ) && *gName && ( *gName != '@' ))
	{	//	Insert the scope operator if not the first scope

		if	( !scope.isEmpty() ) {
			scope	= "::" + scope;

			if (fNeedBracket) {
				scope = '[' + scope;
				fNeedBracket = false;
			}
		}

		//	Determine what kind of scope it is

		if	( *gName == '?' )
			switch	( *++gName )
			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -