From 17ae054165f6287a7dc15b4bb873ae0e01c86d78 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 16 May 2012 11:57:07 +0000 Subject: [PATCH] [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 --- pykd/typeinfo.cpp | 164 ++++++++++++++++------------------------------ pykd/typeinfo.h | 16 ++--- 2 files changed, 64 insertions(+), 116 deletions(-) diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index 1bd2833..1230727 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -32,6 +32,7 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &typeSym ) return TypeInfoPtr( new ArrayTypeInfo( typeSym ) ); case SymTagPointerType: + case SymTagVTable: return TypeInfoPtr( new PointerTypeInfo( typeSym ) ); case SymTagEnum: @@ -258,6 +259,10 @@ PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symbol ) if (btVoid == static_cast(pointTo->getBaseType())) m_derefName = "Void"; break; + + case SymTagVTableShape: + m_derefName = "VTable"; + break; } } m_size = (ULONG)symbol->getSize(); @@ -470,91 +475,84 @@ TypeInfoPtr TypeInfo::getRecurciveComplexType( TypeInfoPtr &lowestType, std::str TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName ) { - pyDia::SymbolPtr field; - LONG addOffset = 0; - try - { - field = m_dia->getChildByName( fieldName ); - } - catch (const pyDia::Exception &) - { - } + if ( m_fields.empty() ) + getFields( m_dia ); - if ( !field && !getBaseField( m_dia, fieldName, addOffset, field ) ) - throw TypeException( m_dia->getName(), fieldName + ": field not found" ); + FieldList::iterator it; + + 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() ) - { - 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; + return it->second; } - ///////////////////////////////////////////////////////////////////////////////////// -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 ) { - ULONG baseClassCount = m_dia->getChildCount(); + if ( m_fields.empty() ) + getFields( m_dia); - for ( ULONG i = 0; i < baseClassCount; ++i ) - { - pyDia::SymbolPtr baseSym = m_dia->getChildByIndex( i ); - - TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym ); - - ULONG baseFieldCount = baseType->getFieldCount(); - - if ( baseFieldCount > index ) - { - return baseType->getFieldNameByIndex( index ); - } - - index -= baseFieldCount; - } - - return m_dia->getChildByIndex( index )->getName(); + return m_fields[ index ].first; } ///////////////////////////////////////////////////////////////////////////////////// ULONG UdtTypeInfo::getFieldCount() { - ULONG fieldCount = m_dia->getChildCount(); + if ( m_fields.empty() ) + getFields( m_dia ); - ULONG baseClassCount = m_dia->getChildCount(); + 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( i ); + pyDia::SymbolPtr childSym = rootSym->getChildByIndex( i ); - TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym ); + ULONG symTag = childSym->getSymTag(); - fieldCount += baseType->getFieldCount(); - } - - return fieldCount; + 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 ) ); + } + } } ///////////////////////////////////////////////////////////////////////////////////// @@ -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( (*it)->getSize() ); - } - return false; -} - -///////////////////////////////////////////////////////////////////////////////////// - TypeInfoPtr EnumTypeInfo::getField( const std::string &fieldName ) { pyDia::SymbolPtr field = m_dia->getChildByName( fieldName ); TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName ); diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 6190ba5..488dcd0 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -282,15 +282,15 @@ protected: 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; + + typedef std::pair< std::string, TypeInfoPtr > FieldType; + + typedef std::vector< FieldType > FieldList; + + FieldList m_fields; + + void getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset = 0 ); }; ///////////////////////////////////////////////////////////////////////////////////