This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Index local classes, virtual and overriding methods.
ClosedPublic

Authored by usaxena95 on Jan 15 2021, 8:23 AM.

Details

Summary

Previously we did not record local class declarations. Now with features like
findImplementation and typeHierarchy, we have a need to index such local
classes to accurately report subclasses and implementations of methods.

Performance testing results:

  • No changes in indexing timing.
  • No significant change in memory usage.
  • 1% increase in #relations.
  • 0.17% increase in #refs.
  • 0.22% increase #symbols.

New index stats
Time to index: 4:13 min
memory usage 543MB
number of symbols: 521.5K
number of refs: 8679K
number of relations: 49K

Base Index stats
Time to index: 4:15 min
memory usage 542MB
number of symbols: 520K
number of refs: 8664K
number of relations: 48.5K

Fixes: https://github.com/clangd/clangd/issues/644

Diff Detail

Event Timeline

usaxena95 created this revision.Jan 15 2021, 8:23 AM
usaxena95 requested review of this revision.Jan 15 2021, 8:23 AM
usaxena95 edited the summary of this revision. (Show Details)Jan 15 2021, 8:41 AM
usaxena95 added a reviewer: hokein.
usaxena95 edited the summary of this revision. (Show Details)

Thank you for taking the time to fix this and the performance measurements to boot.
My only question is does this try and index lambdas, under the hood they are declared as a CXXRecordDecl, defined in function scope?

Added tests for not indexing lambdas.

My only question is does this try and index lambdas, under the hood they are declared as a CXXRecordDecl, defined in function scope?

I would not expect that to happen as it is an anonymous class and we filter those in the beginning of shouldCollectSymbol.
Added tests to test this.

Although now that I enabled this in all SymbolCollectorTests, this causes a regression in RefContainers.

void f2() {
      (void) $ref1a[[f1]](1);
      auto fptr = &$ref1b[[f1]];
    }

&f1 is contained in fptr instead of f2. No immediate ideas why would this happen. Will take a look into this next week.

nridge added a subscriber: nridge.Jan 17 2021, 2:55 PM

Although now that I enabled this in all SymbolCollectorTests, this causes a regression in RefContainers.

void f2() {
      (void) $ref1a[[f1]](1);
      auto fptr = &$ref1b[[f1]];
    }

&f1 is contained in fptr instead of f2. No immediate ideas why would this happen.

I have a theory as to why.

If you look at the next test case in RefContainers:

int $toplevel2[[v1]] = $ref2[[f1]](2);

here, v1 is a global variable, and it is the containing symbol for the reference in the initializer.

So, I think libIndex considers references in initializers to be contained in the declaration of the variable. The reason this didn't happen for local variables until now, is that IndexFunctionLocals was false, and libIndex probably avoids returning non-indexed symbols in ASTNode::Parent.

Although now that I enabled this in all SymbolCollectorTests, this causes a regression in RefContainers.

void f2() {
      (void) $ref1a[[f1]](1);
      auto fptr = &$ref1b[[f1]];
    }

&f1 is contained in fptr instead of f2. No immediate ideas why would this happen.

I have a theory as to why.

If you look at the next test case in RefContainers:

int $toplevel2[[v1]] = $ref2[[f1]](2);

here, v1 is a global variable, and it is the containing symbol for the reference in the initializer.

So, I think libIndex considers references in initializers to be contained in the declaration of the variable. The reason this didn't happen for local variables until now, is that IndexFunctionLocals was false, and libIndex probably avoids returning non-indexed symbols in ASTNode::Parent.

This looks like a bug in libindex -- not sure we should fix that before this patch, I think we can probably live with this, and fix the bug afterwards.

clang-tools-extra/clangd/index/FileIndex.cpp
64–65

Can you add a comment explicitly mentioning that we only index function-local classes and its methods? Without a comment, the reader would expect we index all function-local symbols by just reading this part of code.

clang-tools-extra/clangd/index/SymbolCollector.cpp
223

nit: CollectMainFileSymbols affects the function-local symbols, I think? please update the comments of SymbolCollector::Options::CollectMainFileSymbols.

231

nit: use index::isFunctionLocalSymbol

usaxena95 updated this revision to Diff 317339.Jan 18 2021, 5:46 AM
usaxena95 marked 3 inline comments as done.

Addressed comments. Left a todo to fix the bug in RefContainers later.

mostly good.

I think we'd better bump the index version, even though this is not a breaking change, but we will collect more data. Not bumping the index version may lead to a half-completed state of the index (e.g. only newly-changed files will get completed index data in background index).

clang-tools-extra/clangd/index/SymbolCollector.cpp
227

having a special case here is subtle, I think the reason we need this is to filter out non-virtual methods etc for function-local classes? not sure we should do this, my guess is that we wouldn't save too much, I'd just remove this and index all members for function-local classes.

usaxena95 marked an inline comment as done.Jan 19 2021, 4:25 AM

I think we'd better bump the index version, even though this is not a breaking change, but we will collect more data. Not bumping the index version may lead to a half-completed state of the index (e.g. only newly-changed files will get completed index data in background index).

Yes. Good point. Incremented the version of the index.

usaxena95 updated this revision to Diff 317522.Jan 19 2021, 4:26 AM

Index all member functions instead of only polymorphic functions.

usaxena95 updated this revision to Diff 317525.Jan 19 2021, 4:30 AM

Updated index tests's input files.

hokein accepted this revision.Jan 19 2021, 6:22 AM

Thanks, looks good!

if you don't mind, could you rerun the benchmark (we have a behavior changes from original version, I guess it won't not change significantly)? and update the data in the description before landing.

This revision is now accepted and ready to land.Jan 19 2021, 6:22 AM
usaxena95 edited the summary of this revision. (Show Details)Jan 19 2021, 6:38 AM

if you don't mind, could you rerun the benchmark (we have a behavior changes from original version, I guess it won't not change significantly)? and update the data in the description before landing.

Updated the stats. The stats are still very similar.

usaxena95 edited the summary of this revision. (Show Details)Jan 19 2021, 7:14 AM