diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-11-20 15:03:10 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-11-23 13:03:34 +0000 |
commit | 0d12c8cba857ae5e0d249ecfafb2a0107866708b (patch) | |
tree | 8d9212be4d5add0333556bba31a8e605be9be728 | |
parent | d3fafcde0fd4f74112d20228ac7175a02ffcb821 (diff) |
clangbackend: More cursor adjustments
Fixes: QTCREATORBUG-21534
Change-Id: Ia8a6f277b186bd6decdfec26bfca30b36802c1c2
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r-- | src/tools/clangbackend/source/tokeninfo.cpp | 42 | ||||
-rw-r--r-- | src/tools/clangbackend/source/tokeninfo.h | 1 | ||||
-rw-r--r-- | tests/unit/unittest/data/highlightingmarks.cpp | 6 | ||||
-rw-r--r-- | 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<CXSourceRange> *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() |