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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits