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",
|
)cpp",
|
||||||
R"cpp(
|
R"cpp(
|
||||||
template<typename $TemplateParameter[[T]],
|
template<typename $TemplateParameter[[T]],
|
||||||
void (T::*$TemplateParameter[[method]])(int)>
|
void ($TemplateParameter[[T]]::*$TemplateParameter[[method]])(int)>
|
||||||
struct $Class[[G]] {
|
struct $Class[[G]] {
|
||||||
void $Method[[foo]](
|
void $Method[[foo]](
|
||||||
$TemplateParameter[[T]] *$Parameter[[O]]) {
|
$TemplateParameter[[T]] *$Parameter[[O]]) {
|
||||||
|
|
|
@ -1162,10 +1162,12 @@ DEF_TRAVERSE_TYPELOC(LValueReferenceType,
|
||||||
DEF_TRAVERSE_TYPELOC(RValueReferenceType,
|
DEF_TRAVERSE_TYPELOC(RValueReferenceType,
|
||||||
{ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
|
{ 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
|
// We traverse this in the type case as well, but how is it not reached through
|
||||||
// the pointee type?
|
// the pointee type?
|
||||||
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
|
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(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
|
||||||
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
|
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,6 +42,7 @@ add_clang_unittest(ToolingTests
|
||||||
RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
|
RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
|
||||||
RecursiveASTVisitorTests/LambdaExpr.cpp
|
RecursiveASTVisitorTests/LambdaExpr.cpp
|
||||||
RecursiveASTVisitorTests/LambdaTemplateParams.cpp
|
RecursiveASTVisitorTests/LambdaTemplateParams.cpp
|
||||||
|
RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
|
||||||
RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
|
RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
|
||||||
RecursiveASTVisitorTests/ParenExpr.cpp
|
RecursiveASTVisitorTests/ParenExpr.cpp
|
||||||
RecursiveASTVisitorTests/TemplateArgumentLocTraverser.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