diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2013-12-10 12:53:20 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2013-12-10 12:53:20 +0100 |
commit | 9f831dde07cb2411808534e76669b28a1b76e21d (patch) | |
tree | ed6252d64c9a3ab27aa93786272cda1b6008f3c7 /src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp | |
parent | cdac81f896ef4b052d76f96485a08e6ec13696b8 (diff) | |
parent | ea1a92484ac99057b06130a012164bf9788650e9 (diff) | |
download | qt-creator-wip/clang.tar.gz |
Merge remote-tracking branch 'origin/master' into wip/clangwip/clang
Change-Id: I8a2c8068a3f2b15034fb1bf6304c9a0f3f0e3c8f
Diffstat (limited to 'src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp')
-rw-r--r-- | src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp | 148 |
1 files changed, 106 insertions, 42 deletions
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp index 1e0f45334f..4530a47b98 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp @@ -210,52 +210,70 @@ IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const enum VirtualType { Virtual, PureVirtual }; static bool isVirtualFunction_helper(const Function *function, - const Snapshot &snapshot, - VirtualType virtualType) + const LookupContext &context, + VirtualType virtualType, + const Function **firstVirtual) { + enum { Unknown, False, True } res = Unknown; + + if (firstVirtual) + *firstVirtual = 0; + if (!function) return false; if (virtualType == PureVirtual) - return function->isPureVirtual(); - - if (function->isVirtual()) - return true; - - const QString filePath = QString::fromUtf8(function->fileName(), function->fileNameLength()); - if (Document::Ptr document = snapshot.document(filePath)) { - LookupContext context(document, snapshot); - QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope()); - if (!results.isEmpty()) { - const bool isDestructor = function->name()->isDestructorNameId(); - foreach (const LookupItem &item, results) { - if (Symbol *symbol = item.declaration()) { - if (Function *functionType = symbol->type()->asFunctionType()) { - if (functionType->name()->isDestructorNameId() != isDestructor) - continue; - if (functionType == function) // already tested - continue; - if (functionType->isFinal()) - return false; - if (functionType->isVirtual()) + res = function->isPureVirtual() ? True : False; + + if (function->isVirtual()) { + if (firstVirtual) + *firstVirtual = function; + if (res == Unknown) + res = True; + } + + if (!firstVirtual && res != Unknown) + return res == True; + + QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope()); + if (!results.isEmpty()) { + const bool isDestructor = function->name()->isDestructorNameId(); + foreach (const LookupItem &item, results) { + if (Symbol *symbol = item.declaration()) { + if (Function *functionType = symbol->type()->asFunctionType()) { + if (functionType->name()->isDestructorNameId() != isDestructor) + continue; + if (functionType == function) // already tested + continue; + if (functionType->isFinal()) + return res == True; + if (functionType->isVirtual()) { + if (!firstVirtual) return true; + if (res == Unknown) + res = True; + *firstVirtual = functionType; } } } } } - return false; + return res == True; } -bool FunctionHelper::isVirtualFunction(const Function *function, const Snapshot &snapshot) +bool FunctionHelper::isVirtualFunction(const Function *function, + const LookupContext &context, + const Function **firstVirtual) { - return isVirtualFunction_helper(function, snapshot, Virtual); + return isVirtualFunction_helper(function, context, Virtual, firstVirtual); } -bool FunctionHelper::isPureVirtualFunction(const Function *function, const Snapshot &snapshot) +bool FunctionHelper::isPureVirtualFunction(const Function *function, + const LookupContext &context, + const Function **firstVirtual) { - return isVirtualFunction_helper(function, snapshot, PureVirtual); + return isVirtualFunction_helper(function, context, PureVirtual, firstVirtual); } QList<Symbol *> FunctionHelper::overrides(Function *function, Class *functionsClass, @@ -324,6 +342,7 @@ typedef QList<Virtuality> VirtualityList; Q_DECLARE_METATYPE(CppEditor::Internal::Virtuality) Q_DECLARE_METATYPE(CppEditor::Internal::VirtualityList) +Q_DECLARE_METATYPE(QList<int>) namespace CppEditor { namespace Internal { @@ -333,33 +352,54 @@ void CppEditorPlugin::test_functionhelper_virtualFunctions() // Create and parse document QFETCH(QByteArray, source); QFETCH(VirtualityList, virtualityList); + QFETCH(QList<int>, firstVirtualList); Document::Ptr document = Document::create(QLatin1String("virtuals")); document->setUtf8Source(source); document->check(); // calls parse(); QCOMPARE(document->diagnosticMessages().size(), 0); QVERIFY(document->translationUnit()->ast()); + QList<const Function *> allFunctions; + const Function *firstVirtual = 0; // Iterate through Function symbols Snapshot snapshot; snapshot.insert(document); + const LookupContext context(document, snapshot); Control *control = document->translationUnit()->control(); Symbol **end = control->lastSymbol(); for (Symbol **it = control->firstSymbol(); it != end; ++it) { - const CPlusPlus::Symbol *symbol = *it; - if (const Function *function = symbol->asFunction()) { + if (const Function *function = (*it)->asFunction()) { + allFunctions.append(function); QTC_ASSERT(!virtualityList.isEmpty(), return); Virtuality virtuality = virtualityList.takeFirst(); - if (FunctionHelper::isVirtualFunction(function, snapshot)) { - if (FunctionHelper::isPureVirtualFunction(function, snapshot)) + QTC_ASSERT(!firstVirtualList.isEmpty(), return); + int firstVirtualIndex = firstVirtualList.takeFirst(); + bool isVirtual = FunctionHelper::isVirtualFunction(function, context, &firstVirtual); + bool isPureVirtual = FunctionHelper::isPureVirtualFunction(function, context, + &firstVirtual); + + // Test for regressions introduced by firstVirtual + QCOMPARE(FunctionHelper::isVirtualFunction(function, context), isVirtual); + QCOMPARE(FunctionHelper::isPureVirtualFunction(function, context), isPureVirtual); + if (isVirtual) { + if (isPureVirtual) QCOMPARE(virtuality, PureVirtual); else QCOMPARE(virtuality, Virtual); } else { + QEXPECT_FAIL("virtual-dtor-dtor", "Not implemented", Abort); + if (allFunctions.size() == 3) + QEXPECT_FAIL("dtor-virtual-dtor-dtor", "Not implemented", Abort); QCOMPARE(virtuality, NotVirtual); } + if (firstVirtualIndex == -1) + QVERIFY(!firstVirtual); + else + QCOMPARE(firstVirtual, allFunctions.at(firstVirtualIndex)); } } QVERIFY(virtualityList.isEmpty()); + QVERIFY(firstVirtualList.isEmpty()); } void CppEditorPlugin::test_functionhelper_virtualFunctions_data() @@ -367,55 +407,79 @@ void CppEditorPlugin::test_functionhelper_virtualFunctions_data() typedef QByteArray _; QTest::addColumn<QByteArray>("source"); QTest::addColumn<VirtualityList>("virtualityList"); + QTest::addColumn<QList<int> >("firstVirtualList"); QTest::newRow("none") << _("struct None { void foo() {} };\n") - << (VirtualityList() << NotVirtual); + << (VirtualityList() << NotVirtual) + << (QList<int>() << -1); QTest::newRow("single-virtual") << _("struct V { virtual void foo() {} };\n") - << (VirtualityList() << Virtual); + << (VirtualityList() << Virtual) + << (QList<int>() << 0); QTest::newRow("single-pure-virtual") << _("struct PV { virtual void foo() = 0; };\n") - << (VirtualityList() << PureVirtual); + << (VirtualityList() << PureVirtual) + << (QList<int>() << 0); QTest::newRow("virtual-derived-with-specifier") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { virtual void foo() {} };\n") - << (VirtualityList() << Virtual << Virtual); + << (VirtualityList() << Virtual << Virtual) + << (QList<int>() << 0 << 0); QTest::newRow("virtual-derived-implicit") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { void foo() {} };\n") - << (VirtualityList() << Virtual << Virtual); + << (VirtualityList() << Virtual << Virtual) + << (QList<int>() << 0 << 0); QTest::newRow("not-virtual-then-virtual") << _("struct Base { void foo() {} };\n" "struct Derived : Base { virtual void foo() {} };\n") - << (VirtualityList() << NotVirtual << Virtual); + << (VirtualityList() << NotVirtual << Virtual) + << (QList<int>() << -1 << 1); QTest::newRow("virtual-final-not-virtual") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { void foo() final {} };\n" "struct Derived2 : Derived { void foo() {} };") - << (VirtualityList() << Virtual << Virtual << NotVirtual); + << (VirtualityList() << Virtual << Virtual << NotVirtual) + << (QList<int>() << 0 << 0 << -1); QTest::newRow("virtual-then-pure") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { virtual void foo() = 0; };\n" "struct Derived2 : Derived { void foo() {} };") - << (VirtualityList() << Virtual << PureVirtual << Virtual); + << (VirtualityList() << Virtual << PureVirtual << Virtual) + << (QList<int>() << 0 << 0 << 0); QTest::newRow("virtual-virtual-final-not-virtual") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { virtual void foo() final {} };\n" "struct Derived2 : Derived { void foo() {} };") - << (VirtualityList() << Virtual << Virtual << NotVirtual); + << (VirtualityList() << Virtual << Virtual << NotVirtual) + << (QList<int>() << 0 << 0 << -1); QTest::newRow("ctor-virtual-dtor") << _("struct Base { Base() {} virtual ~Base() {} };\n") - << (VirtualityList() << NotVirtual << Virtual); + << (VirtualityList() << NotVirtual << Virtual) + << (QList<int>() << -1 << 1); + + QTest::newRow("virtual-dtor-dtor") + << _("struct Base { virtual ~Base() {} };\n" + "struct Derived : Base { ~Derived() {} };\n") + << (VirtualityList() << Virtual << Virtual) + << (QList<int>() << 0 << 0); + + QTest::newRow("dtor-virtual-dtor-dtor") + << _("struct Base { ~Base() {} };\n" + "struct Derived : Base { virtual ~Derived() {} };\n" + "struct Derived2 : Derived { ~Derived2() {} };\n") + << (VirtualityList() << NotVirtual << Virtual << Virtual) + << (QList<int>() << -1 << 1 << 1); } } // namespace Internal |