Skip to content

Commit b06df22

Browse files
committed
[clangd] Follow-up on rGdea48079b90d
Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D110925
1 parent 601168e commit b06df22

File tree

9 files changed

+82
-71
lines changed

9 files changed

+82
-71
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
12031203
loadMainFilePreambleMacros(Clang->getPreprocessor(), Input.Preamble);
12041204
if (Includes)
12051205
Clang->getPreprocessor().addPPCallbacks(
1206-
collectIncludeStructureCallback(Clang->getSourceManager(), Includes));
1206+
Includes->collect(Clang->getSourceManager()));
12071207
if (llvm::Error Err = Action.Execute()) {
12081208
log("Execute() failed when running codeComplete for {0}: {1}",
12091209
Input.FileName, toString(std::move(Err)));
@@ -1380,7 +1380,7 @@ class CodeCompleteFlow {
13801380
const auto &SM = Recorder->CCSema->getSourceManager();
13811381
llvm::StringMap<SourceParams> ProxSources;
13821382
auto MainFileID =
1383-
Includes.getID(SM.getFileEntryForID(SM.getMainFileID()), SM);
1383+
Includes.getID(SM.getFileEntryForID(SM.getMainFileID()));
13841384
assert(MainFileID);
13851385
for (auto &HeaderIDAndDepth : Includes.includeDepth(*MainFileID)) {
13861386
auto &Source =

clang-tools-extra/clangd/Headers.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +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, SM),
71-
IncludedID = Out->getOrCreateID(File, SM);
70+
auto IncludingID = Out->getOrCreateID(IncludingFileEntry),
71+
IncludedID = Out->getOrCreateID(File);
7272
Out->IncludeChildren[IncludingID].push_back(IncludedID);
7373
}
7474
}
@@ -150,16 +150,15 @@ llvm::SmallVector<llvm::StringRef, 1> getRankedIncludes(const Symbol &Sym) {
150150
}
151151

152152
std::unique_ptr<PPCallbacks>
153-
collectIncludeStructureCallback(const SourceManager &SM,
154-
IncludeStructure *Out) {
155-
return std::make_unique<RecordHeaders>(SM, Out);
153+
IncludeStructure::collect(const SourceManager &SM) {
154+
MainFileEntry = SM.getFileEntryForID(SM.getMainFileID());
155+
return std::make_unique<RecordHeaders>(SM, this);
156156
}
157157

158158
llvm::Optional<IncludeStructure::HeaderID>
159-
IncludeStructure::getID(const FileEntry *Entry,
160-
const SourceManager &SM) const {
159+
IncludeStructure::getID(const FileEntry *Entry) const {
161160
// HeaderID of the main file is always 0;
162-
if (SM.getMainFileID() == SM.translateFile(Entry)) {
161+
if (Entry == MainFileEntry) {
163162
return static_cast<IncludeStructure::HeaderID>(0u);
164163
}
165164
auto It = UIDToIndex.find(Entry->getUniqueID());
@@ -169,12 +168,12 @@ IncludeStructure::getID(const FileEntry *Entry,
169168
}
170169

171170
IncludeStructure::HeaderID
172-
IncludeStructure::getOrCreateID(const FileEntry *Entry,
173-
const SourceManager &SM) {
174-
// Main file's FileID was not known at IncludeStructure creation time.
175-
if (SM.getMainFileID() == SM.translateFile(Entry)) {
176-
UIDToIndex[Entry->getUniqueID()] =
177-
static_cast<IncludeStructure::HeaderID>(0u);
171+
IncludeStructure::getOrCreateID(const FileEntry *Entry) {
172+
// Main file's FileEntry was not known at IncludeStructure creation time.
173+
if (Entry == MainFileEntry) {
174+
if (RealPathNames.front().empty())
175+
RealPathNames.front() = MainFileEntry->tryGetRealPathName().str();
176+
return MainFileID;
178177
}
179178
auto R = UIDToIndex.try_emplace(
180179
Entry->getUniqueID(),

clang-tools-extra/clangd/Headers.h

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "index/Symbol.h"
1515
#include "support/Logger.h"
1616
#include "support/Path.h"
17+
#include "clang/Basic/FileEntry.h"
1718
#include "clang/Basic/TokenKinds.h"
1819
#include "clang/Format/Format.h"
1920
#include "clang/Lex/HeaderSearch.h"
@@ -119,15 +120,22 @@ class IncludeStructure {
119120
RealPathNames.emplace_back();
120121
}
121122

123+
// Returns a PPCallback that visits all inclusions in the main file and
124+
// populates the structure.
125+
std::unique_ptr<PPCallbacks> collect(const SourceManager &SM);
126+
127+
void setMainFileEntry(const FileEntry *Entry) {
128+
assert(Entry && Entry->isValid());
129+
this->MainFileEntry = Entry;
130+
}
131+
122132
// HeaderID identifies file in the include graph. It corresponds to a
123133
// FileEntry rather than a FileID, but stays stable across preamble & main
124134
// file builds.
125135
enum class HeaderID : unsigned {};
126136

127-
llvm::Optional<HeaderID> getID(const FileEntry *Entry,
128-
const SourceManager &SM) const;
129-
HeaderID getOrCreateID(const FileEntry *Entry,
130-
const SourceManager &SM);
137+
llvm::Optional<HeaderID> getID(const FileEntry *Entry) const;
138+
HeaderID getOrCreateID(const FileEntry *Entry);
131139

132140
StringRef getRealPath(HeaderID ID) const {
133141
assert(static_cast<unsigned>(ID) <= RealPathNames.size());
@@ -141,32 +149,33 @@ class IncludeStructure {
141149
// All transitive includes (absolute paths), with their minimum include depth.
142150
// Root --> 0, #included file --> 1, etc.
143151
// Root is the ID of the header being visited first.
144-
// Usually it is getID(SM.getFileEntryForID(SM.getMainFileID()), SM).
145-
llvm::DenseMap<HeaderID, unsigned> includeDepth(HeaderID Root) const;
152+
llvm::DenseMap<HeaderID, unsigned>
153+
includeDepth(HeaderID Root = MainFileID) const;
146154

147155
// Maps HeaderID to the ids of the files included from it.
148156
llvm::DenseMap<HeaderID, SmallVector<HeaderID>> IncludeChildren;
149157

150158
std::vector<Inclusion> MainFileIncludes;
151159

160+
// We reserve HeaderID(0) for the main file and will manually check for that
161+
// in getID and getOrCreateID because the UniqueID is not stable when the
162+
// content of the main file changes.
163+
static const HeaderID MainFileID = HeaderID(0u);
164+
152165
private:
166+
// MainFileEntry will be used to check if the queried file is the main file
167+
// or not.
168+
const FileEntry *MainFileEntry = nullptr;
169+
153170
std::vector<std::string> RealPathNames; // In HeaderID order.
154-
// HeaderID maps the FileEntry::UniqueID to the internal representation.
171+
// FileEntry::UniqueID is mapped to the internal representation (HeaderID).
155172
// Identifying files in a way that persists from preamble build to subsequent
156-
// builds is surprisingly hard. FileID is unavailable in
157-
// InclusionDirective(), and RealPathName and UniqueID are not preserved in
173+
// builds is surprisingly hard. FileID is unavailable in InclusionDirective(),
174+
// and RealPathName and UniqueID are not preserved in
158175
// the preamble.
159-
//
160-
// We reserve 0 to the main file and will manually check for that in getID
161-
// and getOrCreateID because llvm::sys::fs::UniqueID is not stable when their
162-
// content of the main file changes.
163176
llvm::DenseMap<llvm::sys::fs::UniqueID, HeaderID> UIDToIndex;
164177
};
165178

166-
/// Returns a PPCallback that visits all inclusions in the main file.
167-
std::unique_ptr<PPCallbacks>
168-
collectIncludeStructureCallback(const SourceManager &SM, IncludeStructure *Out);
169-
170179
// Calculates insertion edit for including a new header in a file.
171180
class IncludeInserter {
172181
public:
@@ -228,7 +237,7 @@ class IncludeInserter {
228237

229238
namespace llvm {
230239

231-
// Support Tokens as DenseMap keys.
240+
// Support HeaderIDs as DenseMap keys.
232241
template <> struct DenseMapInfo<clang::clangd::IncludeStructure::HeaderID> {
233242
static inline clang::clangd::IncludeStructure::HeaderID getEmptyKey() {
234243
return static_cast<clang::clangd::IncludeStructure::HeaderID>(
@@ -251,30 +260,6 @@ template <> struct DenseMapInfo<clang::clangd::IncludeStructure::HeaderID> {
251260
}
252261
};
253262

254-
// Support Tokens as DenseMap keys.
255-
template <> struct DenseMapInfo<llvm::sys::fs::UniqueID> {
256-
static inline llvm::sys::fs::UniqueID getEmptyKey() {
257-
auto EmptyKey = DenseMapInfo<std::pair<unsigned, unsigned>>::getEmptyKey();
258-
return {EmptyKey.first, EmptyKey.second};
259-
}
260-
261-
static inline llvm::sys::fs::UniqueID getTombstoneKey() {
262-
auto TombstoneKey =
263-
DenseMapInfo<std::pair<unsigned, unsigned>>::getTombstoneKey();
264-
return {TombstoneKey.first, TombstoneKey.second};
265-
}
266-
267-
static unsigned getHashValue(const llvm::sys::fs::UniqueID &Tag) {
268-
return hash_value(
269-
std::pair<unsigned, unsigned>(Tag.getDevice(), Tag.getFile()));
270-
}
271-
272-
static bool isEqual(const llvm::sys::fs::UniqueID &LHS,
273-
const llvm::sys::fs::UniqueID &RHS) {
274-
return LHS == RHS;
275-
}
276-
};
277-
278263
} // namespace llvm
279264

280265
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H

clang-tools-extra/clangd/ParsedAST.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
439439
// Otherwise we would collect the replayed includes again...
440440
// (We can't *just* use the replayed includes, they don't have Resolved path).
441441
Clang->getPreprocessor().addPPCallbacks(
442-
collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
442+
Includes.collect(Clang->getSourceManager()));
443443
// Copy over the macros in the preamble region of the main file, and combine
444444
// with non-preamble macros below.
445445
MainFileMacros Macros;

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class CppFilePreambleCallbacks : public PreambleCallbacks {
104104
"SourceMgr and LangOpts must be set at this point");
105105

106106
return std::make_unique<PPChainedCallbacks>(
107-
collectIncludeStructureCallback(*SourceMgr, &Includes),
107+
Includes.collect(*SourceMgr),
108108
std::make_unique<PPChainedCallbacks>(
109109
std::make_unique<CollectMainFileMacros>(*SourceMgr, Macros),
110110
collectPragmaMarksCallback(*SourceMgr, Marks)));
@@ -285,7 +285,7 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) {
285285
const auto &SM = Clang->getSourceManager();
286286
Preprocessor &PP = Clang->getPreprocessor();
287287
IncludeStructure Includes;
288-
PP.addPPCallbacks(collectIncludeStructureCallback(SM, &Includes));
288+
PP.addPPCallbacks(Includes.collect(SM));
289289
ScannedPreamble SP;
290290
SP.Bounds = Bounds;
291291
PP.addPPCallbacks(

clang-tools-extra/clangd/unittests/HeadersTests.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class HeadersTest : public ::testing::Test {
7272
auto &SM = Clang->getSourceManager();
7373
auto Entry = SM.getFileManager().getFile(Filename);
7474
EXPECT_TRUE(Entry);
75-
return Includes.getOrCreateID(*Entry, SM);
75+
return Includes.getOrCreateID(*Entry);
7676
}
7777

7878
IncludeStructure collectIncludes() {
@@ -82,7 +82,7 @@ class HeadersTest : public ::testing::Test {
8282
Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]));
8383
IncludeStructure Includes;
8484
Clang->getPreprocessor().addPPCallbacks(
85-
collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
85+
Includes.collect(Clang->getSourceManager()));
8686
EXPECT_FALSE(Action.Execute());
8787
Action.EndSourceFile();
8888
return Includes;
@@ -180,9 +180,9 @@ TEST_F(HeadersTest, OnlyCollectInclusionsInMain) {
180180
#include "bar.h"
181181
)cpp";
182182
auto Includes = collectIncludes();
183-
EXPECT_THAT(Includes.MainFileIncludes,
184-
UnorderedElementsAre(
185-
AllOf(Written("\"bar.h\""), Resolved(BarHeader))));
183+
EXPECT_THAT(
184+
Includes.MainFileIncludes,
185+
UnorderedElementsAre(AllOf(Written("\"bar.h\""), Resolved(BarHeader))));
186186
EXPECT_THAT(Includes.includeDepth(getID(MainFile, Includes)),
187187
UnorderedElementsAre(Distance(getID(MainFile, Includes), 0u),
188188
Distance(getID(BarHeader, Includes), 1u),

clang-tools-extra/clangd/unittests/ParsedASTTests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,10 +516,10 @@ TEST(ParsedASTTest, PatchesAdditionalIncludes) {
516516
IncludeStructure Includes = PatchedAST->getIncludeStructure();
517517
auto MainFE = FM.getFile(testPath("foo.cpp"));
518518
ASSERT_TRUE(MainFE);
519-
auto MainID = Includes.getID(*MainFE, SM);
519+
auto MainID = Includes.getID(*MainFE);
520520
auto AuxFE = FM.getFile(testPath("sub/aux.h"));
521521
ASSERT_TRUE(AuxFE);
522-
auto AuxID = Includes.getID(*AuxFE, SM);
522+
auto AuxID = Includes.getID(*AuxFE);
523523
EXPECT_THAT(Includes.IncludeChildren[*MainID], Contains(*AuxID));
524524
}
525525

@@ -560,12 +560,12 @@ TEST(ParsedASTTest, PatchesDeletedIncludes) {
560560
IncludeStructure Includes = ExpectedAST.getIncludeStructure();
561561
auto MainFE = FM.getFile(testPath("foo.cpp"));
562562
ASSERT_TRUE(MainFE);
563-
auto MainID = Includes.getOrCreateID(*MainFE, SM);
563+
auto MainID = Includes.getOrCreateID(*MainFE);
564564
auto &PatchedFM = PatchedAST->getSourceManager().getFileManager();
565565
IncludeStructure PatchedIncludes = PatchedAST->getIncludeStructure();
566566
auto PatchedMainFE = PatchedFM.getFile(testPath("foo.cpp"));
567567
ASSERT_TRUE(PatchedMainFE);
568-
auto PatchedMainID = PatchedIncludes.getOrCreateID(*PatchedMainFE, SM);
568+
auto PatchedMainID = PatchedIncludes.getOrCreateID(*PatchedMainFE);
569569
EXPECT_EQ(Includes.includeDepth(MainID)[MainID],
570570
PatchedIncludes.includeDepth(PatchedMainID)[PatchedMainID]);
571571
}

clang-tools-extra/clangd/unittests/PreambleTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ collectPatchedIncludes(llvm::StringRef ModifiedContents,
8383
}
8484
IncludeStructure Includes;
8585
Clang->getPreprocessor().addPPCallbacks(
86-
collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
86+
Includes.collect(Clang->getSourceManager()));
8787
if (llvm::Error Err = Action.Execute()) {
8888
ADD_FAILURE() << "failed to execute action: " << std::move(Err);
8989
return {};

llvm/include/llvm/Support/FileSystem/UniqueID.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#ifndef LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
1515
#define LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
1616

17+
#include "llvm/ADT/DenseMap.h"
1718
#include <cstdint>
19+
#include <utility>
1820

1921
namespace llvm {
2022
namespace sys {
@@ -47,6 +49,31 @@ class UniqueID {
4749

4850
} // end namespace fs
4951
} // end namespace sys
52+
53+
// Support UniqueIDs as DenseMap keys.
54+
template <> struct DenseMapInfo<llvm::sys::fs::UniqueID> {
55+
static inline llvm::sys::fs::UniqueID getEmptyKey() {
56+
auto EmptyKey = DenseMapInfo<std::pair<unsigned, unsigned>>::getEmptyKey();
57+
return {EmptyKey.first, EmptyKey.second};
58+
}
59+
60+
static inline llvm::sys::fs::UniqueID getTombstoneKey() {
61+
auto TombstoneKey =
62+
DenseMapInfo<std::pair<unsigned, unsigned>>::getTombstoneKey();
63+
return {TombstoneKey.first, TombstoneKey.second};
64+
}
65+
66+
static unsigned getHashValue(const llvm::sys::fs::UniqueID &Tag) {
67+
return hash_value(
68+
std::pair<unsigned, unsigned>(Tag.getDevice(), Tag.getFile()));
69+
}
70+
71+
static bool isEqual(const llvm::sys::fs::UniqueID &LHS,
72+
const llvm::sys::fs::UniqueID &RHS) {
73+
return LHS == RHS;
74+
}
75+
};
76+
5077
} // end namespace llvm
5178

5279
#endif // LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H

0 commit comments

Comments
 (0)