aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2020-11-20 15:03:10 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2020-11-23 13:03:34 +0000
commit0d12c8cba857ae5e0d249ecfafb2a0107866708b (patch)
tree8d9212be4d5add0333556bba31a8e605be9be728
parentd3fafcde0fd4f74112d20228ac7175a02ffcb821 (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.cpp42
-rw-r--r--src/tools/clangbackend/source/tokeninfo.h1
-rw-r--r--tests/unit/unittest/data/highlightingmarks.cpp6
-rw-r--r--tests/unit/unittest/tokenprocessor-test.cpp7
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()