CDB: Fix STL debugger helpers for MSVC2012 beta.

In MSVC2012, more bases classes for std::string
and containers were introduced whereas std::pair_base
was removed compared to MSVC2010.

Add a findMember() function to be able to skip base
classes when looking for a certain member to finally
fix this issue.
Introduce SymbolGroupValue::parent()/childCount()
and simplify the helpers using it.

Change-Id: I7a6aad5c07739ca9cbf350489acd6d03bd1865e8
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Friedemann Kleint
2012-08-02 13:32:37 +02:00
committed by hjk
parent c45ae0e288
commit b5abaa27df
4 changed files with 113 additions and 102 deletions

View File

@@ -126,6 +126,22 @@ SymbolGroupValue SymbolGroupValue::operator[](unsigned index) const
return SymbolGroupValue(m_errorMessage);
}
unsigned SymbolGroupValue::childCount() const
{
if (ensureExpanded())
return unsigned(m_node->children().size());
return 0;
}
SymbolGroupValue SymbolGroupValue::parent() const
{
if (isValid())
if (AbstractSymbolGroupNode *aParent = m_node->parent())
if (SymbolGroupNode *parent = aParent->asSymbolGroupNode())
return SymbolGroupValue(parent, m_context);
return SymbolGroupValue("parent() invoked on invalid value.");
}
bool SymbolGroupValue::ensureExpanded() const
{
if (!isValid() || !m_node->canExpand())
@@ -205,7 +221,7 @@ int SymbolGroupValue::intValue(int defaultValue) const
return rc;
}
if (SymbolGroupValue::verbose)
DebugPrint() << name() << "::intValue() fails";
DebugPrint() << name() << '/' << type() << '/'<< m_errorMessage << ": intValue() fails";
return defaultValue;
}
@@ -217,7 +233,7 @@ ULONG64 SymbolGroupValue::pointerValue(ULONG64 defaultValue) const
return rc;
}
if (SymbolGroupValue::verbose)
DebugPrint() << name() << "::pointerValue() fails";
DebugPrint() << name() << '/'<< type() << '/' << m_errorMessage << ": pointerValue() fails";
return defaultValue;
}
@@ -383,6 +399,30 @@ SymbolGroupValue SymbolGroupValue::typeCastedValue(ULONG64 address, const char *
return SymbolGroupValue();
}
SymbolGroupValue SymbolGroupValue::findMember(const SymbolGroupValue &start,
const std::string &symbolName)
{
const unsigned count = start.childCount();
for (unsigned i = 0; i < count ; ++i) { // check members
const SymbolGroupValue child = start[i];
if (child.name() == symbolName)
return child;
}
// Recurse down base classes at the beginning that have class names
// as value.
for (unsigned i = 0; i < count; ++i) {
const SymbolGroupValue child = start[i];
const std::wstring value = child.value();
if (value.compare(0, 6, L"class ") && value.compare(0, 7, L"struct ")) {
break;
} else {
if (SymbolGroupValue r = findMember(child, symbolName))
return r;
}
}
return SymbolGroupValue();
}
std::wstring SymbolGroupValue::wcharPointerData(unsigned charCount, unsigned maxCharCount) const
{
const bool truncated = charCount > maxCharCount;
@@ -2047,14 +2087,10 @@ static inline bool dumpQWindow(const SymbolGroupValue &v, std::wostream &str, vo
// Dump a std::string.
static bool dumpStd_W_String(const SymbolGroupValue &v, int type, std::wostream &str)
{
SymbolGroupValue bx = v[unsigned(0)]["_Bx"];
int reserved = 0;
if (bx) { // MSVC 2010
reserved = v[unsigned(0)]["_Myres"].intValue();
} else { // MSVC2008
bx = v["_Bx"];
reserved = v["_Myres"].intValue();
}
// Find 'bx'. MSVC 2012 has 2 base classes, MSVC 2010 1,
// and MSVC2008 none
const SymbolGroupValue bx = SymbolGroupValue::findMember(v, "_Bx");
const int reserved = bx.parent()["_Myres"].intValue();
if (!bx || reserved < 0)
return false;
// 'Buf' array for small strings, else pointer 'Ptr'.