From: Johan Vikstrom Date: Mon, 5 Aug 2019 12:20:43 +0000 (+0000) Subject: [AST] Fix RecursiveASTVisitor visiting implicit constructor initializers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d283a9c57cb2f88db5675a2488bfdf6612b5aef;p=clang [AST] Fix RecursiveASTVisitor visiting implicit constructor initializers. Summary: RecursiveASTVisitor was visiting implcit constructor initializers. This caused semantic highlighting in clangd to emit error logs. Fixes this by checking if the constructor is written or if the visitor should visit implicit decls. Reviewers: hokein, ilya-biryukov Subscribers: kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D65735 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@367839 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index dd2c1dad71..eb047bd5c5 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2023,7 +2023,8 @@ bool RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) { if (CXXConstructorDecl *Ctor = dyn_cast(D)) { // Constructor initializers. for (auto *I : Ctor->inits()) { - TRY_TO(TraverseConstructorInitializer(I)); + if (I->isWritten() || getDerived().shouldVisitImplicitCode()) + TRY_TO(TraverseConstructorInitializer(I)); } } diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt index a10bff6d83..99a3e0f209 100644 --- a/unittests/Tooling/CMakeLists.txt +++ b/unittests/Tooling/CMakeLists.txt @@ -31,6 +31,7 @@ add_clang_unittest(ToolingTests RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp RecursiveASTVisitorTests/DeclRefExpr.cpp RecursiveASTVisitorTests/ImplicitCtor.cpp + RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp RecursiveASTVisitorTests/InitListExprPostOrder.cpp RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp RecursiveASTVisitorTests/InitListExprPreOrder.cpp diff --git a/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp b/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp new file mode 100644 index 0000000000..5b133e140e --- /dev/null +++ b/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp @@ -0,0 +1,57 @@ +//=- unittest/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.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 CXXCtorInitializerVisitor + : public ExpectedLocationVisitor { +public: + CXXCtorInitializerVisitor(bool VisitImplicitCode) + : VisitImplicitCode(VisitImplicitCode) {} + + bool shouldVisitImplicitCode() const { return VisitImplicitCode; } + + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + if (!Init->isWritten()) + VisitedImplicitInitializer = true; + Match("initializer", Init->getSourceLocation()); + return ExpectedLocationVisitor< + CXXCtorInitializerVisitor>::TraverseConstructorInitializer(Init); + } + + bool VisitedImplicitInitializer = false; + +private: + bool VisitImplicitCode; +}; + +// Check to ensure that CXXCtorInitializer is not visited when implicit code +// should not be visited and that it is visited when implicit code should be +// visited. +TEST(RecursiveASTVisitor, CXXCtorInitializerVisitNoImplicit) { + for (bool VisitImplCode : {true, false}) { + CXXCtorInitializerVisitor Visitor(VisitImplCode); + Visitor.ExpectMatch("initializer", 7, 17); + EXPECT_TRUE(Visitor.runOver(R"cpp( + class A {}; + class B : public A { + B() {}; + }; + class C : public A { + C() : A() {} + }; + )cpp", + CXXCtorInitializerVisitor::Lang_CXX)); + EXPECT_EQ(Visitor.VisitedImplicitInitializer, VisitImplCode); + } +} +} // end anonymous namespace