Author: jvikstrom
Date: Fri Aug 9 00:30:28 2019
New Revision: 368402
URL: http://llvm.org/viewvc/llvm-project?rev=368402&view=rev
Log:
[AST] No longer visiting CXXMethodDecl bodies created by compiler when method
was default created.
Summary:
Clang generates function bodies and puts them in the AST for default methods if
it is defaulted outside the class definition.
`
struct A {
A &operator=(A &&O);
};
A &A::operator=(A &&O) = default;
`
This will generate a function body for the `A &A::operator=(A &&O)` and put it
in the AST. This body should not be visited if implicit code is not visited as
it is implicit.
This was causing SemanticHighlighting in clangd to generate duplicate tokens
and putting them in weird places.
Reviewers: hokein, ilya-biryukov, gribozavr
Subscribers: mgorny, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65938
Added:
cfe/trunk/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp
Modified:
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/unittests/Tooling/CMakeLists.txt
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=368402&r1=368401&r2=368402&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Aug 9 00:30:28 2019
@@ -2027,7 +2027,13 @@ bool RecursiveASTVisitor<Derived>::Trave
}
}
- if (D->isThisDeclarationADefinition()) {
+ bool VisitBody = D->isThisDeclarationADefinition();
+ // If a method is set to default outside the class definition the compiler
+ // generates the method body and adds it to the AST.
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
+ VisitBody &= !MD->isDefaulted() || getDerived().shouldVisitImplicitCode();
+
+ if (VisitBody) {
TRY_TO(TraverseStmt(D->getBody())); // Function body.
}
return true;
Modified: cfe/trunk/unittests/Tooling/CMakeLists.txt
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/CMakeLists.txt?rev=368402&r1=368401&r2=368402&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/CMakeLists.txt (original)
+++ cfe/trunk/unittests/Tooling/CMakeLists.txt Fri Aug 9 00:30:28 2019
@@ -28,6 +28,7 @@ add_clang_unittest(ToolingTests
RecursiveASTVisitorTests/ConstructExpr.cpp
RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
RecursiveASTVisitorTests/CXXMemberCall.cpp
+ RecursiveASTVisitorTests/CXXMethodDecl.cpp
RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
RecursiveASTVisitorTests/DeclRefExpr.cpp
RecursiveASTVisitorTests/ImplicitCtor.cpp
Added: cfe/trunk/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp?rev=368402&view=auto
==============================================================================
--- cfe/trunk/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp
(added)
+++ cfe/trunk/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp Fri
Aug 9 00:30:28 2019
@@ -0,0 +1,58 @@
+//=------ unittest/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.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"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+
+namespace {
+
+class CXXMethodDeclVisitor
+ : public ExpectedLocationVisitor<CXXMethodDeclVisitor> {
+public:
+ CXXMethodDeclVisitor(bool VisitImplicitCode)
+ : VisitImplicitCode(VisitImplicitCode) {}
+
+ bool shouldVisitImplicitCode() const { return VisitImplicitCode; }
+
+ bool VisitDeclRefExpr(DeclRefExpr *D) {
+ Match("declref", D->getLocation());
+ return true;
+ }
+ bool VisitParmVarDecl(ParmVarDecl *P) {
+ Match("parm", P->getLocation());
+ return true;
+ }
+
+private:
+ bool VisitImplicitCode;
+};
+
+TEST(RecursiveASTVisitor, CXXMethodDeclNoDefaultBodyVisited) {
+ for (bool VisitImplCode : {false, true}) {
+ CXXMethodDeclVisitor Visitor(VisitImplCode);
+ if (VisitImplCode)
+ Visitor.ExpectMatch("declref", 8, 28);
+ else
+ Visitor.DisallowMatch("declref", 8, 28);
+
+ Visitor.ExpectMatch("parm", 8, 27);
+ llvm::StringRef Code = R"cpp(
+ struct B {};
+ struct A {
+ B BB;
+ A &operator=(A &&O);
+ };
+
+ A &A::operator=(A &&O) = default;
+ )cpp";
+ EXPECT_TRUE(Visitor.runOver(Code, CXXMethodDeclVisitor::Lang_CXX11));
+ }
+}
+} // end anonymous namespace
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits