Author: Eduardo Caldas Date: 2020-08-04T14:31:12Z New Revision: 8ce15f7eeb122c0bba4b676d797217359dd57c30
URL: https://github.com/llvm/llvm-project/commit/8ce15f7eeb122c0bba4b676d797217359dd57c30 DIFF: https://github.com/llvm/llvm-project/commit/8ce15f7eeb122c0bba4b676d797217359dd57c30.diff LOG: [SyntaxTree] Fix crash on pointer to member function Differential Revision: https://reviews.llvm.org/D85146 Added: Modified: clang/lib/Tooling/Syntax/BuildTree.cpp clang/unittests/Tooling/Syntax/TreeTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index 1f192180ec45..15b7c8fab198 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -939,6 +939,8 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> { return true; } + // FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test + // results. Find test coverage or remove it. bool TraverseParenTypeLoc(ParenTypeLoc L) { // We reverse order of traversal to get the proper syntax structure. if (!WalkUpFromParenTypeLoc(L)) @@ -987,6 +989,16 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> { return WalkUpFromFunctionTypeLoc(L); } + bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) { + // In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds + // to "Y::*" but it points to a `ParenTypeLoc` that corresponds to + // "(Y::*mp)" We thus reverse the order of traversal to get the proper + // syntax structure. + if (!WalkUpFromMemberPointerTypeLoc(L)) + return false; + return TraverseTypeLoc(L.getPointeeLoc()); + } + bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) { auto SR = L.getLocalSourceRange(); Builder.foldNode(Builder.getRange(SR), diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp index a722ca2b1a45..3ccfabb95da9 100644 --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -4074,6 +4074,99 @@ const int X::* b; )txt")); } +TEST_P(SyntaxTreeTest, MemberFunctionPointer) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +struct X { + struct Y {}; +}; +void (X::*xp)(); +void (X::**xpp)(const int*); +// FIXME: Generate the right syntax tree for this type, +// i.e. create a syntax node for the outer member pointer +void (X::Y::*xyp)(const int*, char); +)cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-struct +| |-X +| |-{ +| |-SimpleDeclaration +| | |-struct +| | |-Y +| | |-{ +| | |-} +| | `-; +| |-} +| `-; +|-SimpleDeclaration +| |-void +| |-SimpleDeclarator +| | |-ParenDeclarator +| | | |-( +| | | |-MemberPointer +| | | | |-X +| | | | |-:: +| | | | `-* +| | | |-xp +| | | `-) +| | `-ParametersAndQualifiers +| | |-( +| | `-) +| `-; +|-SimpleDeclaration +| |-void +| |-SimpleDeclarator +| | |-ParenDeclarator +| | | |-( +| | | |-MemberPointer +| | | | |-X +| | | | |-:: +| | | | `-* +| | | |-* +| | | |-xpp +| | | `-) +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-const +| | | |-int +| | | `-SimpleDeclarator +| | | `-* +| | `-) +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-ParenDeclarator + | | |-( + | | |-X + | | |-:: + | | |-MemberPointer + | | | |-Y + | | | |-:: + | | | `-* + | | |-xyp + | | `-) + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-const + | | |-int + | | `-SimpleDeclarator + | | `-* + | |-, + | |-SimpleDeclaration + | | `-char + | `-) + `-; +)txt")); +} + TEST_P(SyntaxTreeTest, ComplexDeclarator) { EXPECT_TRUE(treeDumpEqual( R"cpp( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits