[0.2.x] ~ check recursive type building

git-svn-id: https://pykd.svn.codeplex.com/svn@79577 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2012-09-14 16:46:35 +00:00 committed by Mikhail I. Izmestev
parent 13b1676d6f
commit bd94e142d1
3 changed files with 91 additions and 37 deletions

View File

@ -8,25 +8,7 @@ namespace pykd {
////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/)
{
return TypeInfoPtr( new CustomStruct(name, alignReq) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG CustomStruct::getSize()
{
if (UdtFieldColl::empty())
return 0;
UdtUtils::Field &field = UdtFieldColl::last();
return field.m_offset + field.m_type->getSize();
}
////////////////////////////////////////////////////////////////////////////////
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
{
bool fieldExist = false;
try
@ -40,10 +22,71 @@ void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldTy
}
if (fieldExist)
throw TypeException(getName(), "duplicate field name: " + fieldName);
}
////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfTypeRecursive(TypeInfoPtr type)
{
if (type->is(this))
throw TypeException(getName(), "wrong type of field");
return throwIfTypeRecursiveImpl(type);
}
////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
{
if (type->isEnum())
return;
try
{
const ULONG fields = type->getFieldCount();
for (ULONG i = 0; i < fields; ++i)
{
TypeInfoPtr fileldType = type->getFieldByIndex(i);
if (fileldType->is(this))
throw TypeException(getName(), "wrong type of field");
throwIfTypeRecursiveImpl(fileldType);
}
}
catch (const TypeException &except)
{
DBG_UNREFERENCED_PARAMETER(except);
}
}
////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/)
{
return TypeInfoPtr( new CustomStruct(name, alignReq) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG CustomStruct::getSize()
{
if (Base::empty())
return 0;
UdtUtils::Field &field = Base::last();
return field.m_offset + field.m_type->getSize();
}
////////////////////////////////////////////////////////////////////////////////
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{
Base::throwIfFiledExist(fieldName);
Base::throwIfTypeRecursive(fieldType);
ULONG offset = getSize();
offset += offset % (m_align ? m_align : fieldType->getAlignReq());
UdtFieldColl::push_back(
Base::push_back(
UdtUtils::Field(offset, fieldName, fieldType)
);
}
@ -73,20 +116,10 @@ ULONG CustomUnion::getSize()
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{
bool fieldExist = false;
try
{
lookupField(fieldName);
fieldExist = true;
}
catch (const TypeException &except)
{
DBG_UNREFERENCED_PARAMETER(except);
}
if (fieldExist)
throw TypeException(getName(), "duplicate field name: " + fieldName);
Base::throwIfFiledExist(fieldName);
Base::throwIfTypeRecursive(fieldType);
UdtFieldColl::push_back(
Base::push_back(
UdtUtils::Field(0, fieldName, fieldType)
);
}

View File

@ -12,14 +12,30 @@ namespace pykd {
////////////////////////////////////////////////////////////////////////////////
class CustomStruct : public UdtFieldColl
class CustomTypeBase : public UdtFieldColl
{
typedef UdtFieldColl Base;
protected:
CustomTypeBase(const std::string &name) : UdtFieldColl(name) {}
void throwIfFiledExist(const std::string &fieldName);
void throwIfTypeRecursive(TypeInfoPtr type);
private:
void throwIfTypeRecursiveImpl(TypeInfoPtr type);
};
////////////////////////////////////////////////////////////////////////////////
class CustomStruct : public CustomTypeBase
{
typedef CustomTypeBase Base;
public:
static TypeInfoPtr create(const std::string &name, ULONG align = 0);
protected:
CustomStruct(const std::string &name, ULONG align)
: UdtFieldColl(name), m_name(name), m_align(align)
: Base(name), m_name(name), m_align(align)
{
}
@ -42,13 +58,14 @@ private:
////////////////////////////////////////////////////////////////////////////////
class CustomUnion : public UdtFieldColl
class CustomUnion : public CustomTypeBase
{
typedef CustomTypeBase Base;
public:
static TypeInfoPtr create(const std::string &name);
protected:
CustomUnion(const std::string &name) : UdtFieldColl(name) {}
CustomUnion(const std::string &name) : Base(name) {}
virtual ULONG getSize() override;

View File

@ -211,6 +211,10 @@ public:
return m_virtualBaseType;
}
bool is(TypeInfo *rhs) const {
return this == rhs;
}
protected:
std::string getComplexName();