Author: mydeveloperday Date: 2020-05-25T10:45:12+02:00 New Revision: 447ea9b4f5f562c8fab7d11ecbb10ecd33155d5b
URL: https://github.com/llvm/llvm-project/commit/447ea9b4f5f562c8fab7d11ecbb10ecd33155d5b DIFF: https://github.com/llvm/llvm-project/commit/447ea9b4f5f562c8fab7d11ecbb10ecd33155d5b.diff LOG: [AST] default implementation is possible for non-member functions in C++20. Summary: Make RAV not visit the default function decl by default. Also update some stale comments on FunctionDecl::isDefault. Fixes https://github.com/clangd/clangd/issues/383 Reviewers: sammccall, rsmith Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D80288 Added: Modified: clang/include/clang/AST/Decl.h clang/include/clang/AST/RecursiveASTVisitor.h clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index d7136a4cd420..2e1630827cce 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2125,19 +2125,17 @@ class FunctionDecl : public DeclaratorDecl, bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; } void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; } - /// Whether this function is defaulted per C++0x. Only valid for - /// special member functions. + /// Whether this function is defaulted. Valid for e.g. + /// special member functions, defaulted comparisions (not methods!). bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; } void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; } - /// Whether this function is explicitly defaulted per C++0x. Only valid - /// for special member functions. + /// Whether this function is explicitly defaulted. bool isExplicitlyDefaulted() const { return FunctionDeclBits.IsExplicitlyDefaulted; } - /// State that this function is explicitly defaulted per C++0x. Only valid - /// for special member functions. + /// State that this function is explicitly defaulted. void setExplicitlyDefaulted(bool ED = true) { FunctionDeclBits.IsExplicitlyDefaulted = ED; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index a264d1cf24b2..b30d456bd24a 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2103,11 +2103,11 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { } } - 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(); + bool VisitBody = + D->isThisDeclarationADefinition() && + // Don't visit the function body if the function definition is generated + // by clang. + (!D->isDefaulted() || getDerived().shouldVisitImplicitCode()); if (VisitBody) { TRY_TO(TraverseStmt(D->getBody())); // Function body. diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp index 6441ea99dd2c..90fa84bd4481 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp @@ -55,4 +55,22 @@ TEST(RecursiveASTVisitor, CXXMethodDeclNoDefaultBodyVisited) { EXPECT_TRUE(Visitor.runOver(Code, CXXMethodDeclVisitor::Lang_CXX11)); } } + +TEST(RecursiveASTVisitor, FunctionDeclNoDefaultBodyVisited) { + for (bool VisitImplCode : {false, true}) { + CXXMethodDeclVisitor Visitor(VisitImplCode); + if (VisitImplCode) + Visitor.ExpectMatch("declref", 4, 58, /*Times=*/2); + else + Visitor.DisallowMatch("declref", 4, 58); + llvm::StringRef Code = R"cpp( + struct s { + int x; + friend auto operator==(s a, s b) -> bool = default; + }; + bool k = s() == s(); // make sure clang generates the "==" definition. + )cpp"; + EXPECT_TRUE(Visitor.runOver(Code, CXXMethodDeclVisitor::Lang_CXX2a)); + } +} } // end anonymous namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits