diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -493,6 +493,9 @@ return traverseNode( X, [&] { return Base::TraverseConstructorInitializer(X); }); } + bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &X) { + return traverseNode(&X, [&] { return Base::TraverseCXXBaseSpecifier(X); }); + } // Stmt is the same, but this form allows the data recursion optimization. bool dataTraverseStmtPre(Stmt *X) { if (!X || isImplicit(X)) diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -1024,6 +1024,12 @@ } )cpp", "new name is the same", !HeaderFile, nullptr, "SameName"}, + {R"cpp(// Ensure it doesn't associate base specifier with base name. + struct A {}; + struct B : priv^ate A {}; + )cpp", + "Cannot rename symbol: there is no symbol at the given location", false, + nullptr}, }; for (const auto& Case : Cases) { diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -261,6 +261,27 @@ )cpp", "StringLiteral", // Not DeclRefExpr to operator()! }, + { + R"cpp( + struct Foo {}; + struct Bar : [[v^ir^tual private Foo]] {}; + )cpp", + "CXXBaseSpecifier", + }, + { + R"cpp( + struct Foo {}; + struct Bar : private [[Fo^o]] {}; + )cpp", + "RecordTypeLoc", + }, + { + R"cpp( + struct Foo {}; + struct Bar : [[Fo^o]] {}; + )cpp", + "RecordTypeLoc", + }, // Point selections. {"void foo() { [[^foo]](); }", "DeclRefExpr"}, diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -193,5 +193,7 @@ return TAL->getSourceRange(); if (const auto *C = get()) return SourceRange(C->getBeginLoc(), C->getEndLoc()); + if (const auto *CBS = get()) + return CBS->getSourceRange(); return SourceRange(); }