CDB: Improve watch expressions.

- Fix watch expressions for array to at least point to the
  initial element.
- Return the name (which is the initial expression for the watch
  symbol group) as last resort if the evaluation fails to avoid
  obtaining "(*) 0" as expression.

Task-number: QTCREATORBUG-7408
Change-Id: Ifdf5ba59f6e18527d98b869f6a273aed283bd7da
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
Friedemann Kleint
2012-05-29 14:31:19 +02:00
parent 8bf3d48c84
commit 7e53c4a738
3 changed files with 25 additions and 10 deletions

View File

@@ -1029,19 +1029,26 @@ int SymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullInam
// Return a watch expression basically as "*(type *)(address)" // Return a watch expression basically as "*(type *)(address)"
static inline std::string watchExpression(ULONG64 address, static inline std::string watchExpression(ULONG64 address,
const std::string &type, const std::string &typeIn,
int /* kType */, int /* kType */,
const std::string &module) const std::string &module)
{ {
std::ostringstream str; std::string type = SymbolGroupValue::stripClassPrefixes(typeIn);
str << "*("; // Try to make watch expressions faster by at least qualifying
// Try to make watch expressions faster by at least qualifying templates with // templates with the local module. We cannot do expensive type
// the local module. We cannot do expensive type lookup here. // lookup here.
// We could insert a placeholder here for non-POD types indicating // We could insert a placeholder here for non-POD types indicating
// that a type lookup should be done when inserting watches? // that a type lookup should be done when inserting watches?
if (!module.empty() && type.find('>') != std::string::npos) if (!module.empty() && type.find('>') != std::string::npos) {
str << module << '!'; type.insert(0, 1, '!');
str << SymbolGroupValue::pointerType(SymbolGroupValue::stripClassPrefixes(type)) << ')' << std::hex << std::showbase << address; 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(); return str.str();
} }
@@ -1053,8 +1060,10 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
{ {
const std::string t = type(); const std::string t = type();
const ULONG64 addr = address(); const ULONG64 addr = address();
SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, // Use name as watchExpression in case evaluation failed (watch group item
watchExpression(addr, t, m_dumperType, m_module)); // 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) if (addr)
str << ",addr=\"" << std::hex << std::showbase << addr << std::noshowbase << std::dec << '"'; str << ",addr=\"" << std::hex << std::showbase << addr << std::noshowbase << std::dec << '"';

View File

@@ -419,6 +419,11 @@ unsigned SymbolGroupValue::isPointerType(const std::string &t)
return 0; return 0;
} }
bool SymbolGroupValue::isArrayType(const std::string &t)
{
return endsWith(t, ']');
}
// Return number of characters to strip for pointer type // Return number of characters to strip for pointer type
bool SymbolGroupValue::isVTableType(const std::string &t) bool SymbolGroupValue::isVTableType(const std::string &t)
{ {

View File

@@ -113,6 +113,7 @@ public:
static std::string moduleOfType(const std::string &type); static std::string moduleOfType(const std::string &type);
// pointer type, return number of characters to strip // pointer type, return number of characters to strip
static unsigned isPointerType(const std::string &); static unsigned isPointerType(const std::string &);
static bool isArrayType(const std::string &);
static bool isVTableType(const std::string &t); static bool isVTableType(const std::string &t);
// add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **' // add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **'
static std::string pointerType(const std::string &type); static std::string pointerType(const std::string &type);