usaxena95 created this revision.
usaxena95 added a reviewer: hokein.
Herald added subscribers: cfe-commits, kadircet, arphaman, jkorous, MaskRay, 
ilya-biryukov.
Herald added a project: clang.

Adds macro references to the dynamic index. 
Tests added.
Also exposed a new API to convert path to URI in URI.h


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71406

Files:
  clang-tools-extra/clangd/URI.cpp
  clang-tools-extra/clangd/URI.h
  clang-tools-extra/clangd/index/FileIndex.cpp
  clang-tools-extra/clangd/index/FileIndex.h
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/clangd/unittests/FileIndexTests.cpp

Index: clang-tools-extra/clangd/unittests/FileIndexTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FileIndexTests.cpp
+++ clang-tools-extra/clangd/unittests/FileIndexTests.cpp
@@ -345,6 +345,41 @@
                              FileURI("unittest:///test2.cc"))}));
 }
 
+TEST(FileIndexTest, MacroRefs) {
+  Annotations HeaderCode(R"cpp(
+    #define $macro[[MACRO]](X) (X+1)
+  )cpp");
+  Annotations MainCode(R"cpp(
+  void f() {
+    int a = $macro[[MACRO]](1);
+  }
+  )cpp");
+
+  auto Macro = findSymbol(
+      TestTU::withHeaderCode(HeaderCode.code()).headerSymbols(), "MACRO");
+  FileIndex Index;
+  // Add test.cc
+  TestTU Test;
+  Test.HeaderCode = HeaderCode.code();
+  Test.Code = MainCode.code();
+  Test.Filename = "test.cc";
+  auto AST = Test.build();
+  Index.updateMain(Test.Filename, AST);
+  // Add test2.cc
+  TestTU Test2;
+  Test2.HeaderCode = HeaderCode.code();
+  Test2.Code = MainCode.code();
+  Test2.Filename = "test2.cc";
+  AST = Test2.build();
+  Index.updateMain(Test2.Filename, AST);
+
+  EXPECT_THAT(getRefs(Index, Macro.ID),
+              RefsAre({AllOf(RefRange(MainCode.range("macro")),
+                             FileURI("unittest:///test.cc")),
+                       AllOf(RefRange(MainCode.range("macro")),
+                             FileURI("unittest:///test2.cc"))}));
+}
+
 TEST(FileIndexTest, CollectMacros) {
   FileIndex M;
   update(M, "f", "#define CLANGD 1");
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -45,31 +45,6 @@
   return ND;
 }
 
-// Returns a URI of \p Path. Firstly, this makes the \p Path absolute using the
-// current working directory of the given SourceManager if the Path is not an
-// absolute path. If failed, this resolves relative paths against \p FallbackDir
-// to get an absolute path. Then, this tries creating an URI for the absolute
-// path with schemes specified in \p Opts. This returns an URI with the first
-// working scheme, if there is any; otherwise, this returns None.
-//
-// The Path can be a path relative to the build directory, or retrieved from
-// the SourceManager.
-std::string toURI(const SourceManager &SM, llvm::StringRef Path,
-                  const SymbolCollector::Options &Opts) {
-  llvm::SmallString<128> AbsolutePath(Path);
-  if (auto File = SM.getFileManager().getFile(Path)) {
-    if (auto CanonPath = getCanonicalPath(*File, SM)) {
-      AbsolutePath = *CanonPath;
-    }
-  }
-  // We don't perform is_absolute check in an else branch because makeAbsolute
-  // might return a relative path on some InMemoryFileSystems.
-  if (!llvm::sys::path::is_absolute(AbsolutePath) && !Opts.FallbackDir.empty())
-    llvm::sys::fs::make_absolute(Opts.FallbackDir, AbsolutePath);
-  llvm::sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true);
-  return URI::create(AbsolutePath).toString();
-}
-
 // All proto generated headers should start with this line.
 static const char *PROTO_HEADER_COMMENT =
     "// Generated by the protocol buffer compiler.  DO NOT EDIT!";
@@ -157,7 +132,7 @@
   auto Path = SM.getFilename(TokLoc);
   if (Path.empty())
     return None;
-  FileURIStorage = toURI(SM, Path, Opts);
+  FileURIStorage = toURI(Path, SM, Opts.FallbackDir).toString();
   SymbolLocation Result;
   Result.FileURI = FileURIStorage.c_str();
   auto Range = getTokenRange(TokLoc, SM, LangOpts);
@@ -517,7 +492,7 @@
     auto Found = URICache.find(FID);
     if (Found == URICache.end()) {
       if (auto *FileEntry = SM.getFileEntryForID(FID)) {
-        auto FileURI = toURI(SM, FileEntry->getName(), Opts);
+        auto FileURI = toURI(FileEntry->getName(), SM, Opts.FallbackDir).toString();
         Found = URICache.insert({FID, FileURI}).first;
       } else {
         // Ignore cases where we can not find a corresponding file entry
@@ -679,7 +654,7 @@
     if (Canonical.startswith("<") || Canonical.startswith("\""))
       return Canonical.str();
     if (Canonical != Filename)
-      return toURI(SM, Canonical, Opts);
+      return toURI(Canonical, SM, Opts.FallbackDir).toString();
   }
   if (!isSelfContainedHeader(FID)) {
     // A .inc or .def file is often included into a real header to define
@@ -690,7 +665,7 @@
     return llvm::None;
   }
   // Standard case: just insert the file itself.
-  return toURI(SM, Filename, Opts);
+  return toURI(Filename, SM, Opts.FallbackDir).toString();
 }
 
 bool SymbolCollector::isSelfContainedHeader(FileID FID) {
Index: clang-tools-extra/clangd/index/FileIndex.h
===================================================================
--- clang-tools-extra/clangd/index/FileIndex.h
+++ clang-tools-extra/clangd/index/FileIndex.h
@@ -140,7 +140,7 @@
 /// Exposed to assist in unit tests.
 SlabTuple indexMainDecls(ParsedAST &AST);
 
-/// Idex declarations from \p AST and macros from \p PP that are declared in
+/// Index declarations from \p AST and macros from \p PP that are declared in
 /// included headers.
 SlabTuple indexHeaderSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
                              const CanonicalIncludes &Includes);
Index: clang-tools-extra/clangd/index/FileIndex.cpp
===================================================================
--- clang-tools-extra/clangd/index/FileIndex.cpp
+++ clang-tools-extra/clangd/index/FileIndex.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "FileIndex.h"
+#include "CollectMacros.h"
 #include "Logger.h"
 #include "ParsedAST.h"
 #include "SymbolCollector.h"
@@ -32,6 +33,7 @@
 
 static SlabTuple indexSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
                               llvm::ArrayRef<Decl *> DeclsToIndex,
+                              const MainFileMacros *MacroRefsToIndex,
                               const CanonicalIncludes &Includes,
                               bool IsIndexMainAST) {
   SymbolCollector::Options CollectorOpts;
@@ -68,6 +70,34 @@
   auto Syms = Collector.takeSymbols();
   auto Refs = Collector.takeRefs();
   auto Relations = Collector.takeRelations();
+
+  if (MacroRefsToIndex && MainFileEntry) {
+    const auto MainFileURI =
+        toURI(MainFileEntry->getName(), SM, CollectorOpts.FallbackDir)
+            .toString();
+    // Copy previous references.
+    RefSlab::Builder RefsBuilder;
+    for (const auto &IDAndRefs : Refs) {
+      for (const auto &Ref : IDAndRefs.second) {
+        RefsBuilder.insert(IDAndRefs.first, Ref);
+      }
+    }
+    // Add macro references.
+    for (const auto &IDToRefs : MacroRefsToIndex->MacroRefs) {
+      for (const auto &Range : IDToRefs.second) {
+        Ref R;
+        R.Location.Start.setLine(Range.start.line);
+        R.Location.Start.setColumn(Range.start.character);
+        R.Location.End.setLine(Range.end.line);
+        R.Location.End.setColumn(Range.end.character);
+        R.Location.FileURI = MainFileURI.c_str();
+        // FIXME: Add correct RefKind information to MainFileMacros.
+        R.Kind = RefKind::Reference;
+        RefsBuilder.insert(IDToRefs.first, R);
+      }
+    }
+    Refs = std::move(RefsBuilder).build();
+  }
   vlog("index AST for {0} (main={1}): \n"
        "  symbol slab: {2} symbols, {3} bytes\n"
        "  ref slab: {4} symbols, {5} refs, {6} bytes\n"
@@ -80,7 +110,8 @@
 
 SlabTuple indexMainDecls(ParsedAST &AST) {
   return indexSymbols(AST.getASTContext(), AST.getPreprocessorPtr(),
-                      AST.getLocalTopLevelDecls(), AST.getCanonicalIncludes(),
+                      AST.getLocalTopLevelDecls(), &AST.getMacros(),
+                      AST.getCanonicalIncludes(),
                       /*IsIndexMainAST=*/true);
 }
 
@@ -89,7 +120,8 @@
   std::vector<Decl *> DeclsToIndex(
       AST.getTranslationUnitDecl()->decls().begin(),
       AST.getTranslationUnitDecl()->decls().end());
-  return indexSymbols(AST, std::move(PP), DeclsToIndex, Includes,
+  return indexSymbols(AST, std::move(PP), DeclsToIndex,
+                      /*MainFileMacros=*/nullptr, Includes,
                       /*IsIndexMainAST=*/false);
 }
 
Index: clang-tools-extra/clangd/URI.h
===================================================================
--- clang-tools-extra/clangd/URI.h
+++ clang-tools-extra/clangd/URI.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PATHURI_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PATHURI_H
 
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Registry.h"
@@ -102,6 +103,18 @@
   std::string Body;
 };
 
+// Returns a URI of \p Path. Firstly, this makes the \p Path absolute using the
+// current working directory of the given SourceManager if the Path is not an
+// absolute path. If failed, this resolves relative paths against \p FallbackDir
+// to get an absolute path. Then, this tries creating an URI for the absolute
+// path with schemes specified in \p Opts. This returns an URI with the first
+// working scheme, if there is any; otherwise, this returns None.
+//
+// The Path can be a path relative to the build directory, or retrieved from
+// the SourceManager.
+URI toURI(llvm::StringRef Path, const SourceManager &SM,
+          const std::string &FallbackDir);
+
 /// URIScheme is an extension point for teaching clangd to recognize a custom
 /// URI scheme. This is expected to be implemented and exposed via the
 /// URISchemeRegistry.
Index: clang-tools-extra/clangd/URI.cpp
===================================================================
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "URI.h"
+#include "SourceCode.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Error.h"
@@ -265,5 +266,21 @@
   return S->get()->getIncludeSpelling(Uri);
 }
 
+URI toURI(llvm::StringRef Path, const SourceManager &SM,
+          const std::string &FallbackDir) {
+  llvm::SmallString<128> AbsolutePath(Path);
+  if (auto File = SM.getFileManager().getFile(Path)) {
+    if (auto CanonPath = getCanonicalPath(*File, SM)) {
+      AbsolutePath = *CanonPath;
+    }
+  }
+  // We don't perform is_absolute check in an else branch because makeAbsolute
+  // might return a relative path on some InMemoryFileSystems.
+  if (!llvm::sys::path::is_absolute(AbsolutePath) && !FallbackDir.empty())
+    llvm::sys::fs::make_absolute(FallbackDir, AbsolutePath);
+  llvm::sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true);
+  return URI::create(AbsolutePath);
+}
+
 } // namespace clangd
 } // namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to