From c41847ce5da4f40754f7ed90c3ad3d7db018d94a Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 20 Jul 2020 13:06:17 +0200 Subject: [PATCH] CppEditor: Find implementations for pure virtual declaration Clearly, if a user presses F2 on the declaration of an (unimplemented) pure virtual function, they want to go to an implementation in a derived class. Fixes: QTCREATORBUG-10160 Change-Id: Ie8c4ff0001ab2c98a2d0e2ebc8d954cc928578c0 Reviewed-by: Christian Stenger --- .../followsymbol_switchmethoddecldef_test.cpp | 25 +++++++++++++++++++ .../cpptools/cppfollowsymbolundercursor.cpp | 13 ++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 1355b2d1781..17f2e364f9c 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -1413,6 +1413,31 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_data() << OverrideItem(QLatin1String("CD1::virt"), 11) << OverrideItem(QLatin1String("CD2::virt"), 14)); + /// Check: Cursor on unimplemented base declaration. + QTest::newRow("allOverrides from base declaration") << _( + "struct A { virtual void $@virt() = 0; };\n" + "\n" + "struct B : A { void virt(); };\n" + "void B::virt() {}\n" + "\n" + "struct C : B { void virt(); };\n" + "void C::virt() {}\n" + "\n" + "struct CD1 : C { void virt(); };\n" + "void CD1::virt() {}\n" + "\n" + "struct CD2 : C { void virt(); };\n" + "void CD2::virt() {}\n" + "\n" + "int f(A *o) { o->virt(); }\n" + "\n") + << (OverrideItemList() + << OverrideItem(QLatin1String("A::virt = 0"), 1) + << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("C::virt"), 7) + << OverrideItem(QLatin1String("CD1::virt"), 10) + << OverrideItem(QLatin1String("CD2::virt"), 13)); + /// Check: Static type is derived class pointer, only overrides of sub classes are presented. QTest::newRow("possibleOverrides1") << _( "struct A { virtual void virt() = 0; };\n" diff --git a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp index a21babf8520..f7307b59c15 100644 --- a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp @@ -111,8 +111,17 @@ VirtualFunctionHelper::VirtualFunctionHelper(TypeOfExpression &typeOfExpression, bool VirtualFunctionHelper::canLookupVirtualFunctionOverrides(Function *function) { m_function = function; - if (!m_function || !m_baseExpressionAST || !m_expressionDocument || !m_document || !m_scope - || m_scope->isClass() || m_scope->isFunction() || m_snapshot.isEmpty()) { + + if (!m_document || m_snapshot.isEmpty() || !m_function || !m_scope) + return false; + + if (m_scope->isClass() && m_function->isPureVirtual()) { + m_staticClassOfFunctionCallExpression = m_scope->asClass(); + return true; + } + + if (!m_baseExpressionAST || !m_expressionDocument + || m_scope->isClass() || m_scope->isFunction()) { return false; }