forked from OSchip/llvm-project
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
This commit is contained in:
parent
385ba6065a
commit
6d5c273500
|
@ -408,7 +408,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
)cpp",
|
||||
R"cpp(
|
||||
template<typename $TemplateParameter[[T]],
|
||||
void (T::*$TemplateParameter[[method]])(int)>
|
||||
void ($TemplateParameter[[T]]::*$TemplateParameter[[method]])(int)>
|
||||
struct $Class[[G]] {
|
||||
void $Method[[foo]](
|
||||
$TemplateParameter[[T]] *$Parameter[[O]]) {
|
||||
|
|
|
@ -1162,10 +1162,12 @@ DEF_TRAVERSE_TYPELOC(LValueReferenceType,
|
|||
DEF_TRAVERSE_TYPELOC(RValueReferenceType,
|
||||
{ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
|
||||
|
||||
// FIXME: location of base class?
|
||||
// We traverse this in the type case as well, but how is it not reached through
|
||||
// the pointee type?
|
||||
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
|
||||
if (auto *TSI = TL.getClassTInfo())
|
||||
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
|
||||
else
|
||||
TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
|
||||
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
|
||||
})
|
||||
|
|
|
@ -42,6 +42,7 @@ add_clang_unittest(ToolingTests
|
|||
RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
|
||||
RecursiveASTVisitorTests/LambdaExpr.cpp
|
||||
RecursiveASTVisitorTests/LambdaTemplateParams.cpp
|
||||
RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
|
||||
RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
|
||||
RecursiveASTVisitorTests/ParenExpr.cpp
|
||||
RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
//===- unittest/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp -===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "TestVisitor.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
|
||||
class MemberPointerTypeLocVisitor
|
||||
: public ExpectedLocationVisitor<MemberPointerTypeLocVisitor> {
|
||||
public:
|
||||
bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
|
||||
if (!TL)
|
||||
return true;
|
||||
Match(TL.getDecl()->getName(), TL.getNameLoc());
|
||||
return true;
|
||||
}
|
||||
bool VisitRecordTypeLoc(RecordTypeLoc RTL) {
|
||||
if (!RTL)
|
||||
return true;
|
||||
Match(RTL.getDecl()->getName(), RTL.getNameLoc());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(RecursiveASTVisitor, VisitTypeLocInMemberPointerTypeLoc) {
|
||||
MemberPointerTypeLocVisitor Visitor;
|
||||
Visitor.ExpectMatch("Bar", 4, 36);
|
||||
Visitor.ExpectMatch("T", 7, 23);
|
||||
EXPECT_TRUE(Visitor.runOver(R"cpp(
|
||||
class Bar { void func(int); };
|
||||
class Foo {
|
||||
void bind(const char*, void(Bar::*Foo)(int)) {}
|
||||
|
||||
template<typename T>
|
||||
void test(void(T::*Foo)());
|
||||
};
|
||||
)cpp"));
|
||||
}
|
||||
|
||||
TEST(RecursiveASTVisitor, NoCrash) {
|
||||
MemberPointerTypeLocVisitor Visitor;
|
||||
EXPECT_FALSE(Visitor.runOver(R"cpp(
|
||||
// MemberPointerTypeLoc.getClassTInfo() is null.
|
||||
class a(b(a::*)) class
|
||||
)cpp"));
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
Loading…
Reference in New Issue