[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:
SND\kernelnet_cp 2012-05-16 11:57:07 +00:00 committed by Mikhail I. Izmestev
parent 64197229cd
commit 17ae054165
2 changed files with 64 additions and 116 deletions

View File

@ -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" );
it = std::find_if( m_fields.begin(), m_fields.end(), boost::bind( &FieldType::first, _1) == fieldName );
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field ); if ( it == m_fields.end() )
throw TypeException( m_dia->getName(), fieldName + ": unknown field type" );
switch( field->getDataKind() ) return it->second;
{
case DataIsMember:
ti->setOffset( addOffset + field->getOffset() );
break;
case DataIsStaticMember:
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() );
return fieldCount; }
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 ) );
}
}
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -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 );

View File

@ -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 );
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////