Skip to content

Commit e7a5347

Browse files
committed
Revert "[clangd] Refactor IncludeStructure: use File (unsigned) for most computations"
This reverts - d1c6e54 - 7394d3b - e507711 - 1bcd6b5
1 parent 3d6f49a commit e7a5347

File tree

5 files changed

+96
-192
lines changed

5 files changed

+96
-192
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,16 +1379,14 @@ class CodeCompleteFlow {
13791379
FileDistanceOptions ProxOpts{}; // Use defaults.
13801380
const auto &SM = Recorder->CCSema->getSourceManager();
13811381
llvm::StringMap<SourceParams> ProxSources;
1382-
auto MainFileID =
1383-
Includes.getOrCreateID(SM.getFileEntryForID(SM.getMainFileID()));
1384-
for (auto &HeaderIDAndDepth : Includes.includeDepth(MainFileID)) {
1385-
auto &Source =
1386-
ProxSources[Includes.getRealPath(HeaderIDAndDepth.getFirst())];
1387-
Source.Cost = HeaderIDAndDepth.getSecond() * ProxOpts.IncludeCost;
1382+
for (auto &Entry : Includes.includeDepth(
1383+
SM.getFileEntryForID(SM.getMainFileID())->getName())) {
1384+
auto &Source = ProxSources[Entry.getKey()];
1385+
Source.Cost = Entry.getValue() * ProxOpts.IncludeCost;
13881386
// Symbols near our transitive includes are good, but only consider
13891387
// things in the same directory or below it. Otherwise there can be
13901388
// many false positives.
1391-
if (HeaderIDAndDepth.getSecond() > 0)
1389+
if (Entry.getValue() > 0)
13921390
Source.MaxUpTraversals = 1;
13931391
}
13941392
FileProximity.emplace(ProxSources, ProxOpts);

clang-tools-extra/clangd/Headers.cpp

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,8 @@ class RecordHeaders : public PPCallbacks {
6767
// Treat as if included from the main file.
6868
IncludingFileEntry = SM.getFileEntryForID(MainFID);
6969
}
70-
auto IncludingID = Out->getOrCreateID(IncludingFileEntry),
71-
IncludedID = Out->getOrCreateID(File);
72-
Out->IncludeChildren[IncludingID].push_back(IncludedID);
70+
Out->recordInclude(IncludingFileEntry->getName(), File->getName(),
71+
File->tryGetRealPathName());
7372
}
7473
}
7574

@@ -155,49 +154,49 @@ collectIncludeStructureCallback(const SourceManager &SM,
155154
return std::make_unique<RecordHeaders>(SM, Out);
156155
}
157156

158-
llvm::Optional<IncludeStructure::HeaderID>
159-
IncludeStructure::getID(const FileEntry *Entry) const {
160-
auto It = NameToIndex.find(Entry->getName());
161-
if (It == NameToIndex.end())
162-
return llvm::None;
163-
return It->second;
157+
void IncludeStructure::recordInclude(llvm::StringRef IncludingName,
158+
llvm::StringRef IncludedName,
159+
llvm::StringRef IncludedRealName) {
160+
auto Child = fileIndex(IncludedName);
161+
if (!IncludedRealName.empty() && RealPathNames[Child].empty())
162+
RealPathNames[Child] = std::string(IncludedRealName);
163+
auto Parent = fileIndex(IncludingName);
164+
IncludeChildren[Parent].push_back(Child);
164165
}
165166

166-
IncludeStructure::HeaderID
167-
IncludeStructure::getOrCreateID(const FileEntry *Entry) {
168-
auto R = NameToIndex.try_emplace(
169-
Entry->getName(),
170-
static_cast<IncludeStructure::HeaderID>(RealPathNames.size()));
167+
unsigned IncludeStructure::fileIndex(llvm::StringRef Name) {
168+
auto R = NameToIndex.try_emplace(Name, RealPathNames.size());
171169
if (R.second)
172170
RealPathNames.emplace_back();
173-
IncludeStructure::HeaderID Result = R.first->getValue();
174-
std::string &RealPathName = RealPathNames[static_cast<unsigned>(Result)];
175-
if (RealPathName.empty())
176-
RealPathName = Entry->tryGetRealPathName().str();
177-
return Result;
171+
return R.first->getValue();
178172
}
179173

180-
llvm::DenseMap<IncludeStructure::HeaderID, unsigned>
181-
IncludeStructure::includeDepth(HeaderID Root) const {
174+
llvm::StringMap<unsigned>
175+
IncludeStructure::includeDepth(llvm::StringRef Root) const {
182176
// Include depth 0 is the main file only.
183-
llvm::DenseMap<HeaderID, unsigned> Result;
184-
assert(static_cast<unsigned>(Root) < RealPathNames.size());
177+
llvm::StringMap<unsigned> Result;
185178
Result[Root] = 0;
186-
std::vector<IncludeStructure::HeaderID> CurrentLevel;
187-
CurrentLevel.push_back(Root);
188-
llvm::DenseSet<IncludeStructure::HeaderID> Seen;
189-
Seen.insert(Root);
179+
std::vector<unsigned> CurrentLevel;
180+
llvm::DenseSet<unsigned> Seen;
181+
auto It = NameToIndex.find(Root);
182+
if (It != NameToIndex.end()) {
183+
CurrentLevel.push_back(It->second);
184+
Seen.insert(It->second);
185+
}
190186

191187
// Each round of BFS traversal finds the next depth level.
192-
std::vector<IncludeStructure::HeaderID> PreviousLevel;
188+
std::vector<unsigned> PreviousLevel;
193189
for (unsigned Level = 1; !CurrentLevel.empty(); ++Level) {
194190
PreviousLevel.clear();
195191
PreviousLevel.swap(CurrentLevel);
196192
for (const auto &Parent : PreviousLevel) {
197193
for (const auto &Child : IncludeChildren.lookup(Parent)) {
198194
if (Seen.insert(Child).second) {
199195
CurrentLevel.push_back(Child);
200-
Result[Child] = Level;
196+
const auto &Name = RealPathNames[Child];
197+
// Can't include files if we don't have their real path.
198+
if (!Name.empty())
199+
Result[Name] = Level;
201200
}
202201
}
203202
}

clang-tools-extra/clangd/Headers.h

Lines changed: 18 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
#include "Protocol.h"
1313
#include "SourceCode.h"
1414
#include "index/Symbol.h"
15-
#include "support/Logger.h"
1615
#include "support/Path.h"
1716
#include "clang/Basic/TokenKinds.h"
1817
#include "clang/Format/Format.h"
1918
#include "clang/Lex/HeaderSearch.h"
2019
#include "clang/Lex/PPCallbacks.h"
2120
#include "clang/Tooling/Inclusions/HeaderIncludes.h"
2221
#include "llvm/ADT/ArrayRef.h"
23-
#include "llvm/ADT/StringExtras.h"
2422
#include "llvm/ADT/StringRef.h"
2523
#include "llvm/ADT/StringSet.h"
2624
#include "llvm/Support/Error.h"
@@ -64,7 +62,7 @@ struct Inclusion {
6462
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Inclusion &);
6563
bool operator==(const Inclusion &LHS, const Inclusion &RHS);
6664

67-
// Contains information about one file in the build graph and its direct
65+
// Contains information about one file in the build grpah and its direct
6866
// dependencies. Doesn't own the strings it references (IncludeGraph is
6967
// self-contained).
7068
struct IncludeGraphNode {
@@ -114,54 +112,34 @@ operator|=(IncludeGraphNode::SourceFlag &A, IncludeGraphNode::SourceFlag B) {
114112
// in any non-preamble inclusions.
115113
class IncludeStructure {
116114
public:
117-
// HeaderID identifies file in the include graph. It corresponds to a
118-
// FileEntry rather than a FileID, but stays stable across preamble & main
119-
// file builds.
120-
enum class HeaderID : unsigned {};
121-
122-
llvm::Optional<HeaderID> getID(const FileEntry *Entry) const;
123-
HeaderID getOrCreateID(const FileEntry *Entry);
124-
125-
StringRef getRealPath(HeaderID ID) const {
126-
assert(static_cast<unsigned>(ID) <= RealPathNames.size());
127-
return RealPathNames[static_cast<unsigned>(ID)];
128-
}
115+
std::vector<Inclusion> MainFileIncludes;
129116

130117
// Return all transitively reachable files.
131118
llvm::ArrayRef<std::string> allHeaders() const { return RealPathNames; }
132119

133120
// Return all transitively reachable files, and their minimum include depth.
134121
// All transitive includes (absolute paths), with their minimum include depth.
135122
// Root --> 0, #included file --> 1, etc.
136-
// Root is the ID of the header being visited first.
137-
// Usually it is getID(SM.getFileEntryForID(SM.getMainFileID())->getName()).
138-
llvm::DenseMap<HeaderID, unsigned> includeDepth(HeaderID Root) const;
123+
// Root is clang's name for a file, which may not be absolute.
124+
// Usually it should be SM.getFileEntryForID(SM.getMainFileID())->getName().
125+
llvm::StringMap<unsigned> includeDepth(llvm::StringRef Root) const;
139126

140-
// Maps HeaderID to the ids of the files included from it.
141-
llvm::DenseMap<HeaderID, SmallVector<HeaderID>> IncludeChildren;
142-
143-
std::vector<Inclusion> MainFileIncludes;
144-
145-
std::string dump() {
146-
std::string Result =
147-
"RealPathNames: " +
148-
llvm::join(RealPathNames.begin(), RealPathNames.end(), ", ");
149-
Result += "; NameToIndex: ";
150-
for (const auto &NameIndex : NameToIndex) {
151-
Result += NameIndex.first().str() + ' ' +
152-
std::to_string(static_cast<unsigned>(NameIndex.second)) + ", ";
153-
}
154-
return Result;
155-
}
127+
// This updates IncludeDepth(), but not MainFileIncludes.
128+
void recordInclude(llvm::StringRef IncludingName,
129+
llvm::StringRef IncludedName,
130+
llvm::StringRef IncludedRealName);
156131

157132
private:
158-
std::vector<std::string> RealPathNames; // In HeaderID order.
159-
// HeaderID maps the FileEntry::Name to the internal representation.
160133
// Identifying files in a way that persists from preamble build to subsequent
161-
// builds is surprisingly hard. FileID is unavailable in
162-
// InclusionDirective(), and RealPathName and UniqueID are not preserved in
163-
// the preamble.
164-
llvm::StringMap<HeaderID> NameToIndex;
134+
// builds is surprisingly hard. FileID is unavailable in InclusionDirective(),
135+
// and RealPathName and UniqueID are not preserved in the preamble.
136+
// We use the FileEntry::Name, which is stable, interned into a "file index".
137+
// The paths we want to expose are the RealPathName, so store those too.
138+
std::vector<std::string> RealPathNames; // In file index order.
139+
unsigned fileIndex(llvm::StringRef Name);
140+
llvm::StringMap<unsigned> NameToIndex; // Values are file indexes.
141+
// Maps a file's index to that of the files it includes.
142+
llvm::DenseMap<unsigned, llvm::SmallVector<unsigned>> IncludeChildren;
165143
};
166144

167145
/// Returns a PPCallback that visits all inclusions in the main file.
@@ -227,31 +205,4 @@ class IncludeInserter {
227205
} // namespace clangd
228206
} // namespace clang
229207

230-
namespace llvm {
231-
232-
// Support Tokens as DenseMap keys.
233-
template <> struct DenseMapInfo<clang::clangd::IncludeStructure::HeaderID> {
234-
static inline clang::clangd::IncludeStructure::HeaderID getEmptyKey() {
235-
return static_cast<clang::clangd::IncludeStructure::HeaderID>(
236-
DenseMapInfo<unsigned>::getEmptyKey());
237-
}
238-
239-
static inline clang::clangd::IncludeStructure::HeaderID getTombstoneKey() {
240-
return static_cast<clang::clangd::IncludeStructure::HeaderID>(
241-
DenseMapInfo<unsigned>::getTombstoneKey());
242-
}
243-
244-
static unsigned
245-
getHashValue(const clang::clangd::IncludeStructure::HeaderID &Tag) {
246-
return hash_value(static_cast<unsigned>(Tag));
247-
}
248-
249-
static bool isEqual(const clang::clangd::IncludeStructure::HeaderID &LHS,
250-
const clang::clangd::IncludeStructure::HeaderID &RHS) {
251-
return LHS == RHS;
252-
}
253-
};
254-
255-
} // namespace llvm
256-
257208
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H

0 commit comments

Comments
 (0)