clangbackend: Work around libclang cursor bug

... involving accessing the member of a nested anonymous union from
within the surrounding class. libclang reports a CXCursor_CXXThisExpr
for this location instead of a CXCursor_MemberRefExpr. However, the
latter is still locatable in the AST, so we can correct this.

Fixes: QTCREATORBUG-25342
Change-Id: I1eba13d5153205a52b3689d8ad52493a56b76c07
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Christian Kandeler
2021-02-15 12:27:23 +01:00
parent 222e8c1286
commit 74177a559e
3 changed files with 30 additions and 0 deletions

View File

@@ -95,6 +95,16 @@ FollowSymbolResult FollowSymbol::followSymbol(CXTranslationUnit tu,
return SourceRangeContainer();
Cursor cursor{cursors[tokenIndex]};
if (cursor.kind() == CXCursor_CXXThisExpr && tokenSpelling != "this") { // QTCREATORBUG-25342
cursor.semanticParent().visit([&cursor](CXCursor current, CXCursor parent) {
if (current == cursor && parent.kind == CXCursor_MemberRefExpr
&& cursor.sourceLocation() == Cursor(parent).sourceLocation()) {
cursor = parent;
return CXChildVisit_Break;
}
return CXChildVisit_Recurse;
});
}
if (cursor.kind() == CXCursor_InclusionDirective) {
CXFile file = clang_getIncludedFile(cursors[tokenIndex].cx());

View File

@@ -209,6 +209,13 @@ TEST_F(FollowSymbol, CursorOnMemberReference)
ASSERT_THAT(memberDeclaration, MatchesHeaderSourceRange(38, 18, 6));
}
TEST_F(FollowSymbol, CursorOnMemberReferenceAnonymousUnion)
{
const auto memberDeclaration = followSymbol(91, 20);
ASSERT_THAT(memberDeclaration, MatchesSourceRange(86, 13, 1));
}
TEST_F(FollowSymbol, CursorOnMemberDeclaration)
{
const auto sameMemberDeclaration = followHeaderSymbol(38, 18);

View File

@@ -80,3 +80,16 @@ int Bar::operator&() {
Bar& Bar::operator[](int) {
return *this;
}
struct S {
union {
int i = 12;
void *something;
};
int func(bool b) {
if (b)
return i;
int i = 42;
return i;
}
};