return AbstractSymbolGroupNodePtrVector();
const std::string innerType = fixInnerType(innerTypes.front(), v.context());
const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str());
+ if (debugVector)
+ DebugPrint() << "QList " << v.name() << " inner type " << innerType << ' ' << innerTypeSize;
if (!innerTypeSize)
return AbstractSymbolGroupNodePtrVector();
/* QList<> is:
innerType, count);
// Check condition for large||static.
bool isLargeOrStatic = innerTypeSize > pointerSize;
- if (!isLargeOrStatic) {
+ if (!isLargeOrStatic && !SymbolGroupValue::isPointerType(innerType)) {
const KnownType kt = knownType(innerType, false); // inner type, no 'class ' prefix.
- if (kt != KT_Unknown && !(knownType(innerType, false) & (KT_Qt_PrimitiveType|KT_Qt_MovableType)))
+ if (kt != KT_Unknown && !(kt & (KT_POD_Type|KT_Qt_PrimitiveType|KT_Qt_MovableType)))
isLargeOrStatic = true;
}
+ if (debugVector)
+ DebugPrint() << "isLargeOrStatic " << isLargeOrStatic;
if (isLargeOrStatic) {
// Retrieve the pointer array ourselves to avoid having to evaluate '*(class foo**)'
if (void *data = readPointerArray(arrayAddress, count, v.context())) {
"-c complex dumpers"},
{"locals",
"Prints local variables of symbol group in GDBMI or debug format",
- "[-t token] [T formats] [-I formats] [-f debugfilter] [-c] [-h] [-d] [-e expand-list] [-u uninitialized-list]\n<frame-number> [iname]\n"
+ "[-t token] [-v] [T formats] [-I formats] [-f debugfilter] [-c] [-h] [-d] [-e expand-list] [-u uninitialized-list]\n<frame-number> [iname]\n"
"-h human-readable ouput\n"
+ "-v increase verboseness of dumping\n"
"-d debug output\n"
"-f debug_filter\n"
"-c complex dumpers\n"
StringVector expandedInames;
StringVector uninitializedInames;
DumpParameters parameters;
+ SymbolGroupValue::verbose = 0;
// Parse away options
while (!tokens.empty() && tokens.front().size() == 2 && tokens.front().at(0) == '-') {
const char option = tokens.front().at(1);
debugFilter = tokens.front();
tokens.pop_front();
break;
+ case 'v':
+ SymbolGroupValue::verbose++;
+ tokens.pop_front();
+ break;
case 'e':
if (tokens.empty()) {
*errorMessage = singleLineUsage(commandDescriptions[CmdLocals]);
return symbolGroupFixedValue();
}
-void SymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname,
+int SymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname,
const DumpParameters &p, const SymbolGroupValueContext &ctx)
{
- dumpNode(str, name(), visitingFullIname, p, ctx);
+ return dumpNode(str, name(), visitingFullIname, p, ctx);
}
-void SymbolGroupNode::dumpNode(std::ostream &str,
- const std::string &aName,
- const std::string &aFullIName,
- const DumpParameters &dumpParameters,
- const SymbolGroupValueContext &ctx)
+int SymbolGroupNode::dumpNode(std::ostream &str,
+ const std::string &aName,
+ const std::string &aFullIName,
+ const DumpParameters &dumpParameters,
+ const SymbolGroupValueContext &ctx)
{
const std::string t = type();
SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, aFullIName);
if (childCountGuess != 0)
valueEditable = false;
str << ",valueenabled=\"" << (valueEnabled ? "true" : "false") << '"'
- << ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"'
- << ",numchild=\"" << childCountGuess << '"';
+ << ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"';
+ return childCountGuess;
}
void SymbolGroupNode::debug(std::ostream &str,
return new ReferenceSymbolGroupNode(nameIname.first, nameIname.second, referencedNode);
}
-void ReferenceSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname,
+int ReferenceSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname,
const DumpParameters &p, const SymbolGroupValueContext &ctx)
{
// Let the referenced node dump with our iname/name
- m_referencedNode->dumpNode(str, name(), visitingFullIname, p, ctx);
+ return m_referencedNode->dumpNode(str, name(), visitingFullIname, p, ctx);
}
void ReferenceSymbolGroupNode::debug(std::ostream &str, const std::string &visitingFullIname,
return new MapNodeSymbolGroupNode(nameIname.first, nameIname.second, address, type, keyRN, valueRN);
}
-void MapNodeSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname,
+int MapNodeSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname,
const DumpParameters &, const SymbolGroupValueContext &)
{
SymbolGroupNode::dumpBasicData(str, name(), visitingFullIname);
if (m_address)
str << ",addr=\"0x" << std::hex << m_address << '"';
str << ",type=\"" << m_type << "\",valueencoded=\"0\",value=\"\",valueenabled=\"false\""
- ",valueeditable=\"false\",numchild=\"2\"";
+ ",valueeditable=\"false\"";
+ return 2;
}
void MapNodeSymbolGroupNode::debug(std::ostream &os, const std::string &visitingFullIname,
indentStream(m_os, depth * 2);
}
m_os << '{';
- node->dump(m_os, fullIname, m_parameters, m_context);
+ const int childCount = node->dump(m_os, fullIname, m_parameters, m_context);
+ m_os << ",numchild=\"" << childCount << '"';
+ if (!childCount)
+ m_visitChildren = false;
if (m_visitChildren) { // open children array
m_os << ",children=[";
} else { // No children, close array.
const std::string &visitingParentIname,
unsigned child, unsigned depth);
- // I/O: GDBMI dump for Visitors
- virtual void dump(std::ostream &str, const std::string &visitingFullIname,
- const DumpParameters &p, const SymbolGroupValueContext &ctx) = 0;
+ // I/O: GDBMI dump for Visitors, return child count
+ virtual int dump(std::ostream &str, const std::string &visitingFullIname,
+ const DumpParameters &p, const SymbolGroupValueContext &ctx) = 0;
// I/O: debug output for Visitors
virtual void debug(std::ostream &os, const std::string &visitingFullIname,
unsigned verbosity, unsigned depth) const;
SymbolGroup *symbolGroup() const { return m_symbolGroup; }
// I/O: Gdbmi dump for Visitors
- virtual void dump(std::ostream &str, const std::string &fullIname,
+ virtual int dump(std::ostream &str, const std::string &fullIname,
const DumpParameters &p, const SymbolGroupValueContext &ctx);
- // Dumper functionality for reference nodes.
- void dumpNode(std::ostream &str, const std::string &aName, const std::string &aFullIName,
+ // Dumper functionality for reference nodes, returns child count guess
+ int dumpNode(std::ostream &str, const std::string &aName, const std::string &aFullIName,
const DumpParameters &p, const SymbolGroupValueContext &ctx);
// I/O: debug for Visitors
static ReferenceSymbolGroupNode *createArrayNode(int index,
SymbolGroupNode *referencedNode);
- virtual void dump(std::ostream &str, const std::string &visitingFullIname,
+ virtual int dump(std::ostream &str, const std::string &visitingFullIname,
const DumpParameters &p, const SymbolGroupValueContext &ctx);
virtual void debug(std::ostream &os, const std::string &visitingFullIname,
unsigned verbosity, unsigned depth) const;
create(int i, ULONG64 address /* = 0 */, const std::string &type,
SymbolGroupNode *key, SymbolGroupNode *value);
- virtual void dump(std::ostream &str, const std::string &visitingFullIname,
+ virtual int dump(std::ostream &str, const std::string &visitingFullIname,
const DumpParameters &p, const SymbolGroupValueContext &ctx);
virtual void debug(std::ostream &os, const std::string &visitingFullIname,
unsigned verbosity, unsigned depth) const;
#include <iomanip>
#include <algorithm>
+unsigned SymbolGroupValue::verbose = 0;
+
SymbolGroupValue::SymbolGroupValue(const std::string &parentError) :
m_node(0), m_errorMessage(parentError)
{
const SymbolGroupValueContext &ctx) :
m_node(node), m_context(ctx)
{
- if (m_node && !m_node->isMemoryAccessible()) // Invalid if no value
+ if (m_node && !m_node->isMemoryAccessible()) { // Invalid if no value
m_node = 0;
+ if (SymbolGroupValue::verbose)
+ DebugPrint() << name() << " memory access error";
+ }
}
SymbolGroupValue::SymbolGroupValue() :
if (index < m_node->children().size())
if (SymbolGroupNode *n = m_node->childAt(index)->asSymbolGroupNode())
return SymbolGroupValue(n, m_context);
+ if (SymbolGroupValue::verbose)
+ DebugPrint() << this->name() << "::operator[" << index << "](const char*) fails";
return SymbolGroupValue(m_errorMessage);
}
m_node->addFlags(SymbolGroupNode::ExpandedByDumper);
return true;
}
+ if (SymbolGroupValue::verbose)
+ DebugPrint() << "Expand failure of '" << name() << "': " << m_errorMessage;
return false;
}
if (AbstractSymbolGroupNode *child = m_node->childByIName(name))
if (SymbolGroupNode *n = child->asSymbolGroupNode())
return SymbolGroupValue(n, m_context);
+ if (SymbolGroupValue::verbose)
+ DebugPrint() << this->name() << "::operator[](" << name << ") fails for " << name;
return SymbolGroupValue(m_errorMessage);
}
if (integerFromString(wStringToString(v), &rc))
return rc;
}
+ if (SymbolGroupValue::verbose)
+ DebugPrint() << name() << "::intValue() fails";
return defaultValue;
}
if (integerFromString(wStringToString(value()), &rc))
return rc;
}
+ if (SymbolGroupValue::verbose)
+ DebugPrint() << name() << "::pointerValue() fails";
return defaultValue;
}
// get the inner types: "QMap<int, double>" -> "int", "double"
static std::vector<std::string> innerTypesOf(const std::string &t);
+ static unsigned verbose;
+
private:
bool ensureExpanded() const;
SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;