static inline std::string msgLocalsUsage(PCSTR args)
{
std::ostringstream str;
- str << "Invalid parameter: '" << args << "' (usage: locals [-d] <frame> [iname]).";
+ str << "Invalid parameter: '" << args
+ << "'\nUsage: locals [-t token] [-h] [-d] [-e expandset] [-u uninitializedset] <frame> [iname]).\n"
+ "-h human-readable ouput\n"
+ "-d debug output\n-e expandset Comma-separated list of expanded inames\n"
+ "-u uninitializedset Comma-separated list of uninitialized inames\n";
return str.str();
}
std::string iname;
StringList tokens = commandTokens<StringList>(args, token);
+ StringVector expandedInames;
+ StringVector uninitializedInames;
+ // Parse away options
while (!tokens.empty() && tokens.front().size() == 2 && tokens.front().at(0) == '-') {
- // Parse options -d (debug)/- humanreadable GDBMI
- switch (tokens.front().at(1)) {
+ const char option = tokens.front().at(1);
+ tokens.pop_front();
+ switch (option) {
case 'd':
debugOutput++;
break;
case 'h':
humanReadableGdbmi = true;
break;
+ case 'u':
+ if (tokens.empty()) {
+ *errorMessage = msgLocalsUsage(args);
+ return std::string();
+ }
+ split(tokens.front(), ',', std::back_inserter(uninitializedInames));
+ tokens.pop_front();
+ break;
+ case 'e':
+ if (tokens.empty()) {
+ *errorMessage = msgLocalsUsage(args);
+ return std::string();
+ }
+ split(tokens.front(), ',', std::back_inserter(expandedInames));
+ tokens.pop_front();
+ break;
}
- tokens.pop_front();
}
+ // Frame and iname
unsigned frame;
if (tokens.empty() || sscanf(tokens.front().c_str(), "%u", &frame) != 1) {
*errorMessage = msgLocalsUsage(args);
SymbolGroup * const symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(), exc.threadId(), frame, errorMessage);
if (!symGroup)
return std::string();
-
+ if (!expandedInames.empty())
+ symGroup->expandList(expandedInames, errorMessage);
+ if (!uninitializedInames.empty())
+ symGroup->markUninitialized(uninitializedInames);
// Complete dump
if (iname.empty())
return debugOutput ? symGroup->debug(debugOutput - 1) : symGroup->dump(humanReadableGdbmi);
enum { debug = 0 };
typedef std::vector<int>::size_type VectorIndexType;
+typedef std::vector<std::string> StringVector;
const char rootNameC[] = "local";
// ------- SymbolGroupNode
SymbolGroupNode::SymbolGroupNode(CIDebugSymbolGroup *symbolGroup,
- const std::string &n,
+ const std::string &name,
+ const std::string &iname,
SymbolGroupNode *parent) :
- m_symbolGroup(symbolGroup), m_parent(parent), m_name(n)
+ m_symbolGroup(symbolGroup), m_parent(parent), m_name(name), m_iname(iname), m_flags(0)
{
memset(&m_parameters, 0, sizeof(DEBUG_SYMBOL_PARAMETERS));
m_parameters.ParentSymbol = DEBUG_ANY_ID;
return m_parent && (m_parent->m_parameters.Flags & DEBUG_SYMBOL_IS_ARRAY);
}
-// iName: Fix array elements to be named 'array.0' instead of 'array.[0]' so
-// that sorting in Qt Creator works.
-std::string SymbolGroupNode::iName() const
-{
- std::string rc = m_name;
-
- //rc += isArrayElement() ? 'a' : 'n';
- if (isArrayElement() && !rc.empty() && rc.at(0) == '[') {
- const std::string::size_type last = rc.size() - 1;
- if (rc.at(last) == ']') {
- rc.erase(last, 1);
- rc.erase(0, 1);
- }
- }
- return rc;
-}
-
// Return full iname as 'locals.this.m_sth'.
std::string SymbolGroupNode::fullIName() const
{
return rc;
}
+// Fix an array iname "[0]" -> "0" for sorting to work correctly
+static inline void fixArrayIname(std::string *iname)
+{
+ if (!iname->empty() && iname->at(0) == '[') {
+ const std::string::size_type last = iname->size() - 1;
+ if (iname->at(last) == ']') {
+ iname->erase(last, 1);
+ iname->erase(0, 1);
+ }
+ }
+}
+
+// Fix up names and inames
+static inline void fixNames(bool isTopLevel, StringVector *names, StringVector *inames)
+{
+ if (names->empty())
+ return;
+ unsigned unnamedId = 1;
+ /* 1) Fix name="__formal", which occurs when someone writes "void foo(int /* x * /)..."
+ * 2) Fix array inames for sorting: "[6]" -> name="[6]",iname="6"
+ * 3) For toplevels: Fix shadowed variables in the order the debugger expects them:
+ \code
+ int x; // Occurrence (1), should be reported as name="x <shadowed 1>"/iname="x#1"
+ if (true) {
+ int x = 5; (2) // Occurrence (2), should be reported as name="x"/iname="x"
+ }
+ \endcode */
+ StringVector::iterator nameIt = names->begin();
+ const StringVector::iterator namesEnd = names->end();
+ for (StringVector::iterator iNameIt = inames->begin(); nameIt != namesEnd ; ++nameIt, ++iNameIt) {
+ std::string &name = *nameIt;
+ std::string &iname = *iNameIt;
+ if (name.empty() || name == "__formal") {
+ const std::string number = toString(unnamedId++);
+ name = "<unnamed " + number + '>';
+ iname = "unnamed#" + number;
+ } else {
+ fixArrayIname(&iname);
+ }
+ if (isTopLevel) {
+ if (const StringVector::size_type shadowCount = std::count(nameIt + 1, namesEnd, name)) {
+ const std::string number = toString(shadowCount);
+ name += " <shadowed ";
+ name += number;
+ name += '>';
+ iname += '#';
+ iname += number;
+ }
+ }
+ }
+}
+
// Index: Index of symbol, parameterOffset: Looking only at a part of the symbol array, offset
void SymbolGroupNode::parseParameters(VectorIndexType index,
VectorIndexType parameterOffset,
const VectorIndexType size = vec.size();
// Scan the top level elements
+ StringVector names;
+ names.reserve(size);
+ // Pass 1) Determine names. We need the complete set first in order to do some corrections.
const VectorIndexType startIndex = isTopLevel ? 0 : index + 1;
for (VectorIndexType pos = startIndex - parameterOffset; pos < size ; pos++ ) {
if (vec.at(pos).ParentSymbol == index) {
const VectorIndexType symbolGroupIndex = pos + parameterOffset;
- HRESULT hr = m_symbolGroup->GetSymbolName(ULONG(symbolGroupIndex), buf, BufSize, &obtainedSize);
- const std::string name = SUCCEEDED(hr) ? std::string(buf) : std::string("unnamed");
- SymbolGroupNode *child = new SymbolGroupNode(m_symbolGroup, name, this);
+ if (FAILED(m_symbolGroup->GetSymbolName(ULONG(symbolGroupIndex), buf, BufSize, &obtainedSize)))
+ buf[0] = '\0';
+ names.push_back(std::string(buf));
+ }
+ }
+ // 2) Fix names
+ StringVector inames = names;
+ fixNames(isTopLevel, &names, &inames);
+ // Pass 3): Add nodes with fixed names
+ StringVector::size_type nameIndex = 0;
+ for (VectorIndexType pos = startIndex - parameterOffset; pos < size ; pos++ ) {
+ if (vec.at(pos).ParentSymbol == index) {
+ const VectorIndexType symbolGroupIndex = pos + parameterOffset;
+ SymbolGroupNode *child = new SymbolGroupNode(m_symbolGroup, names.at(nameIndex),
+ inames.at(nameIndex), this);
child->parseParameters(symbolGroupIndex, parameterOffset, vec);
m_children.push_back(child);
+ nameIndex++;
}
}
if (isTopLevel)
SymbolGroupNode *SymbolGroupNode::create(CIDebugSymbolGroup *sg, const std::string &name, const SymbolGroup::SymbolParameterVector &vec)
{
- SymbolGroupNode *rc = new SymbolGroupNode(sg, name);
+ SymbolGroupNode *rc = new SymbolGroupNode(sg, name, name);
rc->parseParameters(DEBUG_ANY_ID, 0, vec);
return rc;
}
str << ",addr=\"" << std::hex << std::showbase << addr << std::noshowbase << std::dec
<< '"';
- ULONG obtainedSize = 0;
- if (const wchar_t *wbuf = getValue(index, &obtainedSize)) {
- const ULONG valueSize = obtainedSize - 1;
- // ASCII or base64?
- if (isSevenBitClean(wbuf, valueSize)) {
- std::wstring value = wbuf;
- fixValue(type, &value);
- str << ",valueencoded=\"0\",value=\"" << gdbmiWStringFormat(value) << '"';
- } else {
- str << ",valueencoded=\"2\",value=\"";
- base64Encode(str, reinterpret_cast<const unsigned char *>(wbuf), valueSize * sizeof(wchar_t));
- str << '"';
+ bool valueEditable = true;
+ bool valueEnabled = true;
+
+ const bool uninitialized = m_flags & Uninitialized;
+ if (uninitialized) {
+ valueEditable = valueEnabled = false;
+ str << ",valueencoded=\"0\",value=\"<not in scope>\"";
+ } else {
+ ULONG obtainedSize = 0;
+ if (const wchar_t *wbuf = getValue(index, &obtainedSize)) {
+ const ULONG valueSize = obtainedSize - 1;
+ // ASCII or base64?
+ if (isSevenBitClean(wbuf, valueSize)) {
+ std::wstring value = wbuf;
+ fixValue(type, &value);
+ str << ",valueencoded=\"0\",value=\"" << gdbmiWStringFormat(value) << '"';
+ } else {
+ str << ",valueencoded=\"2\",value=\"";
+ base64Encode(str, reinterpret_cast<const unsigned char *>(wbuf), valueSize * sizeof(wchar_t));
+ str << '"';
+ }
+ delete [] wbuf;
}
- delete [] wbuf;
}
// Children: Dump all known or subelements (guess).
- const VectorIndexType childCountGuess = m_children.empty() ? m_parameters.SubElements : m_children.size();
+ const VectorIndexType childCountGuess = uninitialized ? 0 :
+ (m_children.empty() ? m_parameters.SubElements : m_children.size());
// No children..suppose we are editable and enabled
- if (childCountGuess == 0)
- str << ",valueenabled=\"true\",valueeditable=\"true\"";
- str << ",numchild=\"" << childCountGuess << '"';
- if (!m_children.empty()) {
+ if (childCountGuess != 0)
+ valueEditable = false;
+ str << ",valueenabled=\"" << (valueEnabled ? "true" : "false") << '"'
+ << ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"'
+ << ",numchild=\"" << childCountGuess << '"';
+ if (!uninitialized && !m_children.empty()) {
str << ",children=[";
if (humanReadable)
str << '\n';
void SymbolGroupNode::debug(std::ostream &str, unsigned verbosity, unsigned depth, ULONG index) const
{
indentStream(str, depth);
- str << '"' << m_name << "\" Children=" << m_children.size() << ' ' << m_parameters;
- if (verbosity)
- str << " Address=0x" << std::hex << address(index) << std::dec << " Type=\"" << getType(index) << "\" Value=\"" << gdbmiWStringFormat(rawValue(index)) << '"';
+ str << '"' << m_name << "\" Children=" << m_children.size() << ' ' << m_parameters
+ << " flags=" << m_flags;
+ if (verbosity) {
+ str << " Address=0x" << std::hex << address(index) << std::dec
+ << " Type=\"" << getType(index) << '"';
+ if (!(m_flags & Uninitialized))
+ str << "\" Value=\"" << gdbmiWStringFormat(rawValue(index)) << '"';
+ }
str << '\n';
}
*errorMessage = "No subelements to expand in node: " + fullIName();
return false;
}
+ if (m_flags & Uninitialized) {
+ *errorMessage = "Refusing to expand uninitialized node: " + fullIName();
+ return false;
+ }
const HRESULT hr = m_symbolGroup->ExpandSymbol(index, TRUE);
{
if (nodes.empty())
return 0;
- // Create a set with a key <level, name>. Also required for 1 node.
+ // Create a set with a key <level, name>. Also required for 1 node (see above).
InamePathEntrySet pathEntries;
const VectorIndexType nodeCount = nodes.size();
for (VectorIndexType i= 0; i < nodeCount; i++) {
return node->expand(index, errorMessage);
}
+// Mark uninitialized (top level only)
+void SymbolGroup::markUninitialized(const std::vector<std::string> &uniniNodes)
+{
+ if (m_root && !m_root->children().empty() && !uniniNodes.empty()) {
+ const std::vector<std::string>::const_iterator unIniNodesBegin = uniniNodes.begin();
+ const std::vector<std::string>::const_iterator unIniNodesEnd = uniniNodes.end();
+
+ const SymbolGroupNodePtrVector::const_iterator childrenEnd = m_root->children().end();
+ for (SymbolGroupNodePtrVector::const_iterator it = m_root->children().begin(); it != childrenEnd; ++it) {
+ if (std::find(unIniNodesBegin, unIniNodesEnd, (*it)->fullIName()) != unIniNodesEnd)
+ (*it)->setFlags((*it)->flags() | SymbolGroupNode::Uninitialized);
+ }
+ }
+}
+
static inline std::string msgAssignError(const std::string &nodeName,
const std::string &value,
const std::string &why)
SymbolGroupNode(const SymbolGroupNode&);
SymbolGroupNode& operator=(const SymbolGroupNode&);
public:
+ enum Flags {
+ Uninitialized = 0x1
+ };
typedef std::vector<DEBUG_SYMBOL_PARAMETERS> SymbolParameterVector;
typedef std::vector<SymbolGroupNode *> SymbolGroupNodePtrVector;
typedef SymbolGroupNodePtrVector::iterator SymbolGroupNodePtrVectorIterator;
explicit SymbolGroupNode(CIDebugSymbolGroup *symbolGroup,
const std::string &name,
+ const std::string &iname,
SymbolGroupNode *parent = 0);
~SymbolGroupNode() { removeChildren(); }
const std::string &name() const { return m_name; }
std::string fullIName() const;
- std::string iName() const;
+ const std::string &iName() const { return m_iname; }
const SymbolGroupNodePtrVector &children() const { return m_children; }
SymbolGroupNode *childAt(unsigned) const;
ULONG subElements() const { return m_parameters.SubElements; }
+ unsigned flags() const { return m_flags; }
+ void setFlags(unsigned f) { m_flags = f; }
+
private:
// Return allocated wide string array of value
wchar_t *getValue(ULONG index, ULONG *obtainedSize = 0) const;
DEBUG_SYMBOL_PARAMETERS m_parameters; // Careful when using ParentSymbol. It might not be correct.
SymbolGroupNodePtrVector m_children;
const std::string m_name;
+ const std::string m_iname;
+ unsigned m_flags;
};
/* Visitor that takes care of iterating over the nodes and the index bookkeeping.
// Expand a node list "locals.i1,locals.i2", expanding all nested child nodes
// (think mkdir -p).
unsigned expandList(const std::vector<std::string> &nodes, std::string *errorMessage);
+ // Mark uninitialized (top level only)
+ void markUninitialized(const std::vector<std::string> &nodes);
// Expand a single node "locals.A.B" requiring that "locals.A.B" is already visible
// (think mkdir without -p).
{
}
+void ByteArrayInputStream::appendSeparator(char c)
+{
+ if (!m_target.isEmpty() && !m_target.endsWith(c))
+ m_target.append(c);
+}
+
void hexPrefixOn(ByteArrayInputStream &bs)
{
bs.setHexPrefix(true);
bs.setIntegerBase(10);
}
+void blankSeparator(ByteArrayInputStream &bs)
+{
+ bs.appendSeparator();
+}
+
QByteArray trimFront(QByteArray in)
{
if (in.isEmpty())
bool hexPrefix() const { return m_hexPrefix; }
void setIntegerBase(int b) { m_integerBase = b; }
int integerBase() const { return m_integerBase; }
+ // Append a separator if required (target does not end with it)
+ void appendSeparator(char c = ' ');
private:
template <class IntType> void appendInt(IntType i);
void hexPrefixOff(ByteArrayInputStream &bs);
void hex(ByteArrayInputStream &bs);
void dec(ByteArrayInputStream &bs);
+void blankSeparator(ByteArrayInputStream &bs);
// Bytearray parse helpers
QByteArray trimFront(QByteArray in);
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
#include <QtCore/QDateTime>
+#include <QtGui/QToolTip>
#ifdef Q_OS_WIN
# include <utils/winutils.h>
Q_DECLARE_METATYPE(Debugger::Internal::MemoryViewAgent*)
enum { debug = 0 };
+enum { debugLocals = 0 };
enum { debugBreakpoints = 0 };
#if 0
namespace Debugger {
namespace Cdb {
+static const char localsPrefixC[] = "local.";
+
using namespace Debugger::Internal;
struct MemoryViewCookie {
// No numerical or any other expressions [yet]
if (!(exp.at(0).isLetter() || exp.at(0) == QLatin1Char('_')))
return;
- const QByteArray iname = QByteArray("local.") + exp.toAscii();
- const QModelIndex index = watchHandler()->itemIndex(iname);
- Q_UNUSED(index)
- Q_UNUSED(mousePos)
+ const QByteArray iname = QByteArray(localsPrefixC) + exp.toAscii();
+ if (const WatchData *data = watchHandler()->findItem(iname)) {
+ QToolTip::hideText();
+ QToolTip::showText(mousePos, data->toToolTip());
+ }
}
void CdbEngine::setupEngine()
showMessage(msg, LogError);
return;
}
- if (!flags & QuietCommand)
- showMessage(QString::fromLocal8Bit(cmd), LogInput);
const int token = m_nextCommandToken++;
if (!arguments.isEmpty())
str << ' ' << arguments;
+ if (!flags & QuietCommand)
+ showMessage(QString::fromLocal8Bit(fullCmd), LogInput);
+
CdbExtensionCommandPtr pendingCommand(new CdbExtensionCommand(fullCmd, token, flags, handler, nextCommandFlag, cookie));
m_extensionCommandQueue.push_back(pendingCommand);
const Debugger::Internal::StackFrames &frames = stackHandler()->frames();
QTC_ASSERT(index < frames.size(), return; )
- if (debug)
+ const StackFrame frame = frames.at(index);
+ if (debug || debugLocals)
qDebug("activateFrame idx=%d '%s' %d", index,
- qPrintable(frames.at(index).file), frames.at(index).line);
+ qPrintable(frame.file), frame.line);
stackHandler()->setCurrentIndex(index);
const bool showAssembler = !frames.at(index).isUsable();
if (showAssembler) { // Assembly code: Clean out model and force instruction mode.
watchHandler()->endCycle();
QAction *assemblerAction = theAssemblerAction();
if (assemblerAction->isChecked()) {
- gotoLocation(frames.at(index), true);
+ gotoLocation(frame, true);
} else {
assemblerAction->trigger(); // Seems to trigger update
}
return;
}
- gotoLocation(frames.at(index), true);
- // Watchers: Initial expand and query
+ gotoLocation(frame, true);
+ // Watchers: Initial expand, get uninitialized and query
+ QByteArray arguments;
+ ByteArrayInputStream str(arguments);
+ // Pre-expand
const QSet<QByteArray> expanded = watchHandler()->expandedINames();
if (!expanded.isEmpty()) {
- QByteArray expandArguments;
- ByteArrayInputStream expandStr(expandArguments);
- expandStr << index << ' ';
+ str << blankSeparator << "-e ";
int i = 0;
foreach(const QByteArray &e, expanded) {
if (i++)
- expandStr << ',';
- expandStr << e;
+ str << ',';
+ str << e;
}
- postExtensionCommand("expandlocals", expandArguments, 0, &CdbEngine::handleExpandLocals);
}
-
+ // Uninitialized variables if desired
+ if (debuggerCore()->boolSetting(UseCodeModel)) {
+ QStringList uninitializedVariables;
+ getUninitializedVariables(debuggerCore()->cppCodeModelSnapshot(),
+ frame.function, frame.file, frame.line, &uninitializedVariables);
+ if (!uninitializedVariables.isEmpty()) {
+ str << blankSeparator << "-u ";
+ int i = 0;
+ foreach(const QString &u, uninitializedVariables) {
+ if (i++)
+ str << ',';
+ str << localsPrefixC << u;
+ }
+ }
+ }
+ // Required arguments: frame
+ str << blankSeparator << index;
watchHandler()->beginCycle();
- postExtensionCommand("locals", QByteArray::number(index), 0, &CdbEngine::handleLocals);
+ postExtensionCommand("locals", arguments, 0, &CdbEngine::handleLocals);
}
void CdbEngine::selectThread(int index)
struct GdbMiRecursionContext
{
- GdbMiRecursionContext(int recursionLevelIn = 0) :
- recursionLevel(recursionLevelIn), childNumChild(-1), childIndex(0) {}
+ enum Type
+ {
+ Debugger, // Debugger symbol dump, recursive/symmetrical
+ GdbMacrosCpp // old gdbmacros.cpp format, unsymmetrical
+ };
+ GdbMiRecursionContext(Type t, int recursionLevelIn = 0) :
+ type(t), recursionLevel(recursionLevelIn), childNumChild(-1), childIndex(0) {}
+
+ const Type type;
int recursionLevel;
int childNumChild;
int childIndex;
QString v;
QByteArray b;
// Check for name/iname and use as expression default
- if (ctx.recursionLevel == 0) {
- // parents have only iname, from which name is derived
- QString iname;
- if (!gdbMiGetStringValue(&iname, root, "iname"))
- qWarning("Internal error: iname missing");
- w.iname = iname.toLatin1();
- w.name = iname;
- const int lastDotPos = w.name.lastIndexOf(QLatin1Char('.'));
- if (lastDotPos != -1)
- w.name.remove(0, lastDotPos + 1);
- w.exp = w.name.toLatin1();
+ w.sortId = ctx.childIndex;
+ // Fully symmetrical
+ if (ctx.type == GdbMiRecursionContext::Debugger) {
+ gdbMiGetByteArrayValue(&w.iname, root, "iname");
+ gdbMiGetStringValue(&w.name, root, "name");
+ gdbMiGetByteArrayValue(&w.exp, root, "exp");
} else {
- // Children can have a 'name' attribute. If missing, assume array index
- // For display purposes, it can be overridden by "key"
- if (!gdbMiGetStringValue(&w.name, root, "name")) {
- w.name = QString::number(ctx.childIndex);
- }
- // Set iname
- w.iname = ctx.parentIName;
- w.iname += '.';
- w.iname += w.name.toLatin1();
- // Key?
- QString key;
- if (gdbMiGetStringValue(&key, root, "key", "keyencoded")) {
- w.name = key.size() > 13 ? key.mid(0, 13) + QLatin1String("...") : key;
+ // gdbmacros.cpp: iname/name present according to recursion level
+ // Check for name/iname and use as expression default
+ if (ctx.recursionLevel == 0) {
+ // parents have only iname, from which name is derived
+ QString iname;
+ if (!gdbMiGetStringValue(&iname, root, "iname"))
+ qWarning("Internal error: iname missing");
+ w.iname = iname.toLatin1();
+ w.name = iname;
+ const int lastDotPos = w.name.lastIndexOf(QLatin1Char('.'));
+ if (lastDotPos != -1)
+ w.name.remove(0, lastDotPos + 1);
+ w.exp = w.name.toLatin1();
+ } else {
+ // Children can have a 'name' attribute. If missing, assume array index
+ // For display purposes, it can be overridden by "key"
+ if (!gdbMiGetStringValue(&w.name, root, "name")) {
+ w.name = QString::number(ctx.childIndex);
+ }
+ // Set iname
+ w.iname = ctx.parentIName;
+ w.iname += '.';
+ w.iname += w.name.toLatin1();
+ // Key?
+ QString key;
+ if (gdbMiGetStringValue(&key, root, "key", "keyencoded")) {
+ w.name = key.size() > 13 ? key.mid(0, 13) + QLatin1String("...") : key;
+ }
}
}
if (w.name.isEmpty()) {
if (children.empty())
return;
wl->back().setChildrenUnneeded();
- GdbMiRecursionContext nextLevelContext(ctx.recursionLevel + 1);
+ GdbMiRecursionContext nextLevelContext(ctx.type, ctx.recursionLevel + 1);
nextLevelContext.parentIName = w.iname;
gdbMiGetStringValue(&nextLevelContext.childType, root, "childtype");
if (!gdbMiGetIntValue(&nextLevelContext.childNumChild, root, "childnumchild"))
if (!root.isValid())
return false;
foreach(const GdbMi &child, root.children())
- gbdMiToWatchData(child, GdbMiRecursionContext(), l);
+ gbdMiToWatchData(child, GdbMiRecursionContext(GdbMiRecursionContext::Debugger), l);
} else {
root.fromStringMultiple(QByteArray(data));
if (!root.isValid())
return false;
- gbdMiToWatchData(root, GdbMiRecursionContext(), l);
+ gbdMiToWatchData(root, GdbMiRecursionContext(GdbMiRecursionContext::GdbMacrosCpp), l);
}
return true;
}