forked from qt-creator/qt-creator
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:
@@ -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 << '"';
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user