From e1111d45707e99db3390941384d41a2fe936bcb2 Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Thu, 7 Jun 2018 14:23:07 +0200 Subject: [PATCH] Clang: Use built-in follow symbol for virtual methods ClangCodeModel currently does not provide a list of overrides. Therefore it makes sense to use ClangCodeModel result for virtual method only if built-in code model does not find anything. Task-number: QTCREATORBUG-20584 Change-Id: I5b4fac7974f990e741d3438ab61827670a8ce8d8 Reviewed-by: Nikolai Kosjar --- src/libs/clangsupport/followsymbolmessage.cpp | 2 +- src/libs/clangsupport/followsymbolmessage.h | 12 ++++++------ src/plugins/clangcodemodel/clangbackendreceiver.cpp | 2 +- src/plugins/clangcodemodel/clangfollowsymbol.cpp | 4 ++-- src/plugins/cpptools/cppsymbolinfo.h | 2 +- src/tools/clangbackend/source/clangfollowsymbol.cpp | 11 ++++++----- tests/unit/unittest/gtest-creator-printing.cpp | 2 +- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/libs/clangsupport/followsymbolmessage.cpp b/src/libs/clangsupport/followsymbolmessage.cpp index 22e77ee6d41..df2d1f5e6f6 100644 --- a/src/libs/clangsupport/followsymbolmessage.cpp +++ b/src/libs/clangsupport/followsymbolmessage.cpp @@ -33,7 +33,7 @@ QDebug operator<<(QDebug debug, const FollowSymbolResult &result) { debug.nospace() << "FollowSymbolResult(" << result.range - << ", " << result.isPureDeclarationForUsage; + << ", " << result.isResultOnlyForFallBack; debug.nospace() << ")"; diff --git a/src/libs/clangsupport/followsymbolmessage.h b/src/libs/clangsupport/followsymbolmessage.h index ec113825aeb..b63820a4ad9 100644 --- a/src/libs/clangsupport/followsymbolmessage.h +++ b/src/libs/clangsupport/followsymbolmessage.h @@ -40,15 +40,15 @@ public: FollowSymbolResult(SourceRangeContainer range) : range(std::move(range)) {} - FollowSymbolResult(SourceRangeContainer range, bool isPureDeclarationForUsage) + FollowSymbolResult(SourceRangeContainer range, bool isResultOnlyForFallBack) : range(std::move(range)) - , isPureDeclarationForUsage(isPureDeclarationForUsage) + , isResultOnlyForFallBack(isResultOnlyForFallBack) {} friend QDataStream &operator<<(QDataStream &out, const FollowSymbolResult &container) { out << container.range; - out << container.isPureDeclarationForUsage; + out << container.isResultOnlyForFallBack; return out; } @@ -56,7 +56,7 @@ public: friend QDataStream &operator>>(QDataStream &in, FollowSymbolResult &container) { in >> container.range; - in >> container.isPureDeclarationForUsage; + in >> container.isResultOnlyForFallBack; return in; } @@ -64,11 +64,11 @@ public: friend bool operator==(const FollowSymbolResult &first, const FollowSymbolResult &second) { return first.range == second.range - && first.isPureDeclarationForUsage == second.isPureDeclarationForUsage; + && first.isResultOnlyForFallBack == second.isResultOnlyForFallBack; } SourceRangeContainer range; - bool isPureDeclarationForUsage = false; + bool isResultOnlyForFallBack = false; }; class FollowSymbolMessage diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp index 2a2792b921d..d340a990d31 100644 --- a/src/plugins/clangcodemodel/clangbackendreceiver.cpp +++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp @@ -265,7 +265,7 @@ CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message) result.endColumn = static_cast(end.column); result.fileName = start.filePath; - result.isPureDeclarationForUsage = message.result.isPureDeclarationForUsage; + result.isResultOnlyForFallBack = message.result.isResultOnlyForFallBack; return result; } diff --git a/src/plugins/clangcodemodel/clangfollowsymbol.cpp b/src/plugins/clangcodemodel/clangfollowsymbol.cpp index e1f33bdf854..f503a777d2a 100644 --- a/src/plugins/clangcodemodel/clangfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangfollowsymbol.cpp @@ -145,7 +145,7 @@ static ::Utils::ProcessLinkCallback extendedCallback(::Utils::ProcessLinkCallbac { // If globalFollowSymbol finds nothing follow to the declaration. return [original_callback = std::move(callback), result](const ::Utils::Link &link) { - if (!link.hasValidTarget() && result.isPureDeclarationForUsage) { + if (link.linkTextStart < 0 && result.isResultOnlyForFallBack) { return original_callback(::Utils::Link(result.fileName, result.startLine, result.startColumn - 1)); } @@ -198,7 +198,7 @@ void ClangFollowSymbol::findLink(const CppTools::CursorInEditor &data, return callback(Utils::Link()); CppTools::SymbolInfo result = m_watcher->result(); // We did not fail but the result is empty - if (result.fileName.isEmpty() || result.isPureDeclarationForUsage) { + if (result.fileName.isEmpty() || result.isResultOnlyForFallBack) { const CppTools::RefactoringEngineInterface &refactoringEngine = *CppTools::CppModelManager::instance(); refactoringEngine.globalFollowSymbol(data, diff --git a/src/plugins/cpptools/cppsymbolinfo.h b/src/plugins/cpptools/cppsymbolinfo.h index 38edec11b3c..16e604a8299 100644 --- a/src/plugins/cpptools/cppsymbolinfo.h +++ b/src/plugins/cpptools/cppsymbolinfo.h @@ -39,7 +39,7 @@ public: int endLine = 0; int endColumn = 0; QString fileName; - bool isPureDeclarationForUsage = false; + bool isResultOnlyForFallBack = false; }; } // namespace CppTools diff --git a/src/tools/clangbackend/source/clangfollowsymbol.cpp b/src/tools/clangbackend/source/clangfollowsymbol.cpp index f557e1850b5..d41af5dc758 100644 --- a/src/tools/clangbackend/source/clangfollowsymbol.cpp +++ b/src/tools/clangbackend/source/clangfollowsymbol.cpp @@ -152,14 +152,15 @@ FollowSymbolResult FollowSymbol::followSymbol(CXTranslationUnit tu, if (!cursor.isDeclaration()) { // This is the symbol usage // We want to return definition - FollowSymbolResult result; cursor = cursor.referenced(); if (cursor.isNull()) return SourceRangeContainer(); - if (!cursor.isDefinition()) { - // We can't find definition in this TU - result.isPureDeclarationForUsage = true; - } + + FollowSymbolResult result; + // We can't find definition in this TU or it's a virtual method call + if (!cursor.isDefinition() || cursor.isVirtualMethod()) + result.isResultOnlyForFallBack = true; + result.range = extractMatchingTokenRange(cursor, tokenSpelling); return result; } diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index a6d6118bccc..a3e5a8982bb 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -241,7 +241,7 @@ std::ostream &operator<<(std::ostream &os, const FollowSymbolResult &result) { os << "(" << result.range - << ", " << result.isPureDeclarationForUsage + << ", " << result.isResultOnlyForFallBack << ")"; return os;