kbobyrev created this revision.
kbobyrev added a reviewer: sammccall.
Herald added subscribers: dexonsmith, usaxena95, kadircet, arphaman.
kbobyrev requested review of this revision.
Herald added subscribers: cfe-commits, llvm-commits, MaskRay, ilya-biryukov.
Herald added projects: LLVM, clang-tools-extra.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110925

Files:
  clang-tools-extra/clangd/Headers.cpp
  clang-tools-extra/clangd/Headers.h
  llvm/include/llvm/Support/FileSystem/UniqueID.h

Index: llvm/include/llvm/Support/FileSystem/UniqueID.h
===================================================================
--- llvm/include/llvm/Support/FileSystem/UniqueID.h
+++ llvm/include/llvm/Support/FileSystem/UniqueID.h
@@ -14,7 +14,9 @@
 #ifndef LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
 #define LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
 
+#include "llvm/ADT/DenseMap.h"
 #include <cstdint>
+#include <utility>
 
 namespace llvm {
 namespace sys {
@@ -47,6 +49,31 @@
 
 } // end namespace fs
 } // end namespace sys
+
+// Support UniqueIDs as DenseMap keys.
+template <> struct DenseMapInfo<llvm::sys::fs::UniqueID> {
+  static inline llvm::sys::fs::UniqueID getEmptyKey() {
+    auto EmptyKey = DenseMapInfo<std::pair<unsigned, unsigned>>::getEmptyKey();
+    return {EmptyKey.first, EmptyKey.second};
+  }
+
+  static inline llvm::sys::fs::UniqueID getTombstoneKey() {
+    auto TombstoneKey =
+        DenseMapInfo<std::pair<unsigned, unsigned>>::getTombstoneKey();
+    return {TombstoneKey.first, TombstoneKey.second};
+  }
+
+  static unsigned getHashValue(const llvm::sys::fs::UniqueID &Tag) {
+    return hash_value(
+        std::pair<unsigned, unsigned>(Tag.getDevice(), Tag.getFile()));
+  }
+
+  static bool isEqual(const llvm::sys::fs::UniqueID &LHS,
+                      const llvm::sys::fs::UniqueID &RHS) {
+    return LHS == RHS;
+  }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
Index: clang-tools-extra/clangd/Headers.h
===================================================================
--- clang-tools-extra/clangd/Headers.h
+++ clang-tools-extra/clangd/Headers.h
@@ -14,6 +14,7 @@
 #include "index/Symbol.h"
 #include "support/Logger.h"
 #include "support/Path.h"
+#include "clang/Basic/FileEntry.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/HeaderSearch.h"
@@ -119,6 +120,12 @@
     RealPathNames.emplace_back();
   }
 
+  void setMainFileEntry(const FileEntry *Entry) {
+    assert(Entry && Entry->isValid());
+    assert(!RealPathNames.empty());
+    this->MainFileEntry = Entry;
+  }
+
   // HeaderID identifies file in the include graph. It corresponds to a
   // FileEntry rather than a FileID, but stays stable across preamble & main
   // file builds.
@@ -126,8 +133,7 @@
 
   llvm::Optional<HeaderID> getID(const FileEntry *Entry,
                                  const SourceManager &SM) const;
-  HeaderID getOrCreateID(const FileEntry *Entry,
-                         const SourceManager &SM);
+  HeaderID getOrCreateID(const FileEntry *Entry, const SourceManager &SM);
 
   StringRef getRealPath(HeaderID ID) const {
     assert(static_cast<unsigned>(ID) <= RealPathNames.size());
@@ -141,8 +147,8 @@
   // All transitive includes (absolute paths), with their minimum include depth.
   // Root --> 0, #included file --> 1, etc.
   // Root is the ID of the header being visited first.
-  // Usually it is getID(SM.getFileEntryForID(SM.getMainFileID()), SM).
-  llvm::DenseMap<HeaderID, unsigned> includeDepth(HeaderID Root) const;
+  llvm::DenseMap<HeaderID, unsigned>
+  includeDepth(HeaderID Root = static_cast<HeaderID>(0u)) const;
 
   // Maps HeaderID to the ids of the files included from it.
   llvm::DenseMap<HeaderID, SmallVector<HeaderID>> IncludeChildren;
@@ -150,16 +156,18 @@
   std::vector<Inclusion> MainFileIncludes;
 
 private:
+  const FileEntry *MainFileEntry;
+
   std::vector<std::string> RealPathNames; // In HeaderID order.
-  // HeaderID maps the FileEntry::UniqueID to the internal representation.
+  // FileEntry::UniqueID is mapped to the internal representation (HeaderID).
   // Identifying files in a way that persists from preamble build to subsequent
-  // builds is surprisingly hard. FileID is unavailable in
-  // InclusionDirective(), and RealPathName and UniqueID are not preserved in
+  // builds is surprisingly hard. FileID is unavailable in InclusionDirective(),
+  // and RealPathName and UniqueID are not preserved in
   // the preamble.
   //
-  // We reserve 0 to the main file and will manually check for that in getID
-  // and getOrCreateID because llvm::sys::fs::UniqueID is not stable when their
-  // content of the main file changes.
+  // We reserve HeaderID(0) for the main file and will manually check for that
+  // in getID and getOrCreateID because llvm::sys::fs::UniqueID is not stable
+  // when their content of the main file changes.
   llvm::DenseMap<llvm::sys::fs::UniqueID, HeaderID> UIDToIndex;
 };
 
@@ -228,7 +236,7 @@
 
 namespace llvm {
 
-// Support Tokens as DenseMap keys.
+// Support HeaderIDs as DenseMap keys.
 template <> struct DenseMapInfo<clang::clangd::IncludeStructure::HeaderID> {
   static inline clang::clangd::IncludeStructure::HeaderID getEmptyKey() {
     return static_cast<clang::clangd::IncludeStructure::HeaderID>(
@@ -251,30 +259,6 @@
   }
 };
 
-// Support Tokens as DenseMap keys.
-template <> struct DenseMapInfo<llvm::sys::fs::UniqueID> {
-  static inline llvm::sys::fs::UniqueID getEmptyKey() {
-    auto EmptyKey = DenseMapInfo<std::pair<unsigned, unsigned>>::getEmptyKey();
-    return {EmptyKey.first, EmptyKey.second};
-  }
-
-  static inline llvm::sys::fs::UniqueID getTombstoneKey() {
-    auto TombstoneKey =
-        DenseMapInfo<std::pair<unsigned, unsigned>>::getTombstoneKey();
-    return {TombstoneKey.first, TombstoneKey.second};
-  }
-
-  static unsigned getHashValue(const llvm::sys::fs::UniqueID &Tag) {
-    return hash_value(
-        std::pair<unsigned, unsigned>(Tag.getDevice(), Tag.getFile()));
-  }
-
-  static bool isEqual(const llvm::sys::fs::UniqueID &LHS,
-                      const llvm::sys::fs::UniqueID &RHS) {
-    return LHS == RHS;
-  }
-};
-
 } // namespace llvm
 
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H
Index: clang-tools-extra/clangd/Headers.cpp
===================================================================
--- clang-tools-extra/clangd/Headers.cpp
+++ clang-tools-extra/clangd/Headers.cpp
@@ -152,14 +152,14 @@
 std::unique_ptr<PPCallbacks>
 collectIncludeStructureCallback(const SourceManager &SM,
                                 IncludeStructure *Out) {
+  Out->setMainFileEntry(SM.getFileEntryForID(SM.getMainFileID()));
   return std::make_unique<RecordHeaders>(SM, Out);
 }
 
 llvm::Optional<IncludeStructure::HeaderID>
-IncludeStructure::getID(const FileEntry *Entry,
-                        const SourceManager &SM) const {
+IncludeStructure::getID(const FileEntry *Entry, const SourceManager &SM) const {
   // HeaderID of the main file is always 0;
-  if (SM.getMainFileID() == SM.translateFile(Entry)) {
+  if (Entry == MainFileEntry) {
     return static_cast<IncludeStructure::HeaderID>(0u);
   }
   auto It = UIDToIndex.find(Entry->getUniqueID());
@@ -171,10 +171,10 @@
 IncludeStructure::HeaderID
 IncludeStructure::getOrCreateID(const FileEntry *Entry,
                                 const SourceManager &SM) {
-  // Main file's FileID was not known at IncludeStructure creation time.
-  if (SM.getMainFileID() == SM.translateFile(Entry)) {
-    UIDToIndex[Entry->getUniqueID()] =
-        static_cast<IncludeStructure::HeaderID>(0u);
+  // Main file's FileEntry was not known at IncludeStructure creation time.
+  if (Entry == MainFileEntry) {
+    RealPathNames[0] = MainFileEntry->tryGetRealPathName().str();
+    return static_cast<IncludeStructure::HeaderID>(0u);
   }
   auto R = UIDToIndex.try_emplace(
       Entry->getUniqueID(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to