Commit e90c89e2 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger:[New CDB]: Add casting to SymbolGroupValue for QVariant.

Reorganize simple dumpers to be easily nested, add QVariant
dumper. Introduce enumeration and detection routine for types.
parent 60cd3d18
......@@ -496,6 +496,14 @@ std::string SymbolGroupNode::type() const
return SUCCEEDED(hr) ? std::string(buf) : std::string();
}
unsigned SymbolGroupNode::size() const
{
DEBUG_SYMBOL_ENTRY entry;
if (SUCCEEDED(m_symbolGroup->debugSymbolGroup()->GetSymbolEntryInformation(m_index, &entry)))
return entry.Size;
return 0;
}
ULONG64 SymbolGroupNode::address() const
{
ULONG64 address = 0;
......@@ -654,6 +662,8 @@ void SymbolGroupNode::debug(std::ostream &str, unsigned verbosity, unsigned dept
str << " DumperFailed";
if (m_flags & ExpandedByDumper)
str << " ExpandedByDumper";
if (m_flags & AdditionalSymbol)
str << " AdditionalSymbol";
str << ' ';
}
if (verbosity) {
......@@ -745,33 +755,34 @@ static inline std::string msgCannotAddSymbol(const std::string &name, const std:
}
// For root nodes, only: Add a new symbol by name
bool SymbolGroupNode::addSymbolByName(const std::string &name,
const std::string &iname,
std::string *errorMessage)
SymbolGroupNode *SymbolGroupNode::addSymbolByName(const std::string &name,
const std::string &iname,
std::string *errorMessage)
{
ULONG index = DEBUG_ANY_ID; // Append
HRESULT hr = m_symbolGroup->debugSymbolGroup()->AddSymbol(name.c_str(), &index);
if (FAILED(hr)) {
*errorMessage = msgCannotAddSymbol(name, msgDebugEngineComFailed("AddSymbol", hr));
return false;
return 0;
}
SymbolParameterVector parameters(1, DEBUG_SYMBOL_PARAMETERS());
hr = m_symbolGroup->debugSymbolGroup()->GetSymbolParameters(index, 1, &(*parameters.begin()));
if (FAILED(hr)) { // Should never fail
*errorMessage = msgCannotAddSymbol(name, msgDebugEngineComFailed("GetSymbolParameters", hr));
return false;
return 0;
}
// Paranoia: Check for cuckoo's eggs (which should not happen)
if (parameters.front().ParentSymbol != m_index) {
*errorMessage = msgCannotAddSymbol(name, "Parent id mismatch");
return false;
return 0;
}
SymbolGroupNode *node = new SymbolGroupNode(m_symbolGroup, index,
name, iname.empty() ? name : iname,
this);
node->parseParameters(0, 0, parameters);
node->addFlags(AdditionalSymbol);
m_children.push_back(node);
return true;
return node;
}
static inline std::string msgNotFound(const std::string &nodeName)
......@@ -919,7 +930,7 @@ bool SymbolGroup::typeCast(const std::string &iname, const std::string &desiredT
return node->typeCast(desiredType, errorMessage);
}
bool SymbolGroup::addSymbol(const std::string &name, const std::string &iname, std::string *errorMessage)
SymbolGroupNode *SymbolGroup::addSymbol(const std::string &name, const std::string &iname, std::string *errorMessage)
{
return m_root->addSymbolByName(name, iname, errorMessage);
}
......
......@@ -67,7 +67,8 @@ public:
DumperOk = 0x4, // Internal dumper ran, value set
DumperFailed = 0x8, // Internal dumper failed
DumperMask = DumperNotApplicable|DumperOk|DumperFailed,
ExpandedByDumper = 0x10
ExpandedByDumper = 0x10,
AdditionalSymbol = 0x20 // Introduced by addSymbol, should not be visible
};
typedef std::vector<DEBUG_SYMBOL_PARAMETERS> SymbolParameterVector;
typedef std::vector<SymbolGroupNode *> SymbolGroupNodePtrVector;
......@@ -83,9 +84,9 @@ public:
static SymbolGroupNode *create(SymbolGroup *sg, const std::string &name, const SymbolParameterVector &vec);
// For root nodes, only: Add a new symbol by name
bool addSymbolByName(const std::string &name, // Expression like 'myarray[1]'
const std::string &iname, // Desired iname, defaults to name
std::string *errorMessage);
SymbolGroupNode *addSymbolByName(const std::string &name, // Expression like 'myarray[1]'
const std::string &iname, // Desired iname, defaults to name
std::string *errorMessage);
const std::string &name() const { return m_name; }
std::string fullIName() const;
......@@ -98,6 +99,7 @@ public:
SymbolGroupNode *childByIName(const char *) const;
const SymbolGroupNode *parent() const { return m_parent; }
SymbolGroup *symbolGroup() const { return m_symbolGroup; }
// I/O: Gdbmi dump for Visitors
void dump(std::ostream &str, const SymbolGroupValueContext &ctx);
......@@ -109,6 +111,7 @@ public:
std::wstring displayValue(const SymbolGroupValueContext &ctx);
std::string type() const;
unsigned size() const; // Size of value
ULONG64 address() const;
bool accept(SymbolGroupNodeVisitor &visitor, unsigned child, unsigned depth);
......@@ -223,9 +226,9 @@ public:
// Cast an (unexpanded) node
bool typeCast(const std::string &iname, const std::string &desiredType, std::string *errorMessage);
// Add a symbol by name expression
bool addSymbol(const std::string &name, // Expression like 'myarray[1]'
const std::string &iname, // Desired iname, defaults to name
std::string *errorMessage);
SymbolGroupNode *addSymbol(const std::string &name, // Expression like 'myarray[1]'
const std::string &iname, // Desired iname, defaults to name
std::string *errorMessage);
bool accept(SymbolGroupNodeVisitor &visitor) const;
......
......@@ -61,12 +61,20 @@ public:
// Access children by name or index (0-based)
SymbolGroupValue operator[](const char *name) const;
SymbolGroupValue operator[](unsigned) const;
// take address and cast to desired (pointer) type
SymbolGroupValue typeCast(const char *type) const;
// take pointer value and cast to desired (pointer) type
SymbolGroupValue pointerTypeCast(const char *type) const;
std::string type() const;
std::wstring value() const;
unsigned size() const;
static inline unsigned sizeOf(const char *type) { return GetTypeSize(type); }
int intValue(int defaultValue = -1) const;
double floatValue(double defaultValue = -999) const;
ULONG64 pointerValue(ULONG64 defaultValue = 0) const;
ULONG64 address() const;
// Return allocated array of data pointed to
unsigned char *pointerData(unsigned length) const;
// Return data pointed to as wchar_t/std::wstring (UTF16)
......@@ -76,12 +84,43 @@ public:
private:
bool ensureExpanded() const;
SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;
SymbolGroupNode *m_node;
SymbolGroupValueContext m_context;
mutable std::string m_errorMessage;
};
// Helpers for detecting types
enum KnownType {
KT_Unknown =0,
KT_Qt_Type = 0x10000,
KT_STL_Type = 0x20000,
KT_ContainerType = 0x40000,
KT_QChar = KT_Qt_Type + 1,
KT_QByteArray = KT_Qt_Type + 2,
KT_QString = KT_Qt_Type + 3,
KT_QColor = KT_Qt_Type + 4,
KT_QFlags = KT_Qt_Type + 5,
KT_QDate = KT_Qt_Type + 6,
KT_QTime = KT_Qt_Type + 7,
KT_QPoint = KT_Qt_Type + 8,
KT_QPointF = KT_Qt_Type + 9,
KT_QSize = KT_Qt_Type + 11,
KT_QSizeF = KT_Qt_Type + 12,
KT_QLine = KT_Qt_Type + 13,
KT_QLineF = KT_Qt_Type + 14,
KT_QRect = KT_Qt_Type + 15,
KT_QRectF = KT_Qt_Type + 16,
KT_QVariant = KT_Qt_Type + 17,
KT_QBasicAtomicInt = KT_Qt_Type + 18,
KT_QAtomicInt = KT_Qt_Type + 19,
KT_StdString = KT_STL_Type + 1,
KT_StdWString = KT_STL_Type + 2
};
KnownType knownType(const std::string &type);
// Dump builtin simple types using SymbolGroupValue expressions,
// returning SymbolGroupNode dumper flags.
unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx, std::wstring *s);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment