[PATCH] D45717: [clangd] Using index for GoToDefinition.

Sam McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 23 07:14:59 PDT 2018


sammccall added a comment.

Thanks for the changes! I still find the logic quite confusing. Happy to chat offline if useful.



================
Comment at: clangd/XRefs.cpp:137
+
+IdentifiedSymbol getSymbolAtPosition(ParsedAST &AST, SourceLocation Pos) {
+  auto DeclMacrosFinder = std::make_shared<DeclarationAndMacrosFinder>(
----------------
this is a nice abstraction - consider hiding the DeclarationAndMacrosFinder inside it!


================
Comment at: clangd/XRefs.cpp:215
 
-  indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(),
-                     DeclMacrosFinder, IndexOpts);
+  // Handle goto definition for macros.
+  if (!Symbols.Macros.empty()) {
----------------
So now you're early-out if there are macros.
This means if you have

```
void log(string s) { cout << s; }
#define LOG log
LOG("hello");
```

You'll offer only line 2 as an option, and not line 1.
I'm not sure that's bad, but it's non-obvious - I think it's the thing that the comment should call out.
e.g. "If the cursor is on a macro, go to the macro's definition without trying to resolve the code it expands to"
(The current comment just echoes the code)


================
Comment at: clangd/XRefs.cpp:226
 
-  std::vector<const Decl *> Decls = DeclMacrosFinder->takeDecls();
-  std::vector<MacroDecl> MacroInfos = DeclMacrosFinder->takeMacroInfos();
+  // Handle goto definition for typical declarations.
+  //
----------------
I'm not sure this line adds anything unless you are more specific about what "typical" means, maybe just drop it.

(nit: go to, not goto)


================
Comment at: clangd/XRefs.cpp:233
+  //  - We use the location from AST and index (if available) to provide the
+  //    final results. Prefer AST over index.
+  //
----------------
because it's more up-to-date?


================
Comment at: clangd/XRefs.cpp:235
+  //
+  //  - For each symbol, we will return a location of the cannonical declaration
+  //    (e.g. function declaration in header), and a location of definition if
----------------
nit: canonical


================
Comment at: clangd/XRefs.cpp:237
+  //    (e.g. function declaration in header), and a location of definition if
+  //    they are available, definition comes first.
+  struct CandidateLocation {
----------------
first why?


================
Comment at: clangd/XRefs.cpp:246
+
+  for (auto D : Symbols.Decls) {
+    llvm::SmallString<128> USR;
----------------
nit: the body of this loop handles building the query and getting the AST locations, but they're interleaved in a confusing way - please separate them, or even make these two separate loops.

In the latter case you could put QueryRequest inside the if(Index) block, which would be easier to follow.


================
Comment at: clangd/XRefs.cpp:248
+    llvm::SmallString<128> USR;
+    if (index::generateUSRForDecl(D, USR))
+      continue;
----------------
why are we skipping the AST location if we can't generate a USR?


================
Comment at: clangd/XRefs.cpp:256
+    CandidateLocation &Candidate = ResultCandidates[ID];
+    bool IsDef = GetDefinition(D) == D;
+    // Populate one of the slots with location for the AST.
----------------
why do you not use GetDefinition(D) as the definition, in the case where it's not equal to D?


================
Comment at: clangd/XRefs.cpp:265
+  if (Index) {
+    log("query index...");
+    std::string HintPath;
----------------
remove this log message or make it more useful :-)


================
Comment at: clangd/XRefs.cpp:277
+                    // it.
+                    auto ToLSPLocation = [&HintPath](
+                        const SymbolLocation &Loc) -> llvm::Optional<Location> {
----------------
(The double-nested lambda is somewhat hard to read, can this just be a top-level function? That's what's needed to share it, right?)


================
Comment at: clangd/XRefs.cpp:516
 
   SourceLocation SourceLocationBeg = getBeginningOfIdentifier(AST, Pos, FE);
   auto DeclMacrosFinder = std::make_shared<DeclarationAndMacrosFinder>(
----------------
can you also use `getSymbolAtPosition` here?


================
Comment at: unittests/clangd/XRefsTests.cpp:42
 // FIXME: this is duplicated with FileIndexTests. Share it.
-ParsedAST build(StringRef Code) {
-  auto CI = createInvocationFromCommandLine(
-      {"clang", "-xc++", testPath("Foo.cpp").c_str()});
-  auto Buf = MemoryBuffer::getMemBuffer(Code);
+ParsedAST build(StringRef MainCode, StringRef HeaderCode = "",
+                StringRef BaseName = "Main",
----------------
this is too complicated, please find a way to make it simpler.
Take a look in TestFS.h for the filesystem stuff.


================
Comment at: unittests/clangd/XRefsTests.cpp:43
+ParsedAST build(StringRef MainCode, StringRef HeaderCode = "",
+                StringRef BaseName = "Main",
+                llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem>
----------------
why allow BaseName to be chosen?


================
Comment at: unittests/clangd/XRefsTests.cpp:44
+                StringRef BaseName = "Main",
+                llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem>
+                    InMemoryFileSystem = nullptr) {
----------------
why do you need to pass in the FS? The FS shouldn't need to be the same between the index and AST.


================
Comment at: unittests/clangd/XRefsTests.cpp:52
+  std::vector<const char *> Cmd = {"clang", "-xc++", MainPath.c_str()};
+  if (!HeaderCode.empty()) {
+    InMemoryFileSystem->addFile(HeaderPath, 0,
----------------
why do this conditionally?


================
Comment at: unittests/clangd/XRefsTests.cpp:72
 
+std::unique_ptr<SymbolIndex> buildIndexFromAST(ParsedAST *AST) {
+  SymbolCollector::Options CollectorOpts;
----------------
can we reuse FileIndex instead of reimplementing it?


================
Comment at: unittests/clangd/XRefsTests.cpp:162
+  // Build index.
+  auto IndexAST = build(SymbolCpp.code(), SymbolHeader.code(), "symbol",
+                        InMemoryFileSystem);
----------------
combine these into `buildIndex`? Having multiple ASTs floating around in the test seems confusing...


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45717





More information about the cfe-commits mailing list