From 0d12c8cba857ae5e0d249ecfafb2a0107866708b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 20 Nov 2020 15:03:10 +0100 Subject: clangbackend: More cursor adjustments Fixes: QTCREATORBUG-21534 Change-Id: Ia8a6f277b186bd6decdfec26bfca30b36802c1c2 Reviewed-by: Christian Stenger --- src/tools/clangbackend/source/tokeninfo.cpp | 42 +++++++++++++++++++------- src/tools/clangbackend/source/tokeninfo.h | 1 + tests/unit/unittest/data/highlightingmarks.cpp | 6 ++++ tests/unit/unittest/tokenprocessor-test.cpp | 7 +++++ 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/tools/clangbackend/source/tokeninfo.cpp b/src/tools/clangbackend/source/tokeninfo.cpp index f5a3622662..5ac579570e 100644 --- a/src/tools/clangbackend/source/tokeninfo.cpp +++ b/src/tools/clangbackend/source/tokeninfo.cpp @@ -226,6 +226,28 @@ bool TokenInfo::isArgumentInCurrentOutputArgumentLocations() const return isOutputArgument; } +// For reasons I don't fully understand, the cursors from clang_annotateTokens() are sometimes +// not the actual cursor for the respective token, but the one for a construct higher up +// in the syntax tree. This is often not what we want (e.g. QTCREATORBUG-21522, QTCREATORBUG-21534), +// so in such cases we re-retrieve the cursor for the token via clang_getCursor(). +Cursor TokenInfo::realCursor(const Cursor &cursor) const +{ + // Magic Qt stuff. + if (cursor.kind() == CXCursor_InvalidFile) + return cursor; + + const SourceLocation tokenLoc = m_token->location(); + const SourceLocation cursorLoc = cursor.sourceLocation(); + if (tokenLoc == cursorLoc) + return cursor; + + // Note: clang_getTokenLocation() does not work. + const CXFile cxFile = clang_getFile(m_token->tu(), tokenLoc.filePath().toByteArray()); + const CXSourceLocation cxLoc = clang_getLocation(m_token->tu(), cxFile, tokenLoc.line(), + tokenLoc.column()); + return clang_getCursor(m_token->tu(), cxLoc); +} + bool TokenInfo::isOutputArgument() const { if (m_currentOutputArgumentRanges->empty()) @@ -358,6 +380,14 @@ void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion) if (cursor.isInvalidDeclaration()) return; + if (recursion == Recursion::FirstPass) { + const Cursor c = realCursor(cursor); + if (!clang_isInvalid(c.kind()) && c != cursor) { + identifierKind(c, Recursion::FirstPass); + return; + } + } + const CXCursorKind kind = cursor.kind(); switch (kind) { case CXCursor_Destructor: @@ -452,18 +482,8 @@ void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion) case CXCursor_InvalidFile: invalidFileKind(); break; - default: { - // QTCREATORBUG-21522 - // Note: clang_getTokenLocation() does not work. - const SourceLocation loc = m_token->location(); - const CXFile cxFile = clang_getFile(m_token->tu(), loc.filePath().toByteArray()); - const CXSourceLocation cxLoc = clang_getLocation(m_token->tu(), cxFile, loc.line(), - loc.column()); - const CXCursor realCursor = clang_getCursor(m_token->tu(), cxLoc); - if (realCursor != cursor) - identifierKind(realCursor, Recursion::FirstPass); + default: break; - } } } diff --git a/src/tools/clangbackend/source/tokeninfo.h b/src/tools/clangbackend/source/tokeninfo.h index 7e125ad5e6..bcb77bddee 100644 --- a/src/tools/clangbackend/source/tokeninfo.h +++ b/src/tools/clangbackend/source/tokeninfo.h @@ -114,6 +114,7 @@ private: void collectOutputArguments(const Cursor &cursor); void filterOutPreviousOutputArguments(); bool isArgumentInCurrentOutputArgumentLocations() const; + Cursor realCursor(const Cursor &cursor) const; std::vector *m_currentOutputArgumentRanges = nullptr; uint m_line = 0; diff --git a/tests/unit/unittest/data/highlightingmarks.cpp b/tests/unit/unittest/data/highlightingmarks.cpp index a28210012b..bc90444028 100644 --- a/tests/unit/unittest/data/highlightingmarks.cpp +++ b/tests/unit/unittest/data/highlightingmarks.cpp @@ -745,3 +745,9 @@ void f4() ASSIGN(int i, thePointer); ASSIGN2(int i, thePointer); } + +const int MyConstant = 8; +void f5() +{ + int arr[MyConstant][8]; +} diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp index a80d90eec4..b1956bbcfd 100644 --- a/tests/unit/unittest/tokenprocessor-test.cpp +++ b/tests/unit/unittest/tokenprocessor-test.cpp @@ -1776,6 +1776,13 @@ TEST_F(TokenProcessor, IndirectMacro) ASSERT_THAT(infos[5], IsHighlightingMark(746u, 20u, 10u, HighlightingType::LocalVariable)); } +TEST_F(TokenProcessor, MultiDimArray) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(752, 28)); + + ASSERT_THAT(infos[3], IsHighlightingMark(752u, 13u, 10u, HighlightingType::GlobalVariable)); +} + Data *TokenProcessor::d; void TokenProcessor::SetUpTestCase() -- cgit v1.2.3