mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 20:03:33 +08:00
[0.1.x] fixed : issue #10763 ( epeated member derived from different base classes )
git-svn-id: https://pykd.svn.codeplex.com/svn@76378 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
64197229cd
commit
17ae054165
@ -32,6 +32,7 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &typeSym )
|
|||||||
return TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
|
return TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
|
||||||
|
|
||||||
case SymTagPointerType:
|
case SymTagPointerType:
|
||||||
|
case SymTagVTable:
|
||||||
return TypeInfoPtr( new PointerTypeInfo( typeSym ) );
|
return TypeInfoPtr( new PointerTypeInfo( typeSym ) );
|
||||||
|
|
||||||
case SymTagEnum:
|
case SymTagEnum:
|
||||||
@ -258,6 +259,10 @@ PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symbol )
|
|||||||
if (btVoid == static_cast<BasicType>(pointTo->getBaseType()))
|
if (btVoid == static_cast<BasicType>(pointTo->getBaseType()))
|
||||||
m_derefName = "Void";
|
m_derefName = "Void";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SymTagVTableShape:
|
||||||
|
m_derefName = "VTable";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_size = (ULONG)symbol->getSize();
|
m_size = (ULONG)symbol->getSize();
|
||||||
@ -470,91 +475,84 @@ TypeInfoPtr TypeInfo::getRecurciveComplexType( TypeInfoPtr &lowestType, std::str
|
|||||||
|
|
||||||
TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName )
|
TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName )
|
||||||
{
|
{
|
||||||
pyDia::SymbolPtr field;
|
if ( m_fields.empty() )
|
||||||
LONG addOffset = 0;
|
getFields( m_dia );
|
||||||
try
|
|
||||||
{
|
|
||||||
field = m_dia->getChildByName( fieldName );
|
|
||||||
}
|
|
||||||
catch (const pyDia::Exception &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !field && !getBaseField( m_dia, fieldName, addOffset, field ) )
|
FieldList::iterator it;
|
||||||
throw TypeException( m_dia->getName(), fieldName + ": field not found" );
|
|
||||||
|
|
||||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field );
|
it = std::find_if( m_fields.begin(), m_fields.end(), boost::bind( &FieldType::first, _1) == fieldName );
|
||||||
|
|
||||||
switch( field->getDataKind() )
|
if ( it == m_fields.end() )
|
||||||
{
|
throw TypeException( m_dia->getName(), fieldName + ": unknown field type" );
|
||||||
case DataIsMember:
|
|
||||||
ti->setOffset( addOffset + field->getOffset() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DataIsStaticMember:
|
return it->second;
|
||||||
ti->setStaticOffset( field->getVa() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw TypeException(m_dia->getName(), fieldName + ": unknown field type" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ti;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index )
|
TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index )
|
||||||
{
|
{
|
||||||
std::string name = getFieldNameByIndex( index );
|
if ( m_fields.empty() )
|
||||||
|
getFields( m_dia );
|
||||||
|
|
||||||
return getField( name );
|
return m_fields[ index ].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string UdtTypeInfo::getFieldNameByIndex( ULONG index )
|
std::string UdtTypeInfo::getFieldNameByIndex( ULONG index )
|
||||||
{
|
{
|
||||||
ULONG baseClassCount = m_dia->getChildCount<SymTagBaseClass>();
|
if ( m_fields.empty() )
|
||||||
|
getFields( m_dia);
|
||||||
|
|
||||||
for ( ULONG i = 0; i < baseClassCount; ++i )
|
return m_fields[ index ].first;
|
||||||
{
|
|
||||||
pyDia::SymbolPtr baseSym = m_dia->getChildByIndex<SymTagBaseClass>( i );
|
|
||||||
|
|
||||||
TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym );
|
|
||||||
|
|
||||||
ULONG baseFieldCount = baseType->getFieldCount();
|
|
||||||
|
|
||||||
if ( baseFieldCount > index )
|
|
||||||
{
|
|
||||||
return baseType->getFieldNameByIndex( index );
|
|
||||||
}
|
|
||||||
|
|
||||||
index -= baseFieldCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_dia->getChildByIndex<SymTagData>( index )->getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG UdtTypeInfo::getFieldCount()
|
ULONG UdtTypeInfo::getFieldCount()
|
||||||
{
|
{
|
||||||
ULONG fieldCount = m_dia->getChildCount<SymTagData>();
|
if ( m_fields.empty() )
|
||||||
|
getFields( m_dia );
|
||||||
|
|
||||||
ULONG baseClassCount = m_dia->getChildCount<SymTagBaseClass>();
|
return (ULONG)m_fields.size();
|
||||||
|
}
|
||||||
|
|
||||||
for ( ULONG i = 0; i < baseClassCount; ++i )
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void UdtTypeInfo::getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset )
|
||||||
|
{
|
||||||
|
ULONG childCount = rootSym->getChildCount();
|
||||||
|
|
||||||
|
for ( ULONG i = 0; i < childCount; ++i )
|
||||||
{
|
{
|
||||||
pyDia::SymbolPtr baseSym = m_dia->getChildByIndex<SymTagBaseClass>( i );
|
pyDia::SymbolPtr childSym = rootSym->getChildByIndex( i );
|
||||||
|
|
||||||
TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym );
|
ULONG symTag = childSym->getSymTag();
|
||||||
|
|
||||||
fieldCount += baseType->getFieldCount();
|
if ( symTag == SymTagBaseClass )
|
||||||
|
{
|
||||||
|
getFields( childSym, startOffset + childSym->getOffset() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ( symTag == SymTagData )
|
||||||
|
{
|
||||||
|
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, childSym );
|
||||||
|
|
||||||
|
switch ( childSym->getDataKind() )
|
||||||
|
{
|
||||||
|
case DataIsMember:
|
||||||
|
ti->setOffset( startOffset + childSym->getOffset() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataIsStaticMember:
|
||||||
|
ti->setStaticOffset( childSym->getVa() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fields.push_back( std::make_pair( childSym->getName(), ti ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fieldCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -590,56 +588,6 @@ std::string UdtTypeInfo::print()
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
|
||||||
UdtTypeInfo::getBaseField(
|
|
||||||
pyDia::SymbolPtr symUdt,
|
|
||||||
const std::string &fieldName,
|
|
||||||
LONG &addOffset,
|
|
||||||
pyDia::SymbolPtr &symField,
|
|
||||||
ULONG currLevel /*= 0*/
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (currLevel > 16)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
LONG currOffset = 0;
|
|
||||||
|
|
||||||
pyDia::SymbolPtrList lstBases = symUdt->findChildrenImpl(SymTagBaseClass);
|
|
||||||
pyDia::SymbolPtrList::iterator it = lstBases.begin();
|
|
||||||
for (; it != lstBases.end(); ++it)
|
|
||||||
{
|
|
||||||
// find in direct base
|
|
||||||
try
|
|
||||||
{
|
|
||||||
symField = (*it)->getChildByName( fieldName );
|
|
||||||
addOffset += currOffset;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (const pyDia::Exception &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// find in base of base
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (getBaseField(*it, fieldName, addOffset, symField, currLevel + 1))
|
|
||||||
{
|
|
||||||
addOffset += currOffset;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const pyDia::Exception &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// correct offset
|
|
||||||
currOffset += static_cast<ULONG>( (*it)->getSize() );
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypeInfoPtr EnumTypeInfo::getField( const std::string &fieldName ) {
|
TypeInfoPtr EnumTypeInfo::getField( const std::string &fieldName ) {
|
||||||
pyDia::SymbolPtr field = m_dia->getChildByName( fieldName );
|
pyDia::SymbolPtr field = m_dia->getChildByName( fieldName );
|
||||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName );
|
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName );
|
||||||
|
@ -282,15 +282,15 @@ protected:
|
|||||||
|
|
||||||
virtual std::string print();
|
virtual std::string print();
|
||||||
|
|
||||||
static bool getBaseField(
|
|
||||||
pyDia::SymbolPtr symUdt,
|
|
||||||
const std::string &fieldName,
|
|
||||||
LONG &addOffset,
|
|
||||||
pyDia::SymbolPtr &symField,
|
|
||||||
ULONG currLevel = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
pyDia::SymbolPtr m_dia;
|
pyDia::SymbolPtr m_dia;
|
||||||
|
|
||||||
|
typedef std::pair< std::string, TypeInfoPtr > FieldType;
|
||||||
|
|
||||||
|
typedef std::vector< FieldType > FieldList;
|
||||||
|
|
||||||
|
FieldList m_fields;
|
||||||
|
|
||||||
|
void getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset = 0 );
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user