Skip to content

Commit

Permalink
[clangd] Allow indexing of __reserved_names outside system headers
Browse files Browse the repository at this point in the history
The special handling for these names was added in
055d809
and the motivation was the C++ standard library.

It turns out some projects like using these names anyway, in particular the
linux kernel. D153946 proposed making this a config option, but there are
some implementation issues with the config system.

As an alternative, this patch tweaks the heuristic so we only drop these symbols
in system headers. This does the right thing for linux and the C++ standard
library, at least.

Fixes clangd/clangd#1680
Fixes #63862

Differential Revision: https://reviews.llvm.org/D155381
  • Loading branch information
sam-mccall committed Jul 21, 2023
1 parent 775d6df commit 290a98c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
3 changes: 2 additions & 1 deletion clang-tools-extra/clangd/index/SymbolCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,8 @@ bool SymbolCollector::shouldCollectSymbol(const NamedDecl &ND,
if (isPrivateProtoDecl(ND))
return false;
if (!Opts.CollectReserved &&
(hasReservedName(ND) || hasReservedScope(*ND.getDeclContext())))
(hasReservedName(ND) || hasReservedScope(*ND.getDeclContext())) &&
ASTCtx.getSourceManager().isInSystemHeader(ND.getLocation()))
return false;

return true;
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/index/SymbolCollector.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class SymbolCollector : public index::IndexDataConsumer {
bool CollectMainFileRefs = false;
/// Collect symbols with reserved names, like __Vector_base.
/// This does not currently affect macros (many like _WIN32 are important!)
/// This only affects system headers.
bool CollectReserved = false;
/// If set to true, SymbolCollector will collect doc for all symbols.
/// Note that documents of symbols being indexed for completion will always
Expand Down
24 changes: 18 additions & 6 deletions clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,12 @@ class SymbolCollectorTest : public ::testing::Test {
Args, Factory->create(), Files.get(),
std::make_shared<PCHContainerOperations>());

InMemoryFileSystem->addFile(TestHeaderName, 0,
llvm::MemoryBuffer::getMemBuffer(HeaderCode));
InMemoryFileSystem->addFile(TestFileName, 0,
llvm::MemoryBuffer::getMemBuffer(MainCode));
// Multiple calls to runSymbolCollector with different contents will fail
// to update the filesystem! Why are we sharing one across tests, anyway?
EXPECT_TRUE(InMemoryFileSystem->addFile(
TestHeaderName, 0, llvm::MemoryBuffer::getMemBuffer(HeaderCode)));
EXPECT_TRUE(InMemoryFileSystem->addFile(
TestFileName, 0, llvm::MemoryBuffer::getMemBuffer(MainCode)));
Invocation.run();
Symbols = Factory->Collector->takeSymbols();
Refs = Factory->Collector->takeRefs();
Expand Down Expand Up @@ -1788,6 +1790,8 @@ TEST_F(SymbolCollectorTest, Origin) {
runSymbolCollector("class Foo {};", /*Main=*/"");
EXPECT_THAT(Symbols, UnorderedElementsAre(
Field(&Symbol::Origin, SymbolOrigin::Static)));
InMemoryFileSystem = new llvm::vfs::InMemoryFileSystem;
CollectorOpts.CollectMacro = true;
runSymbolCollector("#define FOO", /*Main=*/"");
EXPECT_THAT(Symbols, UnorderedElementsAre(
Field(&Symbol::Origin, SymbolOrigin::Static)));
Expand Down Expand Up @@ -1941,17 +1945,25 @@ TEST_F(SymbolCollectorTest, NoCrashOnObjCMethodCStyleParam) {

TEST_F(SymbolCollectorTest, Reserved) {
const char *Header = R"cpp(
#pragma once
void __foo();
namespace _X { int secret; }
)cpp";

CollectorOpts.CollectReserved = true;
runSymbolCollector("", Header);
runSymbolCollector(Header, "");
EXPECT_THAT(Symbols, UnorderedElementsAre(qName("__foo"), qName("_X"),
qName("_X::secret")));

CollectorOpts.CollectReserved = false;
runSymbolCollector("", Header); //
runSymbolCollector(Header, "");
EXPECT_THAT(Symbols, UnorderedElementsAre(qName("__foo"), qName("_X"),
qName("_X::secret")));

// Ugly: for some reason we reuse the test filesystem across tests.
// You can't overwrite the same filename with new content!
InMemoryFileSystem = new llvm::vfs::InMemoryFileSystem;
runSymbolCollector("#pragma GCC system_header\n" + std::string(Header), "");
EXPECT_THAT(Symbols, IsEmpty());
}

Expand Down

0 comments on commit 290a98c

Please sign in to comment.