Cdbext: Allow to watch members.

Change-Id: I185d188c8847d90a75694a680bc20488f3d0a9e6
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
David Schulz
2015-03-16 11:09:41 +01:00
parent 60e84fbaf4
commit f11bc8c607
2 changed files with 114 additions and 39 deletions

View File

@@ -756,8 +756,7 @@ 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);
@@ -773,6 +772,40 @@ std::string WatchesSymbolGroup::fixWatchExpressionI(CIDebugSymbols *s, const std
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.

View File

@@ -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;
} }
do {
if (index == DEBUG_ANY_ID) { // Occasionally happens for unknown or 'complicated' types 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."); *errorMessage = msgCannotAddSymbol(namePart, "DEBUG_ANY_ID was returned as symbol index by AddSymbol.");
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;
} }
SymbolParameterVector parameters(1, DEBUG_SYMBOL_PARAMETERS()); hr = symbolGroup->GetSymbolParameters(index, 1, &(*indexParameters.begin()));
hr = m_symbolGroup->debugSymbolGroup()->GetSymbolParameters(index, 1, &(*parameters.begin()));
if (FAILED(hr)) { // Should never fail if (FAILED(hr)) { // Should never fail
std::ostringstream str; std::ostringstream str;
str << "Cannot retrieve 1 symbol parameter entry at " << index << ": " str << "Cannot retrieve 1 symbol parameter entry at " << index << ": "
<< msgDebugEngineComFailed("GetSymbolParameters", hr); << msgDebugEngineComFailed("GetSymbolParameters", hr);
*errorMessage = msgCannotAddSymbol(namePart, str.str());
return 0;
}
if (partEnd == std::string::npos)
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()); *errorMessage = msgCannotAddSymbol(name, str.str());
return 0; return 0;
} }
// Paranoia: Check for cuckoo's eggs (which should not happen) ULONG childCount = indexParameters.at(0).SubElements;
if (parameters.front().ParentSymbol != m_index) { SymbolParameterVector childParameters(childCount + 1, DEBUG_SYMBOL_PARAMETERS());
*errorMessage = msgCannotAddSymbol(name, "Parent id mismatch"); SymbolGroup::getSymbolParameters(symbolGroup, index,
return 0; 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;