From 25144c0afe39f9079812ebc660ed332a4f267e47 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 4 Apr 2022 12:01:39 +0200 Subject: [PATCH] ClangCodeModel: Fix erroneous highlighting as output argument ... for objects with non-const member calls. Amends 8247f4f3dd. Fixes: QTCREATORBUG-27306 Change-Id: I13fdf1ff9daf9ac084beda6c1d8ada5801adca4c Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/clangcodemodel/clangdclient.cpp | 10 +++++++-- .../clangcodemodel/test/clangdtests.cpp | 6 ++++++ .../test/data/highlighting/highlighting.cpp | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index ab08f9cc96f..0e4ff1bc3e8 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2707,9 +2707,15 @@ static void semanticHighlighter(QFutureInterface &future, if (path.rbegin()->hasConstType()) return false; for (auto it = path.rbegin() + 1; it != path.rend(); ++it) { - if (it->kind() == "Call" || it->kind() == "CXXConstruct" - || it->kind() == "MemberInitializer") { + if (it->kind() == "CXXConstruct" || it->kind() == "MemberInitializer") return true; + + if (it->kind() == "Call") { + // In class templates, member calls can result in "Call" nodes rather than + // "CXXMemberCall". We try to detect this by checking for a certain kind of + // child node. + const QList children = it->children().value_or(QList()); + return children.isEmpty() || children.first().kind() != "CXXDependentScopeMember"; } // The token should get marked for e.g. lambdas, but not for assignment operators, diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 0381bd25772..67339c77293 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1315,6 +1315,12 @@ void ClangdTestHighlighting::test_data() QTest::newRow("deref operator (object)") << 960 << 10 << 960 << 11 << QList{C_LOCAL} << 0; QTest::newRow("deref operator (member)") << 960 << 12 << 960 << 13 << QList{C_FIELD} << 0; QTest::newRow("nested call") << 979 << 20 << 979 << 21 << QList{C_LOCAL} << 0; + QTest::newRow("member call on dependent (1)") << 996 << 19 << 996 << 22 + << QList{C_FIELD} << 0; + QTest::newRow("member call on dependent (2)") << 996 << 38 << 996 << 41 + << QList{C_FIELD} << 0; + QTest::newRow("member call on dependent (3)") << 999 << 9 << 999 << 12 + << QList{C_LOCAL} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index 7275ddd3307..1d4bcce7f8e 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -978,3 +978,24 @@ void nestedCall() my_struct* s = get_my_struct(); new my_struct2(s->method(0)); } + +template +class my_class +{ +private: + struct my_int + { + int n; + }; + + std::vector vec; + +public: + void foo() + { + auto it = vec.begin(), end = vec.end(); + + T* ptr = nullptr; + ptr->bar(); + } +};