Skip to content

Commit 6d5c273

Browse files
committed
Reland "[AST] Traverse the class type loc inside the member type loc.""
Summary: added a unittest which causes "TL.getClassTInfo" is null. Reviewers: ilya-biryukov Subscribers: mgorny, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D71186
1 parent 385ba60 commit 6d5c273

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,8 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
407407
}
408408
)cpp",
409409
R"cpp(
410-
template<typename $TemplateParameter[[T]],
411-
void (T::*$TemplateParameter[[method]])(int)>
410+
template<typename $TemplateParameter[[T]],
411+
void ($TemplateParameter[[T]]::*$TemplateParameter[[method]])(int)>
412412
struct $Class[[G]] {
413413
void $Method[[foo]](
414414
$TemplateParameter[[T]] *$Parameter[[O]]) {

clang/include/clang/AST/RecursiveASTVisitor.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1162,11 +1162,13 @@ DEF_TRAVERSE_TYPELOC(LValueReferenceType,
11621162
DEF_TRAVERSE_TYPELOC(RValueReferenceType,
11631163
{ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
11641164

1165-
// FIXME: location of base class?
11661165
// We traverse this in the type case as well, but how is it not reached through
11671166
// the pointee type?
11681167
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1169-
TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
1168+
if (auto *TSI = TL.getClassTInfo())
1169+
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
1170+
else
1171+
TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
11701172
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
11711173
})
11721174

clang/unittests/Tooling/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ add_clang_unittest(ToolingTests
4242
RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
4343
RecursiveASTVisitorTests/LambdaExpr.cpp
4444
RecursiveASTVisitorTests/LambdaTemplateParams.cpp
45+
RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
4546
RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
4647
RecursiveASTVisitorTests/ParenExpr.cpp
4748
RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===- unittest/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp -===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "TestVisitor.h"
10+
11+
using namespace clang;
12+
13+
namespace {
14+
15+
class MemberPointerTypeLocVisitor
16+
: public ExpectedLocationVisitor<MemberPointerTypeLocVisitor> {
17+
public:
18+
bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
19+
if (!TL)
20+
return true;
21+
Match(TL.getDecl()->getName(), TL.getNameLoc());
22+
return true;
23+
}
24+
bool VisitRecordTypeLoc(RecordTypeLoc RTL) {
25+
if (!RTL)
26+
return true;
27+
Match(RTL.getDecl()->getName(), RTL.getNameLoc());
28+
return true;
29+
}
30+
};
31+
32+
TEST(RecursiveASTVisitor, VisitTypeLocInMemberPointerTypeLoc) {
33+
MemberPointerTypeLocVisitor Visitor;
34+
Visitor.ExpectMatch("Bar", 4, 36);
35+
Visitor.ExpectMatch("T", 7, 23);
36+
EXPECT_TRUE(Visitor.runOver(R"cpp(
37+
class Bar { void func(int); };
38+
class Foo {
39+
void bind(const char*, void(Bar::*Foo)(int)) {}
40+
41+
template<typename T>
42+
void test(void(T::*Foo)());
43+
};
44+
)cpp"));
45+
}
46+
47+
TEST(RecursiveASTVisitor, NoCrash) {
48+
MemberPointerTypeLocVisitor Visitor;
49+
EXPECT_FALSE(Visitor.runOver(R"cpp(
50+
// MemberPointerTypeLoc.getClassTInfo() is null.
51+
class a(b(a::*)) class
52+
)cpp"));
53+
}
54+
55+
} // end anonymous namespace

0 commit comments

Comments
 (0)