forked from qt-creator/qt-creator
Cdbext: Allow to watch members.
Change-Id: I185d188c8847d90a75694a680bc20488f3d0a9e6 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -756,23 +756,56 @@ std::string WatchesSymbolGroup::fixWatchExpressionI(CIDebugSymbols *s, const std
|
|||||||
// Check if it matches the form
|
// Check if it matches the form
|
||||||
std::string::size_type typeStartPos;
|
std::string::size_type typeStartPos;
|
||||||
std::string::size_type typeEndPos;
|
std::string::size_type typeEndPos;
|
||||||
if (!parseWatchExpression(expression, &typeStartPos, &typeEndPos))
|
if (parseWatchExpression(expression, &typeStartPos, &typeEndPos)) {
|
||||||
return expression;
|
std::string type = expression.substr(typeStartPos, typeEndPos - typeStartPos);
|
||||||
std::string type = expression.substr(typeStartPos, typeEndPos - typeStartPos);
|
trimFront(type);
|
||||||
trimFront(type);
|
trimBack(type);
|
||||||
trimBack(type);
|
// Do not qualify POD types
|
||||||
// Do not qualify POD types
|
const KnownType kt = knownType(type, 0);
|
||||||
const KnownType kt = knownType(type, 0);
|
if (kt & KT_POD_Type)
|
||||||
if (kt & KT_POD_Type)
|
return expression;
|
||||||
return expression;
|
SymbolGroupValueContext ctx;
|
||||||
SymbolGroupValueContext ctx;
|
ctx.symbols = s;
|
||||||
ctx.symbols = s;
|
const std::string resolved = SymbolGroupValue::resolveType(type, ctx);
|
||||||
const std::string resolved = SymbolGroupValue::resolveType(type, ctx);
|
if (resolved.empty() || resolved == type)
|
||||||
if (resolved.empty() || resolved == type)
|
return expression;
|
||||||
return expression;
|
std::string fixed = expression;
|
||||||
std::string fixed = expression;
|
fixed.replace(typeStartPos, typeEndPos - typeStartPos, resolved);
|
||||||
fixed.replace(typeStartPos, typeEndPos - typeStartPos, resolved);
|
return fixed;
|
||||||
return fixed;
|
} else {
|
||||||
|
// unify the access operator
|
||||||
|
std::string fixed;
|
||||||
|
const std::string::const_iterator end = expression.end();
|
||||||
|
for (std::string::const_iterator pos = expression.begin(); pos != end; ++pos) {
|
||||||
|
switch (*pos) {
|
||||||
|
case '*':
|
||||||
|
case '&':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
++pos;
|
||||||
|
if (pos == end) {
|
||||||
|
fixed.push_back('-');
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
if (*pos == '>') {
|
||||||
|
fixed.push_back('.');
|
||||||
|
} else {
|
||||||
|
fixed.push_back('-');
|
||||||
|
fixed.push_back(*pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
fixed.push_back('.');
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
fixed.push_back(*pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper with debug output.
|
// Wrapper with debug output.
|
||||||
|
|||||||
@@ -1412,36 +1412,78 @@ SymbolGroupNode *SymbolGroupNode::addSymbolByName(const std::string &module,
|
|||||||
std::string *errorMessage)
|
std::string *errorMessage)
|
||||||
{
|
{
|
||||||
ULONG index = DEBUG_ANY_ID; // Append
|
ULONG index = DEBUG_ANY_ID; // Append
|
||||||
HRESULT hr = m_symbolGroup->debugSymbolGroup()->AddSymbol(name.c_str(), &index);
|
|
||||||
|
char buf[BufSize];
|
||||||
|
CIDebugSymbolGroup *symbolGroup = m_symbolGroup->debugSymbolGroup();
|
||||||
|
SymbolParameterVector indexParameters(1, DEBUG_SYMBOL_PARAMETERS());
|
||||||
|
|
||||||
|
static const char separator = '.';
|
||||||
|
std::string::size_type partStart = 0;
|
||||||
|
std::string::size_type partEnd = name.find(separator);
|
||||||
|
std::string namePart = name.substr(0, partEnd);
|
||||||
|
|
||||||
|
HRESULT hr = symbolGroup->AddSymbol(namePart.c_str(), &index);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = msgCannotAddSymbol(name, msgDebugEngineComFailed("AddSymbol", hr));
|
*errorMessage = msgCannotAddSymbol(namePart, msgDebugEngineComFailed("AddSymbol", hr));
|
||||||
ExtensionContext::instance().report('X', 0, 0, "Error", "%s", errorMessage->c_str());
|
ExtensionContext::instance().report('X', 0, 0, "Error", "%s", errorMessage->c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (index == DEBUG_ANY_ID) { // Occasionally happens for unknown or 'complicated' types
|
|
||||||
*errorMessage = msgCannotAddSymbol(name, "DEBUG_ANY_ID was returned as symbol index by AddSymbol.");
|
do {
|
||||||
ExtensionContext::instance().report('X', 0, 0, "Error", "%s", errorMessage->c_str());
|
if (index == DEBUG_ANY_ID) { // Occasionally happens for unknown or 'complicated' types
|
||||||
return 0;
|
*errorMessage = msgCannotAddSymbol(namePart, "DEBUG_ANY_ID was returned as symbol index by AddSymbol.");
|
||||||
}
|
ExtensionContext::instance().report('X', 0, 0, "Error", "%s", errorMessage->c_str());
|
||||||
SymbolParameterVector parameters(1, DEBUG_SYMBOL_PARAMETERS());
|
return 0;
|
||||||
hr = m_symbolGroup->debugSymbolGroup()->GetSymbolParameters(index, 1, &(*parameters.begin()));
|
}
|
||||||
if (FAILED(hr)) { // Should never fail
|
hr = symbolGroup->GetSymbolParameters(index, 1, &(*indexParameters.begin()));
|
||||||
std::ostringstream str;
|
if (FAILED(hr)) { // Should never fail
|
||||||
str << "Cannot retrieve 1 symbol parameter entry at " << index << ": "
|
std::ostringstream str;
|
||||||
<< msgDebugEngineComFailed("GetSymbolParameters", hr);
|
str << "Cannot retrieve 1 symbol parameter entry at " << index << ": "
|
||||||
*errorMessage = msgCannotAddSymbol(name, str.str());
|
<< msgDebugEngineComFailed("GetSymbolParameters", hr);
|
||||||
return 0;
|
*errorMessage = msgCannotAddSymbol(namePart, str.str());
|
||||||
}
|
return 0;
|
||||||
// Paranoia: Check for cuckoo's eggs (which should not happen)
|
}
|
||||||
if (parameters.front().ParentSymbol != m_index) {
|
|
||||||
*errorMessage = msgCannotAddSymbol(name, "Parent id mismatch");
|
if (partEnd == std::string::npos)
|
||||||
return 0;
|
break;
|
||||||
}
|
partStart = partEnd + 1;
|
||||||
|
partEnd = name.find(separator, partStart);
|
||||||
|
namePart = name.substr(partStart, partEnd == std::string::npos ? partEnd
|
||||||
|
: partEnd - partStart);
|
||||||
|
|
||||||
|
hr = symbolGroup->ExpandSymbol(index, TRUE);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
std::ostringstream str;
|
||||||
|
str << "Cannot expand " << namePart.c_str() << ": "
|
||||||
|
<< msgDebugEngineComFailed("ExpandSymbol", hr);
|
||||||
|
*errorMessage = msgCannotAddSymbol(name, str.str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ULONG childCount = indexParameters.at(0).SubElements;
|
||||||
|
SymbolParameterVector childParameters(childCount + 1, DEBUG_SYMBOL_PARAMETERS());
|
||||||
|
SymbolGroup::getSymbolParameters(symbolGroup, index,
|
||||||
|
childCount + 1, &childParameters, errorMessage);
|
||||||
|
|
||||||
|
const VectorIndexType size = childParameters.size();
|
||||||
|
ULONG newIndex = DEBUG_ANY_ID;
|
||||||
|
for (VectorIndexType pos = 1; pos < size ; ++pos) {
|
||||||
|
if (childParameters.at(pos).ParentSymbol != index)
|
||||||
|
continue;
|
||||||
|
if (FAILED(symbolGroup->GetSymbolName(ULONG(index + pos), buf, BufSize, NULL)))
|
||||||
|
buf[0] = '\0';
|
||||||
|
if (!namePart.compare(buf)) {
|
||||||
|
newIndex = index + (ULONG)pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = newIndex;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
SymbolGroupNode *node = new SymbolGroupNode(m_symbolGroup, index,
|
SymbolGroupNode *node = new SymbolGroupNode(m_symbolGroup, index,
|
||||||
module,
|
module,
|
||||||
displayName.empty() ? name : displayName,
|
displayName.empty() ? name : displayName,
|
||||||
iname.empty() ? name : iname);
|
iname.empty() ? name : iname);
|
||||||
node->parseParameters(0, 0, parameters);
|
node->parseParameters(0, 0, indexParameters);
|
||||||
node->addFlags(AdditionalSymbol);
|
node->addFlags(AdditionalSymbol);
|
||||||
addChild(node);
|
addChild(node);
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
Reference in New Issue
Block a user