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