summaryrefslogtreecommitdiff
path: root/clang-tools-extra/clangd/Headers.cpp
diff options
context:
space:
mode:
authorKirill Bobyrev <kbobyrev@google.com>2021-09-30 14:41:27 +0200
committerKirill Bobyrev <kbobyrev@google.com>2021-09-30 14:41:27 +0200
commitdea48079b90d40f2087435b778544dffb0ab1793 (patch)
treeb080c43aa9be813e488d993535baae7d667415ff /clang-tools-extra/clangd/Headers.cpp
parent68e56bd320d70470c39ec921bd23dae6836770d7 (diff)
downloadllvm-dea48079b90d40f2087435b778544dffb0ab1793.tar.gz
[clangd] Land D110386 again
This time, use llvm::sys::fs::UniqueID instead of unstable FileEntry::getName(), this should solve the problems on Windows and elsewhere.
Diffstat (limited to 'clang-tools-extra/clangd/Headers.cpp')
-rw-r--r--clang-tools-extra/clangd/Headers.cpp68
1 files changed, 40 insertions, 28 deletions
diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp
index 111b05849b81..ea07e050e938 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -67,8 +67,9 @@ public:
// Treat as if included from the main file.
IncludingFileEntry = SM.getFileEntryForID(MainFID);
}
- Out->recordInclude(IncludingFileEntry->getName(), File->getName(),
- File->tryGetRealPathName());
+ auto IncludingID = Out->getOrCreateID(IncludingFileEntry, SM),
+ IncludedID = Out->getOrCreateID(File, SM);
+ Out->IncludeChildren[IncludingID].push_back(IncludedID);
}
}
@@ -154,38 +155,52 @@ collectIncludeStructureCallback(const SourceManager &SM,
return std::make_unique<RecordHeaders>(SM, Out);
}
-void IncludeStructure::recordInclude(llvm::StringRef IncludingName,
- llvm::StringRef IncludedName,
- llvm::StringRef IncludedRealName) {
- auto Child = fileIndex(IncludedName);
- if (!IncludedRealName.empty() && RealPathNames[Child].empty())
- RealPathNames[Child] = std::string(IncludedRealName);
- auto Parent = fileIndex(IncludingName);
- IncludeChildren[Parent].push_back(Child);
+llvm::Optional<IncludeStructure::HeaderID>
+IncludeStructure::getID(const FileEntry *Entry,
+ const SourceManager &SM) const {
+ // HeaderID of the main file is always 0;
+ if (SM.getMainFileID() == SM.translateFile(Entry)) {
+ return static_cast<IncludeStructure::HeaderID>(0u);
+ }
+ auto It = UIDToIndex.find(Entry->getUniqueID());
+ if (It == UIDToIndex.end())
+ return llvm::None;
+ return It->second;
}
-unsigned IncludeStructure::fileIndex(llvm::StringRef Name) {
- auto R = NameToIndex.try_emplace(Name, RealPathNames.size());
+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);
+ }
+ auto R = UIDToIndex.try_emplace(
+ Entry->getUniqueID(),
+ static_cast<IncludeStructure::HeaderID>(RealPathNames.size()));
if (R.second)
RealPathNames.emplace_back();
- return R.first->getValue();
+ IncludeStructure::HeaderID Result = R.first->getSecond();
+ std::string &RealPathName = RealPathNames[static_cast<unsigned>(Result)];
+ if (RealPathName.empty())
+ RealPathName = Entry->tryGetRealPathName().str();
+ return Result;
}
-llvm::StringMap<unsigned>
-IncludeStructure::includeDepth(llvm::StringRef Root) const {
+llvm::DenseMap<IncludeStructure::HeaderID, unsigned>
+IncludeStructure::includeDepth(HeaderID Root) const {
// Include depth 0 is the main file only.
- llvm::StringMap<unsigned> Result;
+ llvm::DenseMap<HeaderID, unsigned> Result;
+ assert(static_cast<unsigned>(Root) < RealPathNames.size());
Result[Root] = 0;
- std::vector<unsigned> CurrentLevel;
- llvm::DenseSet<unsigned> Seen;
- auto It = NameToIndex.find(Root);
- if (It != NameToIndex.end()) {
- CurrentLevel.push_back(It->second);
- Seen.insert(It->second);
- }
+ std::vector<IncludeStructure::HeaderID> CurrentLevel;
+ CurrentLevel.push_back(Root);
+ llvm::DenseSet<IncludeStructure::HeaderID> Seen;
+ Seen.insert(Root);
// Each round of BFS traversal finds the next depth level.
- std::vector<unsigned> PreviousLevel;
+ std::vector<IncludeStructure::HeaderID> PreviousLevel;
for (unsigned Level = 1; !CurrentLevel.empty(); ++Level) {
PreviousLevel.clear();
PreviousLevel.swap(CurrentLevel);
@@ -193,10 +208,7 @@ IncludeStructure::includeDepth(llvm::StringRef Root) const {
for (const auto &Child : IncludeChildren.lookup(Parent)) {
if (Seen.insert(Child).second) {
CurrentLevel.push_back(Child);
- const auto &Name = RealPathNames[Child];
- // Can't include files if we don't have their real path.
- if (!Name.empty())
- Result[Name] = Level;
+ Result[Child] = Level;
}
}
}