Commit 466ea484 authored by Leandro Melo's avatar Leandro Melo

C++: Improve file accuracy when finding symbols

This patch introduces a priority-based mechanism when searching for certains
symbols in the snapshot. The priority corresponds to how similar the file path
from the "reference" symbol is to the file path from the "candidate" symbol.
This solves a variety of issues when matching "equivalent" symbols but that
are in another file/project, such as when following a function declaration,
a forward class declaration, or adding a definition through a quickfix.

There's now a symbol finder which will compute the "best" search order and cache
the most recent results. A consequence is that following symbols in some cases
is slower, but not apparently significatly.

Note: The "find" functions were moved from the Snapshot to the new SymbolFinder
class.

Task-number: QTCREATORBUG-6697
Task-number: QTCREATORBUG-6792

Change-Id: Ia518f014275fec1f4d0cb3224bd4e06a9df6d557
Reviewed-by: default avatarRoberto Raggi <roberto.raggi@nokia.com>
parent 271ec63a
...@@ -717,239 +717,3 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const ...@@ -717,239 +717,3 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const
} }
} }
namespace {
class FindMatchingDefinition: public SymbolVisitor
{
Symbol *_declaration;
const OperatorNameId *_oper;
QList<Function *> _result;
public:
FindMatchingDefinition(Symbol *declaration)
: _declaration(declaration)
, _oper(0)
{
if (_declaration->name())
_oper = _declaration->name()->asOperatorNameId();
}
QList<Function *> result() const { return _result; }
using SymbolVisitor::visit;
virtual bool visit(Function *fun)
{
if (_oper) {
if (const Name *name = fun->unqualifiedName()) {
if (_oper->isEqualTo(name))
_result.append(fun);
}
} else if (const Identifier *id = _declaration->identifier()) {
if (id->isEqualTo(fun->identifier()))
_result.append(fun);
}
return false;
}
virtual bool visit(Block *)
{
return false;
}
};
} // end of anonymous namespace
// strict means the returned symbol has to match exactly,
// including argument count and argument types
Symbol *Snapshot::findMatchingDefinition(Symbol *declaration, bool strict) const
{
if (!declaration)
return 0;
Document::Ptr thisDocument = document(QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()));
if (! thisDocument) {
qWarning() << "undefined document:" << declaration->fileName();
return 0;
}
Function *declarationTy = declaration->type()->asFunctionType();
if (! declarationTy) {
qWarning() << "not a function:" << declaration->fileName() << declaration->line() << declaration->column();
return 0;
}
foreach (Document::Ptr doc, *this) {
const Identifier *id = declaration->identifier();
if (id && ! doc->control()->findIdentifier(id->chars(),
id->size()))
continue;
if (!id) {
if (!declaration->name())
continue;
const OperatorNameId *oper = declaration->name()->asOperatorNameId();
if (!oper)
continue;
if (!doc->control()->findOperatorNameId(oper->kind()))
continue;
}
FindMatchingDefinition candidates(declaration);
candidates.accept(doc->globalNamespace());
const QList<Function *> result = candidates.result();
if (! result.isEmpty()) {
LookupContext context(doc, *this);
QList<Function *> viableFunctions;
ClassOrNamespace *enclosingType = context.lookupType(declaration);
if (! enclosingType)
continue; // nothing to do
foreach (Function *fun, result) {
const QList<LookupItem> declarations = context.lookup(fun->name(), fun->enclosingScope());
if (declarations.isEmpty())
continue;
const LookupItem best = declarations.first();
if (enclosingType == context.lookupType(best.declaration()))
viableFunctions.append(fun);
}
if (viableFunctions.isEmpty())
continue;
else if (! strict && viableFunctions.length() == 1)
return viableFunctions.first();
Function *best = 0;
foreach (Function *fun, viableFunctions) {
if (! (fun->unqualifiedName() && fun->unqualifiedName()->isEqualTo(declaration->unqualifiedName())))
continue;
else if (fun->argumentCount() == declarationTy->argumentCount()) {
if (! strict && ! best)
best = fun;
unsigned argc = 0;
for (; argc < declarationTy->argumentCount(); ++argc) {
Symbol *arg = fun->argumentAt(argc);
Symbol *otherArg = declarationTy->argumentAt(argc);
if (! arg->type().isEqualTo(otherArg->type()))
break;
}
if (argc == declarationTy->argumentCount())
best = fun;
}
}
if (strict && ! best)
continue;
if (! best)
best = viableFunctions.first();
return best;
}
}
return 0;
}
Class *Snapshot::findMatchingClassDeclaration(Symbol *declaration) const
{
if (! declaration->identifier())
return 0;
foreach (Document::Ptr doc, *this) {
if (! doc->control()->findIdentifier(declaration->identifier()->chars(),
declaration->identifier()->size()))
continue;
LookupContext context(doc, *this);
ClassOrNamespace *type = context.lookupType(declaration);
if (!type)
continue;
foreach (Symbol *s, type->symbols()) {
if (Class *c = s->asClass())
return c;
}
}
return 0;
}
void CPlusPlus::findMatchingDeclaration(const LookupContext &context,
Function *functionType,
QList<Declaration *> *typeMatch,
QList<Declaration *> *argumentCountMatch,
QList<Declaration *> *nameMatch)
{
Scope *enclosingScope = functionType->enclosingScope();
while (! (enclosingScope->isNamespace() || enclosingScope->isClass()))
enclosingScope = enclosingScope->enclosingScope();
Q_ASSERT(enclosingScope != 0);
const Name *functionName = functionType->name();
if (! functionName)
return; // anonymous function names are not valid c++
ClassOrNamespace *binding = 0;
const QualifiedNameId *qName = functionName->asQualifiedNameId();
if (qName) {
if (qName->base())
binding = context.lookupType(qName->base(), enclosingScope);
else
binding = context.globalNamespace();
functionName = qName->name();
}
if (!binding) { // declaration for a global function
binding = context.lookupType(enclosingScope);
if (!binding)
return;
}
const Identifier *funcId = functionName->identifier();
if (!funcId) // E.g. operator, which we might be able to handle in the future...
return;
foreach (Symbol *s, binding->symbols()) {
Scope *scope = s->asScope();
if (!scope)
continue;
for (Symbol *s = scope->find(funcId); s; s = s->next()) {
if (! s->name())
continue;
else if (! funcId->isEqualTo(s->identifier()))
continue;
else if (! s->type()->isFunctionType())
continue;
else if (Declaration *decl = s->asDeclaration()) {
if (Function *declFunTy = decl->type()->asFunctionType()) {
if (functionType->isEqualTo(declFunTy))
typeMatch->prepend(decl);
else if (functionType->argumentCount() == declFunTy->argumentCount())
argumentCountMatch->prepend(decl);
else
nameMatch->append(decl);
}
}
}
}
}
QList<Declaration *> CPlusPlus::findMatchingDeclaration(const LookupContext &context, Function *functionType)
{
QList<Declaration *> result;
QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
findMatchingDeclaration(context, functionType, &typeMatch, &argumentCountMatch, &nameMatch);
result.append(typeMatch);
result.append(argumentCountMatch);
result.append(nameMatch);
return result;
}
...@@ -381,9 +381,6 @@ public: ...@@ -381,9 +381,6 @@ public:
Document::Ptr documentFromSource(const QByteArray &preprocessedCode, Document::Ptr documentFromSource(const QByteArray &preprocessedCode,
const QString &fileName) const; const QString &fileName) const;
Symbol *findMatchingDefinition(Symbol *symbol, bool strict = false) const;
Class *findMatchingClassDeclaration(Symbol *symbol) const;
private: private:
void simplified_helper(Document::Ptr doc, Snapshot *snapshot) const; void simplified_helper(Document::Ptr doc, Snapshot *snapshot) const;
...@@ -391,15 +388,6 @@ private: ...@@ -391,15 +388,6 @@ private:
_Base _documents; _Base _documents;
}; };
void CPLUSPLUS_EXPORT findMatchingDeclaration(
const LookupContext &context,
Function *functionType,
QList<Declaration *> *typeMatch,
QList<Declaration *> *argumentCountMatch,
QList<Declaration *> *nameMatch);
QList<Declaration *> CPLUSPLUS_EXPORT findMatchingDeclaration(
const LookupContext &context, Function *functionType);
} // namespace CPlusPlus } // namespace CPlusPlus
#endif // CPLUSPLUS_CPPDOCUMENT_H #endif // CPLUSPLUS_CPPDOCUMENT_H
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <cpptools/doxygengenerator.h> #include <cpptools/doxygengenerator.h>
#include <cpptools/cpptoolssettings.h> #include <cpptools/cpptoolssettings.h>
#include <cpptools/symbolfinder.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
...@@ -419,6 +420,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent) ...@@ -419,6 +420,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
, m_firstRenameChange(false) , m_firstRenameChange(false)
, m_objcEnabled(false) , m_objcEnabled(false)
, m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings()) , m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings())
, m_symbolFinder(new CppTools::SymbolFinder(QString()))
{ {
m_initialized = false; m_initialized = false;
qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo"); qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo");
...@@ -862,7 +864,9 @@ void CPPEditorWidget::onContentsChanged(int position, int charsRemoved, int char ...@@ -862,7 +864,9 @@ void CPPEditorWidget::onContentsChanged(int position, int charsRemoved, int char
} }
void CPPEditorWidget::updateFileName() void CPPEditorWidget::updateFileName()
{ } {
m_symbolFinder.reset(new CppTools::SymbolFinder(file()->fileName()));
}
void CPPEditorWidget::jumpToOutlineElement(int) void CPPEditorWidget::jumpToOutlineElement(int)
{ {
...@@ -1076,7 +1080,7 @@ void CPPEditorWidget::switchDeclarationDefinition() ...@@ -1076,7 +1080,7 @@ void CPPEditorWidget::switchDeclarationDefinition()
openCppEditorAt(linkToSymbol(best.first())); openCppEditorAt(linkToSymbol(best.first()));
} else if (lastVisibleSymbol && lastVisibleSymbol->isDeclaration() && lastVisibleSymbol->type()->isFunctionType()) { } else if (lastVisibleSymbol && lastVisibleSymbol->isDeclaration() && lastVisibleSymbol->type()->isFunctionType()) {
if (Symbol *def = snapshot.findMatchingDefinition(lastVisibleSymbol)) if (Symbol *def = m_symbolFinder->findMatchingDefinition(lastVisibleSymbol, snapshot))
openCppEditorAt(linkToSymbol(def)); openCppEditorAt(linkToSymbol(def));
} }
} }
...@@ -1171,12 +1175,13 @@ CPPEditorWidget::Link CPPEditorWidget::attemptFuncDeclDef(const QTextCursor &cur ...@@ -1171,12 +1175,13 @@ CPPEditorWidget::Link CPPEditorWidget::attemptFuncDeclDef(const QTextCursor &cur
Symbol *target = 0; Symbol *target = 0;
if (FunctionDefinitionAST *funDef = declParent->asFunctionDefinition()) { if (FunctionDefinitionAST *funDef = declParent->asFunctionDefinition()) {
QList<Declaration *> candidates = findMatchingDeclaration(LookupContext(doc, snapshot), QList<Declaration *> candidates =
funDef->symbol); m_symbolFinder->findMatchingDeclaration(LookupContext(doc, snapshot),
funDef->symbol);
if (!candidates.isEmpty()) // TODO: improve disambiguation if (!candidates.isEmpty()) // TODO: improve disambiguation
target = candidates.first(); target = candidates.first();
} else if (declParent->asSimpleDeclaration()) { } else if (declParent->asSimpleDeclaration()) {
target = snapshot.findMatchingDefinition(funcDecl->symbol); target = m_symbolFinder->findMatchingDefinition(funcDecl->symbol, snapshot);
} }
if (target) { if (target) {
...@@ -1426,9 +1431,8 @@ CPPEditorWidget::Link CPPEditorWidget::findLinkAt(const QTextCursor &cursor, ...@@ -1426,9 +1431,8 @@ CPPEditorWidget::Link CPPEditorWidget::findLinkAt(const QTextCursor &cursor,
if (def == lastVisibleSymbol) if (def == lastVisibleSymbol)
def = 0; // jump to declaration then. def = 0; // jump to declaration then.
if (symbol->isForwardClassDeclaration()) { if (symbol->isForwardClassDeclaration())
def = snapshot.findMatchingClassDeclaration(symbol); def = m_symbolFinder->findMatchingClassDeclaration(symbol, snapshot);
}
} }
link = linkToSymbol(def ? def : symbol); link = linkToSymbol(def ? def : symbol);
...@@ -1464,7 +1468,7 @@ Symbol *CPPEditorWidget::findDefinition(Symbol *symbol, const Snapshot &snapshot ...@@ -1464,7 +1468,7 @@ Symbol *CPPEditorWidget::findDefinition(Symbol *symbol, const Snapshot &snapshot
else if (! symbol->type()->isFunctionType()) else if (! symbol->type()->isFunctionType())
return 0; // not a function declaration return 0; // not a function declaration
return snapshot.findMatchingDefinition(symbol); return m_symbolFinder->findMatchingDefinition(symbol, snapshot);
} }
unsigned CPPEditorWidget::editorRevision() const unsigned CPPEditorWidget::editorRevision() const
...@@ -2254,6 +2258,11 @@ void CPPEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch) ...@@ -2254,6 +2258,11 @@ void CPPEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch)
updateFunctionDeclDefLink(); updateFunctionDeclDefLink();
} }
CppTools::SymbolFinder *CPPEditorWidget::symbolFinder() const
{
return m_symbolFinder.data();
}
void CPPEditorWidget::abortDeclDefLink() void CPPEditorWidget::abortDeclDefLink()
{ {
if (!m_declDefLink) if (!m_declDefLink)
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <QtCore/QFutureWatcher> #include <QtCore/QFutureWatcher>
#include <QtCore/QModelIndex> #include <QtCore/QModelIndex>
#include <QtCore/QVector> #include <QtCore/QVector>
#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QComboBox; class QComboBox;
...@@ -65,6 +66,7 @@ class CppModelManagerInterface; ...@@ -65,6 +66,7 @@ class CppModelManagerInterface;
namespace CppTools { namespace CppTools {
class CppCodeStyleSettings; class CppCodeStyleSettings;
class CppRefactoringFile; class CppRefactoringFile;
class SymbolFinder;
} }
namespace TextEditor { namespace TextEditor {
...@@ -200,6 +202,8 @@ public: ...@@ -200,6 +202,8 @@ public:
QSharedPointer<FunctionDeclDefLink> declDefLink() const; QSharedPointer<FunctionDeclDefLink> declDefLink() const;
void applyDeclDefLinkChanges(bool jumpToMatch); void applyDeclDefLinkChanges(bool jumpToMatch);
CppTools::SymbolFinder *symbolFinder() const;
Q_SIGNALS: Q_SIGNALS:
void outlineModelIndexChanged(const QModelIndex &index); void outlineModelIndexChanged(const QModelIndex &index);
...@@ -333,6 +337,7 @@ private: ...@@ -333,6 +337,7 @@ private:
QSharedPointer<FunctionDeclDefLink> m_declDefLink; QSharedPointer<FunctionDeclDefLink> m_declDefLink;
CppTools::CommentsSettings m_commentsSettings; CppTools::CommentsSettings m_commentsSettings;
QScopedPointer<CppTools::SymbolFinder> m_symbolFinder;
}; };
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <coreplugin/ifile.h> #include <coreplugin/ifile.h>
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <cpptools/symbolfinder.h>
#include <FullySpecifiedType.h> #include <FullySpecifiedType.h>
#include <Literals.h> #include <Literals.h>
...@@ -184,8 +185,11 @@ void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot, ...@@ -184,8 +185,11 @@ void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
&& (declaration->asTemplate()->declaration()->isClass() && (declaration->asTemplate()->declaration()->isClass()
|| declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) { || declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) {
if (declaration->isForwardClassDeclaration()) if (declaration->isForwardClassDeclaration())
if (Symbol *classDeclaration = snapshot.findMatchingClassDeclaration(declaration)) if (Symbol *classDeclaration =
m_editor->symbolFinder()->findMatchingClassDeclaration(
declaration, snapshot)) {
declaration = classDeclaration; declaration = classDeclaration;
}
CppClass *cppClass = new CppClass(declaration); CppClass *cppClass = new CppClass(declaration);
if (m_lookupBaseClasses) if (m_lookupBaseClasses)
cppClass->lookupBases(declaration, context); cppClass->lookupBases(declaration, context);
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <cplusplus/LookupContext.h> #include <cplusplus/LookupContext.h>
#include <cplusplus/Overview.h> #include <cplusplus/Overview.h>
#include <cpptools/cpprefactoringchanges.h> #include <cpptools/cpprefactoringchanges.h>
#include <cpptools/symbolfinder.h>
#include <texteditor/refactoroverlay.h> #include <texteditor/refactoroverlay.h>
#include <texteditor/tooltip/tooltip.h> #include <texteditor/tooltip/tooltip.h>
#include <texteditor/tooltip/tipcontents.h> #include <texteditor/tooltip/tipcontents.h>
...@@ -165,13 +166,16 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio ...@@ -165,13 +166,16 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio
Symbol *target = 0; Symbol *target = 0;
if (FunctionDefinitionAST *funcDef = link->sourceDeclaration->asFunctionDefinition()) { if (FunctionDefinitionAST *funcDef = link->sourceDeclaration->asFunctionDefinition()) {
QList<Declaration *> nameMatch, argumentCountMatch, typeMatch; QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
findMatchingDeclaration(LookupContext(link->sourceDocument, snapshot), CppTools::SymbolFinder finder(funcDef->symbol->fileName(), funcDef->symbol->fileNameLength());
funcDef->symbol, finder.findMatchingDeclaration(LookupContext(link->sourceDocument, snapshot),
&typeMatch, &argumentCountMatch, &nameMatch); funcDef->symbol,
&typeMatch, &argumentCountMatch, &nameMatch);
if (!typeMatch.isEmpty()) if (!typeMatch.isEmpty())
target = typeMatch.first(); target = typeMatch.first();
} else if (link->sourceDeclaration->asSimpleDeclaration()) { } else if (link->sourceDeclaration->asSimpleDeclaration()) {
target = snapshot.findMatchingDefinition(link->sourceFunctionDeclarator->symbol, true); CppTools::SymbolFinder finder(link->sourceFunctionDeclarator->symbol->fileName(),
link->sourceFunctionDeclarator->symbol->fileNameLength());
target = finder.findMatchingDefinition(link->sourceFunctionDeclarator->symbol, snapshot, true);
} }
if (!target) { if (!target) {
return noResult; return noResult;
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <cpptools/cppclassesfilter.h> #include <cpptools/cppclassesfilter.h>
#include <cpptools/searchsymbols.h> #include <cpptools/searchsymbols.h>
#include <cpptools/symbolfinder.h>
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
...@@ -1552,7 +1553,10 @@ private: ...@@ -1552,7 +1553,10 @@ private:
{ {
Q_ASSERT(fwdClass != 0); Q_ASSERT(fwdClass != 0);
if (Class *k = assistInterface()->snapshot().findMatchingClassDeclaration(fwdClass)) { CppTools::SymbolFinder symbolFinder(fwdClass->fileName(), fwdClass->fileNameLength());
if (Class *k =
symbolFinder.findMatchingClassDeclaration(fwdClass,
assistInterface()->snapshot())) {
const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength()); const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength());
// collect the fwd headers // collect the fwd headers
......
...@@ -37,7 +37,8 @@ HEADERS += completionsettingspage.h \ ...@@ -37,7 +37,8 @@ HEADERS += completionsettingspage.h \
cppcodestylepreferences.h \ cppcodestylepreferences.h \
cpptoolsreuse.h \ cpptoolsreuse.h \
doxygengenerator.h \ doxygengenerator.h \
commentssettings.h commentssettings.h \
symbolfinder.h
SOURCES += completionsettingspage.cpp \ SOURCES += completionsettingspage.cpp \
cppclassesfilter.cpp \ cppclassesfilter.cpp \
...@@ -66,7 +67,8 @@ SOURCES += completionsettingspage.cpp \ ...@@ -66,7 +67,8 @@ SOURCES += completionsettingspage.cpp \
cppcodestylepreferences.cpp \ cppcodestylepreferences.cpp \
cpptoolsreuse.cpp \ cpptoolsreuse.cpp \
doxygengenerator.cpp \ doxygengenerator.cpp \
commentssettings.cpp commentssettings.cpp \
symbolfinder.cpp
FORMS += completionsettingspage.ui \ FORMS += completionsettingspage.ui \
cppfilesettingspage.ui \ cppfilesettingspage.ui \
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "cpptoolsplugin.h" #include "cpptoolsplugin.h"
#include "cpprefactoringchanges.h" #include "cpprefactoringchanges.h"
#include "insertionpointlocator.h" #include "insertionpointlocator.h"
#include "symbolfinder.h"
#include <AST.h> #include <AST.h>
#include <ASTVisitor.h> #include <ASTVisitor.h>
...@@ -516,7 +517,10 @@ static InsertionLocation nextToSurroundingDefinitions(Declaration *declaration, ...@@ -516,7 +517,10 @@ static InsertionLocation nextToSurroundingDefinitions(Declaration *declaration,
} }
// find the declaration's definition // find the declaration's definition
Symbol *definition = changes.snapshot().findMatchingDefinition(surroundingFunctionDecl); CppTools::SymbolFinder symbolFinder(surroundingFunctionDecl->fileName(),
surroundingFunctionDecl->fileNameLength());
Symbol *definition = symbolFinder.findMatchingDefinition(surroundingFunctionDecl,
changes.snapshot());
if (!definition) if (!definition)
return noResult; return noResult;
...@@ -555,7 +559,10 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition( ...@@ -555,7 +559,10 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition(
if (!declaration) if (!declaration)
return result; return result;
if (Symbol *s = m_refactoringChanges.snapshot().findMatchingDefinition(declaration, true)) { CppTools::SymbolFinder symbolFinder(declaration->fileName(), declaration->fileNameLength());
if (Symbol *s = symbolFinder.findMatchingDefinition(declaration,
m_refactoringChanges.snapshot(),
true)) {
if (Function *f = s->asFunction()) { if (Function *f = s->asFunction()) {
if (f->isConst() == declaration->type().isConst() if (f->isConst() == declaration->type().isConst