Debugger: Simplify use of getUninitializedVariables()

Change-Id: I7962fe2d582fc3f2ad6a76fb600038f454b75dc0
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2018-05-25 15:37:39 +02:00
parent 94d41afade
commit 8416a14f3d
3 changed files with 22 additions and 49 deletions

View File

@@ -1168,10 +1168,9 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters)
cmd.arg("displaystringlimit", action(DisplayStringLimit)->value().toString()); cmd.arg("displaystringlimit", action(DisplayStringLimit)->value().toString());
if (boolSetting(UseCodeModel)) { if (boolSetting(UseCodeModel)) {
QStringList uninitializedVariables; QStringList variables = getUninitializedVariables(m_codeModelSnapshot,
getUninitializedVariables(m_codeModelSnapshot, frame.function, frame.file, frame.line);
frame.function, frame.file, frame.line, &uninitializedVariables); cmd.arg("uninitialized", variables);
cmd.arg("uninitialized", uninitializedVariables);
} }
cmd.callback = [this](const DebuggerResponse &response) { cmd.callback = [this](const DebuggerResponse &response) {
@@ -1239,13 +1238,12 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters)
// Uninitialized variables if desired. Quote as safeguard against shadowed // Uninitialized variables if desired. Quote as safeguard against shadowed
// variables in case of errors in uninitializedVariables(). // variables in case of errors in uninitializedVariables().
if (boolSetting(UseCodeModel)) { if (boolSetting(UseCodeModel)) {
QStringList uninitializedVariables; const QStringList variables = getUninitializedVariables(m_codeModelSnapshot,
getUninitializedVariables(m_codeModelSnapshot, frame.function, frame.file, frame.line);
frame.function, frame.file, frame.line, &uninitializedVariables); if (!variables.isEmpty()) {
if (!uninitializedVariables.isEmpty()) {
str << blankSeparator << "-u \""; str << blankSeparator << "-u \"";
int i = 0; int i = 0;
foreach (const QString &u, uninitializedVariables) { for (const QString &u : variables) {
if (i++) if (i++)
str << ','; str << ',';
str << localsPrefixC << u; str << localsPrefixC << u;

View File

@@ -182,27 +182,24 @@ static void blockRecursion(const Overview &overview,
blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1); blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1);
} }
// Inline helper with integer error return codes. QStringList getUninitializedVariables(const Snapshot &snapshot,
static inline const QString &functionName,
int getUninitializedVariablesI(const Snapshot &snapshot, const QString &file,
const QString &functionName, int line)
const QString &file,
int line,
QStringList *uninitializedVariables)
{ {
uninitializedVariables->clear(); QStringList result;
// Find document // Find document
if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1) if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1)
return 1; return result;
const Snapshot::const_iterator docIt = snapshot.find(file); const Snapshot::const_iterator docIt = snapshot.find(file);
if (docIt == snapshot.end()) if (docIt == snapshot.end())
return 2; return result;
const Document::Ptr doc = docIt.value(); const Document::Ptr doc = docIt.value();
// Look at symbol at line and find its function. Either it is the // Look at symbol at line and find its function. Either it is the
// function itself or some expression/variable. // function itself or some expression/variable.
const Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0); const Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0);
if (!symbolAtLine) if (!symbolAtLine)
return 4; return result;
// First figure out the function to do a safety name check // First figure out the function to do a safety name check
// and the innermost scope at cursor position // and the innermost scope at cursor position
const Function *function = nullptr; const Function *function = nullptr;
@@ -221,46 +218,25 @@ int getUninitializedVariablesI(const Snapshot &snapshot,
} }
} }
if (!function || !innerMostScope) if (!function || !innerMostScope)
return 7; return result;
// Compare function names with a bit off fuzz, // Compare function names with a bit off fuzz,
// skipping modules from a CDB symbol "lib!foo" or namespaces // skipping modules from a CDB symbol "lib!foo" or namespaces
// that the code model does not show at this point // that the code model does not show at this point
Overview overview; Overview overview;
const QString name = overview.prettyName(function->name()); const QString name = overview.prettyName(function->name());
if (!functionName.endsWith(name)) if (!functionName.endsWith(name))
return 11; return result;
if (functionName.size() > name.size()) { if (functionName.size() > name.size()) {
const char previousChar = functionName.at(functionName.size() - name.size() - 1).toLatin1(); const char previousChar = functionName.at(functionName.size() - name.size() - 1).toLatin1();
if (previousChar != ':' && previousChar != '!' ) if (previousChar != ':' && previousChar != '!' )
return 11; return result;
} }
// Starting from the innermost block scope, collect declarations. // Starting from the innermost block scope, collect declarations.
SeenHash seenHash; SeenHash seenHash;
blockRecursion(overview, innerMostScope, line, uninitializedVariables, &seenHash); blockRecursion(overview, innerMostScope, line, &result, &seenHash);
return 0; return result;
} }
bool getUninitializedVariables(const Snapshot &snapshot,
const QString &function,
const QString &file,
int line,
QStringList *uninitializedVariables)
{
const int rc = getUninitializedVariablesI(snapshot, function, file, line, uninitializedVariables);
if (debug) {
QString msg;
QTextStream str(&msg);
str << "getUninitializedVariables() " << function << ' ' << file << ':' << line
<< " returns (int) " << rc << " '"
<< uninitializedVariables->join(QLatin1Char(',')) << '\'';
if (rc)
str << " of " << snapshot.size() << " documents";
qDebug() << msg;
}
return rc == 0;
}
QString cppFunctionAt(const QString &fileName, int line, int column) QString cppFunctionAt(const QString &fileName, int line, int column)
{ {
const Snapshot snapshot = CppModelManager::instance()->snapshot(); const Snapshot snapshot = CppModelManager::instance()->snapshot();

View File

@@ -49,9 +49,8 @@ QString cppFunctionAt(const QString &fileName, int line, int column = 0);
// Get variables that are not initialized at a certain line // Get variables that are not initialized at a certain line
// of a function from the code model. Shadowed variables will // of a function from the code model. Shadowed variables will
// be reported using the debugger naming conventions '<shadowed n>' // be reported using the debugger naming conventions '<shadowed n>'
bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot, QStringList getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
const QString &function, const QString &file, int line, const QString &function, const QString &file, int line);
QStringList *uninitializedVariables);
ContextData getLocationContext(TextEditor::TextDocument *document, int lineNumber); ContextData getLocationContext(TextEditor::TextDocument *document, int lineNumber);