Nebiroth updated this revision to Diff 120482.
Nebiroth added a comment.

- Now overriding InclusionDirective as a callback to get proper includes 
information.
- Fixed tests.


https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/Protocol.h
  test/clangd/documenthighlight.test
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===================================================================
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -1056,7 +1055,7 @@
         AddDocument(FileIndex);
 
       Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-      ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+      Server.findDefinitions(FilePaths[FileIndex], Pos);
     };
 
     std::vector<std::function<void()>> AsyncRequests = {
@@ -1185,6 +1184,57 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+
+  ClangdServer Server(CDB, DiagConsumer, FS, 0, clangd::CodeCompleteOptions(),
+                      EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector<Location> Locations = Server.findDefinitions(FooCpp, P).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = URI::unparse(Locations[0].uri);
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = Server.findDefinitions(FooCpp, P3).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = Server.findDefinitions(FooCpp, P2).get().Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: test/clangd/documenthighlight.test
===================================================================
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+# CHECK: Content-Length: 580
+# CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
+# CHECK:   "textDocumentSync": 1,
+# CHECK:   "documentFormattingProvider": true,
+# CHECK:   "documentRangeFormattingProvider": true,
+# CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
+# CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
+# CHECK: }}}
+#
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 16, "character": 4}, "end": {"line": 16, "character": 12}}, "kind": 1},{"range": {"start": {"line": 17, "character": 0}, "end": {"line": 17, "character": 7}}, "kind": 1}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 12, "character": 4}, "end": {"line": 12, "character": 9}}, "kind": 1},{"range": {"start": {"line": 18, "character": 17}, "end": {"line": 18, "character": 21}}, "kind": 1},{"range": {"start": {"line": 19, "character": 4}, "end": {"line": 19, "character": 8}}, "kind": 1}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 4, "character": 5}, "end": {"line": 4, "character": 22}}, "kind": 1},{"range": {"start": {"line": 21, "character": 8}, "end": {"line": 21, "character": 25}}, "kind": 1}]}
+
Index: clangd/Protocol.h
===================================================================
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -96,12 +96,21 @@
   friend bool operator<(const Range &LHS, const Range &RHS) {
     return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end);
   }
-
   static llvm::Optional<Range> parse(llvm::yaml::MappingNode *Params,
                                      clangd::Logger &Logger);
   static std::string unparse(const Range &P);
+
+};
+
+class RangeHash {
+public:
+  std::size_t operator()(const Range &R) const
+  {
+    return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) | ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
 };
 
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/GlobalCompilationDatabase.cpp
===================================================================
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -9,6 +9,7 @@
 
 #include "GlobalCompilationDatabase.h"
 #include "Logger.h"
+#include "ProtocolHandlers.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -30,6 +31,8 @@
   Command.CommandLine.insert(It, ExtraFlags.begin(), ExtraFlags.end());
 }
 
+
+
 tooling::CompileCommand getDefaultCompileCommand(PathRef File) {
   std::vector<std::string> CommandLine{"clang", "-fsyntax-only", File.str()};
   return tooling::CompileCommand(llvm::sys::path::parent_path(File),
Index: clangd/ClangdUnit.h
===================================================================
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -22,6 +22,7 @@
 #include <future>
 #include <memory>
 #include <mutex>
+#include <unordered_map>
 
 namespace llvm {
 class raw_ostream;
@@ -128,11 +129,17 @@
 struct PreambleData {
   PreambleData(PrecompiledPreamble Preamble,
                std::vector<serialization::DeclID> TopLevelDeclIDs,
-               std::vector<DiagWithFixIts> Diags);
+               std::vector<DiagWithFixIts> Diags,
+               std::unordered_map<Range, Path, RangeHash> IncludeMap,
+               std::vector<std::pair<SourceRange, std::string>> DataVector,
+               std::vector<Range> RangeVector);
 
   PrecompiledPreamble Preamble;
   std::vector<serialization::DeclID> TopLevelDeclIDs;
   std::vector<DiagWithFixIts> Diags;
+  std::unordered_map<Range, Path, RangeHash> IncludeMap;
+  std::vector<std::pair<SourceRange, std::string>> DataVector;
+  std::vector<Range> RangeVector;
 };
 
 /// Manages resources, required by clangd. Allows to rebuild file with new
@@ -304,8 +311,11 @@
                             clangd::Logger &Logger);
 
 /// Get definition of symbol at a specified \p Pos.
-std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos,
-                                      clangd::Logger &Logger);
+std::vector<Location>
+findDefinitions(ParsedAST &AST, Position Pos, clangd::Logger &Logger,
+                std::unordered_map<Range, Path, RangeHash> IncludeLocationMap,
+                std::vector<std::pair<SourceRange, std::string>> DataVector,
+                std::vector<Range> RangeVector);
 
 /// For testing/debugging purposes. Note that this method deserializes all
 /// unserialized Decls, so use with care.
Index: clangd/ClangdUnit.cpp
===================================================================
--- clangd/ClangdUnit.cpp
+++ clangd/ClangdUnit.cpp
@@ -30,10 +30,30 @@
 
 #include <algorithm>
 #include <chrono>
+#include <iostream>
 
 using namespace clang::clangd;
 using namespace clang;
 
+class DelegatingPPCallbacks : public PPCallbacks {
+
+public:
+  DelegatingPPCallbacks(PPCallbacks &PPCallbacks) : Callbacks(PPCallbacks) {}
+
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
+    Callbacks.InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
+                                 FilenameRange, File, SearchPath, RelativePath,
+                                 Imported);
+  }
+
+private:
+  PPCallbacks &Callbacks;
+};
+
 namespace {
 
 class DeclTrackingASTConsumer : public ASTConsumer {
@@ -72,12 +92,110 @@
   std::vector<const Decl *> TopLevelDecls;
 };
 
-class CppFilePreambleCallbacks : public PreambleCallbacks {
+std::vector<Range>
+fillRangeVector(const SourceManager &SM,
+                std::vector<std::pair<SourceRange, std::string>> DataVector,
+                std::vector<Range> RangeVector) {
+  if (RangeVector.empty()) {
+    for (unsigned I = 0; I < DataVector.size(); I++) {
+      Position Begin;
+      Begin.line = SM.getSpellingLineNumber(DataVector[I].first.getBegin());
+      Begin.character =
+          SM.getSpellingColumnNumber(DataVector[I].first.getBegin());
+      Position End;
+      End.line = SM.getSpellingLineNumber(DataVector[I].first.getEnd());
+      End.character = SM.getSpellingColumnNumber(DataVector[I].first.getEnd());
+      Range R = {Begin, End};
+      RangeVector.push_back(R);
+    }
+  }
+  return RangeVector;
+}
+
+void findPreambleIncludes(
+    const SourceManager &SM, const LangOptions &LangOpts,
+    std::unordered_map<Range, Path, RangeHash> &IncludeLocationMap,
+    std::vector<std::pair<SourceRange, std::string>> DataVector,
+    std::vector<Range> RangeVector) {
+
+  for (unsigned I = 0; I < DataVector.size(); I++) {
+    if (SM.isInMainFile(DataVector[I].first.getBegin()))
+      IncludeLocationMap.insert({RangeVector[I], DataVector[I].second});
+  }
+}
+
+std::unordered_map<Range, Path, RangeHash> findIncludesOutsidePreamble(
+    const SourceManager &SM, const LangOptions &LangOpts,
+    std::unordered_map<Range, Path, RangeHash> IncludeLocationMap) {
+
+  unsigned NumSlocs = SM.local_sloc_entry_size();
+  SmallVector<SourceLocation, 10> InclusionStack;
+
+  for (unsigned I = 0; I < NumSlocs; ++I) {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &SL = SM.getLocalSLocEntry(I, &Invalid);
+    if (!SL.isFile() || Invalid)
+      continue;
+    const SrcMgr::FileInfo &FI = SL.getFile();
+
+    SourceLocation L = FI.getIncludeLoc();
+    InclusionStack.clear();
+
+    SourceLocation LocationToInsert;
+
+    while (L.isValid()) {
+      PresumedLoc PLoc = SM.getPresumedLoc(L);
+      InclusionStack.push_back(L);
+      L = PLoc.isValid() ? PLoc.getIncludeLoc() : SourceLocation();
+    }
+    if (InclusionStack.size() == 0) {
+      // Skip main file
+      continue;
+    }
+
+    if (InclusionStack.size() > 1) {
+      // Don't care about includes of includes
+      continue;
+    }
+
+    StringRef FilePath = FI.getContentCache()->OrigEntry->tryGetRealPathName();
+    if (FilePath.empty()) {
+      continue;
+    }
+
+    Position Begin;
+    Begin.line = SM.getSpellingLineNumber(InclusionStack.front());
+    Begin.character = SM.getSpellingColumnNumber(InclusionStack.front());
+
+    SourceLocation LocEnd =
+        Lexer::getLocForEndOfToken(InclusionStack.front(), 0, SM, LangOpts);
+
+    Position End;
+    End.line = SM.getSpellingLineNumber(LocEnd);
+    End.character = SM.getSpellingColumnNumber(LocEnd);
+    Range R = {Begin, End};
+    IncludeLocationMap.insert({R, FilePath.str()});
+  }
+
+  return IncludeLocationMap;
+}
+
+class CppFilePreambleCallbacks : public PreambleCallbacks, public PPCallbacks {
 public:
   std::vector<serialization::DeclID> takeTopLevelDeclIDs() {
     return std::move(TopLevelDeclIDs);
   }
 
+  std::unordered_map<Range, Path, RangeHash> takeIncludeLocationMap() {
+    return std::move(IncludeLocationMap);
+  }
+
+  std::vector<std::pair<SourceRange, std::string>> takeDataVector() {
+    return std::move(DataVector);
+  }
+
+  std::vector<Range> takeRangeVector() { return std::move(RangeVector); }
+
   void AfterPCHEmitted(ASTWriter &Writer) override {
     TopLevelDeclIDs.reserve(TopLevelDecls.size());
     for (Decl *D : TopLevelDecls) {
@@ -96,9 +214,29 @@
     }
   }
 
+  void AfterExecute(CompilerInstance &CI) override {
+    RangeVector =
+        fillRangeVector(CI.getSourceManager(), DataVector, RangeVector);
+    findPreambleIncludes(CI.getSourceManager(), CI.getLangOpts(),
+                         IncludeLocationMap, DataVector, RangeVector);
+  }
+
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
+    if (File && !File->tryGetRealPathName().empty())
+      DataVector.push_back(std::pair<SourceRange, std::string>(
+          FilenameRange.getAsRange(), File->tryGetRealPathName()));
+  }
+
 private:
   std::vector<Decl *> TopLevelDecls;
   std::vector<serialization::DeclID> TopLevelDeclIDs;
+  std::vector<std::pair<SourceRange, std::string>> DataVector;
+  std::vector<Range> RangeVector;
+  std::unordered_map<Range, Path, RangeHash> IncludeLocationMap;
 };
 
 /// Convert from clang diagnostic level to LSP severity.
@@ -915,12 +1053,20 @@
   const SourceLocation &SearchedLocation;
   const ASTContext &AST;
   Preprocessor &PP;
+  std::unordered_map<Range, Path, RangeHash> IncludeLocationMap;
+  std::vector<std::pair<SourceRange, std::string>> DataVector;
+  std::vector<Range> RangeVector;
 
 public:
-  DeclarationLocationsFinder(raw_ostream &OS,
-                             const SourceLocation &SearchedLocation,
-                             ASTContext &AST, Preprocessor &PP)
-      : SearchedLocation(SearchedLocation), AST(AST), PP(PP) {}
+  DeclarationLocationsFinder(
+      raw_ostream &OS, const SourceLocation &SearchedLocation, ASTContext &AST,
+      Preprocessor &PP,
+      std::unordered_map<Range, Path, RangeHash> IncludeLocationMap,
+      std::vector<std::pair<SourceRange, std::string>> DataVector,
+      std::vector<Range> RangeVector)
+      : SearchedLocation(SearchedLocation), AST(AST), PP(PP),
+        IncludeLocationMap(IncludeLocationMap), DataVector(DataVector),
+        RangeVector(RangeVector) {}
 
   std::vector<Location> takeLocations() {
     // Don't keep the same location multiple times.
@@ -950,6 +1096,11 @@
            SourceMgr.getFileID(SearchedLocation) == FID;
   }
 
+  bool isSameLine(unsigned Line) const {
+    const SourceManager &SourceMgr = AST.getSourceManager();
+    return Line == SourceMgr.getSpellingLineNumber(SearchedLocation);
+  }
+
   void addDeclarationLocation(const SourceRange &ValSourceRange) {
     const SourceManager &SourceMgr = AST.getSourceManager();
     const LangOptions &LangOpts = AST.getLangOpts();
@@ -963,14 +1114,32 @@
     End.line = SourceMgr.getSpellingLineNumber(LocEnd) - 1;
     End.character = SourceMgr.getSpellingColumnNumber(LocEnd) - 1;
     Range R = {Begin, End};
+    addLocation(URI::fromFile(
+                    SourceMgr.getFilename(SourceMgr.getSpellingLoc(LocStart))),
+                R);
+  }
+
+  void addLocation(URI Uri, Range R) {
+
     Location L;
-    L.uri = URI::fromFile(
-        SourceMgr.getFilename(SourceMgr.getSpellingLoc(LocStart)));
+    L.uri = Uri;
     L.range = R;
     DeclarationLocations.push_back(L);
   }
 
   void finish() override {
+
+    IncludeLocationMap = ::findIncludesOutsidePreamble(
+        AST.getSourceManager(), AST.getLangOpts(), IncludeLocationMap);
+
+    for (auto It = IncludeLocationMap.begin(); It != IncludeLocationMap.end();
+         ++It) {
+      Range R = It->first;
+      Path P = It->second;
+      if (isSameLine(R.start.line))
+        addLocation(URI::fromFile(P), R);
+    }
+
     // Also handle possible macro at the searched location.
     Token Result;
     if (!Lexer::getRawToken(SearchedLocation, Result, AST.getSourceManager(),
@@ -1040,8 +1209,11 @@
 }
 } // namespace
 
-std::vector<Location> clangd::findDefinitions(ParsedAST &AST, Position Pos,
-                                              clangd::Logger &Logger) {
+std::vector<Location> clangd::findDefinitions(
+    ParsedAST &AST, Position Pos, clangd::Logger &Logger,
+    std::unordered_map<Range, Path, RangeHash> IncludeLocationMap,
+    std::vector<std::pair<SourceRange, std::string>> DataVector,
+    std::vector<Range> RangeVector) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
   if (!FE)
@@ -1051,7 +1223,7 @@
 
   auto DeclLocationsFinder = std::make_shared<DeclarationLocationsFinder>(
       llvm::errs(), SourceLocationBeg, AST.getASTContext(),
-      AST.getPreprocessor());
+      AST.getPreprocessor(), IncludeLocationMap, DataVector, RangeVector);
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -1133,11 +1305,17 @@
 ParsedASTWrapper::ParsedASTWrapper(llvm::Optional<ParsedAST> AST)
     : AST(std::move(AST)) {}
 
-PreambleData::PreambleData(PrecompiledPreamble Preamble,
-                           std::vector<serialization::DeclID> TopLevelDeclIDs,
-                           std::vector<DiagWithFixIts> Diags)
+PreambleData::PreambleData(
+    PrecompiledPreamble Preamble,
+    std::vector<serialization::DeclID> TopLevelDeclIDs,
+    std::vector<DiagWithFixIts> Diags,
+    std::unordered_map<Range, Path, RangeHash> IncludeMap,
+    std::vector<std::pair<SourceRange, std::string>> DataVector,
+    std::vector<Range> RangeVector)
     : Preamble(std::move(Preamble)),
-      TopLevelDeclIDs(std::move(TopLevelDeclIDs)), Diags(std::move(Diags)) {}
+      TopLevelDeclIDs(std::move(TopLevelDeclIDs)), Diags(std::move(Diags)),
+      IncludeMap(std::move(IncludeMap)), DataVector(std::move(DataVector)),
+      RangeVector(std::move(RangeVector)) {}
 
 std::shared_ptr<CppFile>
 CppFile::Create(PathRef FileName, tooling::CompileCommand Command,
@@ -1291,15 +1469,20 @@
           CompilerInstance::createDiagnostics(
               &CI->getDiagnosticOpts(), &PreambleDiagnosticsConsumer, false);
       CppFilePreambleCallbacks SerializedDeclsCollector;
+      std::unique_ptr<DelegatingPPCallbacks> DelegatedPPCallbacks =
+          llvm::make_unique<DelegatingPPCallbacks>(SerializedDeclsCollector);
       auto BuiltPreamble = PrecompiledPreamble::Build(
           *CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine, VFS, PCHs,
-          SerializedDeclsCollector);
+          SerializedDeclsCollector, std::move(DelegatedPPCallbacks));
 
       if (BuiltPreamble) {
         return std::make_shared<PreambleData>(
             std::move(*BuiltPreamble),
             SerializedDeclsCollector.takeTopLevelDeclIDs(),
-            std::move(PreambleDiags));
+            std::move(PreambleDiags),
+            SerializedDeclsCollector.takeIncludeLocationMap(),
+            SerializedDeclsCollector.takeDataVector(),
+            SerializedDeclsCollector.takeRangeVector());
       } else {
         return nullptr;
       }
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <future>
+#include <unordered_map>
 
 using namespace clang;
 using namespace clang::clangd;
@@ -364,11 +365,26 @@
         llvm::errc::invalid_argument);
 
   std::vector<Location> Result;
-  Resources->getAST().get()->runUnderLock([Pos, &Result, this](ParsedAST *AST) {
-    if (!AST)
-      return;
-    Result = clangd::findDefinitions(*AST, Pos, Logger);
-  });
+  std::unordered_map<Range, Path, RangeHash> IncludeLocationMap;
+  std::vector<std::pair<SourceRange, std::string>> DataVector;
+  std::vector<Range> RangeVector;
+
+  std::shared_future<std::shared_ptr<const PreambleData>> Preamble =
+      Resources->getPreamble();
+  if (Preamble.get()) {
+    IncludeLocationMap = Preamble.get()->IncludeMap;
+    DataVector = Preamble.get()->DataVector;
+    RangeVector = Preamble.get()->RangeVector;
+  }
+  Resources->getAST().get()->runUnderLock(
+      [Pos, &Result, Preamble, this](ParsedAST *AST) {
+        if (!AST)
+          return;
+
+        Result = clangd::findDefinitions(
+            *AST, Pos, Logger, Preamble.get()->IncludeMap,
+            Preamble.get()->DataVector, Preamble.get()->RangeVector);
+      });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to