forked from OSchip/llvm-project
[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 llvm-svn: 367839
This commit is contained in:
parent
068f8c74e4
commit
be60f97d23
|
@ -2023,7 +2023,8 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
|
|||
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
|
||||
// Constructor initializers.
|
||||
for (auto *I : Ctor->inits()) {
|
||||
TRY_TO(TraverseConstructorInitializer(I));
|
||||
if (I->isWritten() || getDerived().shouldVisitImplicitCode())
|
||||
TRY_TO(TraverseConstructorInitializer(I));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<CXXCtorInitializerVisitor> {
|
||||
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
|
Loading…
Reference in New Issue