diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp index 5a39f8555ef..38ce0ec29fb 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp @@ -1029,19 +1029,26 @@ int SymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullInam // Return a watch expression basically as "*(type *)(address)" static inline std::string watchExpression(ULONG64 address, - const std::string &type, + const std::string &typeIn, int /* kType */, const std::string &module) { - std::ostringstream str; - str << "*("; - // Try to make watch expressions faster by at least qualifying templates with - // the local module. We cannot do expensive type lookup here. + std::string type = SymbolGroupValue::stripClassPrefixes(typeIn); + // Try to make watch expressions faster by at least qualifying + // templates with the local module. We cannot do expensive type + // lookup here. // We could insert a placeholder here for non-POD types indicating // that a type lookup should be done when inserting watches? - if (!module.empty() && type.find('>') != std::string::npos) - str << module << '!'; - str << SymbolGroupValue::pointerType(SymbolGroupValue::stripClassPrefixes(type)) << ')' << std::hex << std::showbase << address; + if (!module.empty() && type.find('>') != std::string::npos) { + type.insert(0, 1, '!'); + type.insert(0, module); + } + if (SymbolGroupValue::isArrayType(type)) + type = SymbolGroupValue::stripArrayType(type); + + std::ostringstream str; + str << "*(" << SymbolGroupValue::pointerType(type) << ')' + << std::hex << std::showbase << address; return str.str(); } @@ -1053,8 +1060,10 @@ int SymbolGroupNode::dumpNode(std::ostream &str, { const std::string t = type(); const ULONG64 addr = address(); - SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, - watchExpression(addr, t, m_dumperType, m_module)); + // Use name as watchExpression in case evaluation failed (watch group item + // names are the expression). + const std::string watchExp = t.empty() ? aName : watchExpression(addr, t, m_dumperType, m_module); + SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, watchExp); if (addr) str << ",addr=\"" << std::hex << std::showbase << addr << std::noshowbase << std::dec << '"'; diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index d20776efcd2..551c1fce554 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -419,6 +419,11 @@ unsigned SymbolGroupValue::isPointerType(const std::string &t) return 0; } +bool SymbolGroupValue::isArrayType(const std::string &t) +{ + return endsWith(t, ']'); +} + // Return number of characters to strip for pointer type bool SymbolGroupValue::isVTableType(const std::string &t) { diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.h b/src/libs/qtcreatorcdbext/symbolgroupvalue.h index b3a98afe7a3..27a12389110 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.h +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.h @@ -113,6 +113,7 @@ public: static std::string moduleOfType(const std::string &type); // pointer type, return number of characters to strip static unsigned isPointerType(const std::string &); + static bool isArrayType(const std::string &); static bool isVTableType(const std::string &t); // add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **' static std::string pointerType(const std::string &type);