Skip to content

Commit 3f02916

Browse files
[clang][IncludeTree] Update alternative IncludeTreeFS creation API
Update the alternaitive API to create IncludeTreeFileSystem to create directly from a list of `FileEntry`. This skips creating a `FileList` in the CAS, thus save time and CAS usage. (cherry picked from commit 59f62f3)
1 parent db1d216 commit 3f02916

File tree

3 files changed

+65
-56
lines changed

3 files changed

+65
-56
lines changed

clang/include/clang/CAS/IncludeTree.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,13 @@ class IncludeTree::File : public IncludeTreeBase<File> {
239239
static Expected<File> create(ObjectStore &DB, StringRef Filename,
240240
ObjectRef Contents);
241241

242+
static Expected<File> get(ObjectStore &DB, ObjectRef Ref) {
243+
auto Node = DB.getProxy(Ref);
244+
if (!Node)
245+
return Node.takeError();
246+
return File(std::move(*Node));
247+
}
248+
242249
llvm::Error print(llvm::raw_ostream &OS, unsigned Indent = 0);
243250

244251
static bool isValid(const ObjectProxy &Node) {
@@ -305,13 +312,6 @@ class IncludeTree::FileList : public IncludeTreeBase<FileList> {
305312
size_t getNumFilesCurrentList() const;
306313
FileSizeTy getFileSize(size_t I) const;
307314

308-
Expected<File> getFile(ObjectRef Ref) {
309-
auto Node = getCAS().getProxy(Ref);
310-
if (!Node)
311-
return Node.takeError();
312-
return File(std::move(*Node));
313-
}
314-
315315
llvm::Error
316316
forEachFileImpl(llvm::DenseSet<ObjectRef> &Seen,
317317
llvm::function_ref<llvm::Error(File, FileSizeTy)> Callback);
@@ -869,10 +869,11 @@ class IncludeTreeRoot : public IncludeTreeBase<IncludeTreeRoot> {
869869
Expected<IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
870870
createIncludeTreeFileSystem(IncludeTreeRoot &Root);
871871

872-
/// Create the same IncludeTreeFileSystem but from IncludeTree::FileList.
873-
Expected<IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
874-
createIncludeTreeFileSystem(llvm::cas::ObjectStore &CAS,
875-
IncludeTree::FileList &List);
872+
/// Create the same IncludeTreeFileSystem but from
873+
/// ArrayRef<IncludeTree::FileEntry>.
874+
Expected<IntrusiveRefCntPtr<llvm::vfs::FileSystem>> createIncludeTreeFileSystem(
875+
llvm::cas::ObjectStore &CAS,
876+
llvm::ArrayRef<IncludeTree::FileList::FileEntry> List);
876877

877878
} // namespace cas
878879
} // namespace clang

clang/lib/CAS/IncludeTree.cpp

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ llvm::Error IncludeTree::FileList::forEachFileImpl(
257257
return llvm::Error::success();
258258

259259
if (Index < FileCount) {
260-
auto Include = getFile(Ref);
260+
auto Include = File::get(getCAS(), Ref);
261261
if (!Include)
262262
return Include.takeError();
263263
return Callback(std::move(*Include), getFileSize(Index));
@@ -1036,54 +1036,66 @@ cas::createIncludeTreeFileSystem(IncludeTreeRoot &Root) {
10361036
if (!FileList)
10371037
return FileList.takeError();
10381038

1039-
return createIncludeTreeFileSystem(Root.getCAS(), *FileList);
1039+
std::vector<IncludeTree::FileList::FileEntry> Files;
1040+
Files.reserve(FileList->getNumReferences());
1041+
1042+
if (auto Err = FileList->forEachFile(
1043+
[&](IncludeTree::File File, IncludeTree::FileList::FileSizeTy Size) {
1044+
Files.push_back({File.getRef(), Size});
1045+
return llvm::Error::success();
1046+
}))
1047+
return std::move(Err);
1048+
1049+
return createIncludeTreeFileSystem(Root.getCAS(), Files);
10401050
}
10411051

10421052
Expected<IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
1043-
cas::createIncludeTreeFileSystem(llvm::cas::ObjectStore &CAS,
1044-
IncludeTree::FileList &FileList) {
1053+
cas::createIncludeTreeFileSystem(
1054+
llvm::cas::ObjectStore &CAS,
1055+
llvm::ArrayRef<IncludeTree::FileList::FileEntry> List) {
10451056
// Map from FilenameRef to ContentsRef.
10461057
llvm::DenseMap<ObjectRef, ObjectRef> SeenContents;
10471058

10481059
IntrusiveRefCntPtr<IncludeTreeFileSystem> IncludeTreeFS =
10491060
new IncludeTreeFileSystem(CAS);
1050-
llvm::Error E = FileList.forEachFile(
1051-
[&](IncludeTree::File File,
1052-
IncludeTree::FileList::FileSizeTy Size) -> llvm::Error {
1053-
auto InsertPair = SeenContents.insert(
1054-
std::make_pair(File.getFilenameRef(), File.getContentsRef()));
1055-
if (!InsertPair.second) {
1056-
if (InsertPair.first->second != File.getContentsRef())
1057-
return diagnoseFileChange(File, InsertPair.first->second);
1058-
return llvm::Error::success();
1059-
}
1060-
1061-
auto FilenameBlob = File.getFilename();
1062-
if (!FilenameBlob)
1063-
return FilenameBlob.takeError();
1064-
1065-
SmallString<128> Filename(FilenameBlob->getData());
1066-
// Strip './' in the filename to match the behaviour of ASTWriter; we
1067-
// also strip './' in IncludeTreeFileSystem::getPath.
1068-
assert(Filename != ".");
1069-
llvm::sys::path::remove_dots(Filename);
1070-
1071-
StringRef DirName = llvm::sys::path::parent_path(Filename);
1072-
if (DirName.empty())
1073-
DirName = ".";
1074-
auto &DirEntry = IncludeTreeFS->Directories[DirName];
1075-
if (DirEntry == llvm::sys::fs::UniqueID()) {
1076-
DirEntry = llvm::vfs::getNextVirtualUniqueID();
1077-
}
1078-
1079-
IncludeTreeFS->Files.insert(
1080-
std::make_pair(Filename, IncludeTreeFileSystem::FileEntry{
1081-
File.getContentsRef(), Size,
1061+
1062+
for (auto &Entry : List) {
1063+
auto File = IncludeTree::File::get(CAS, Entry.FileRef);
1064+
1065+
if (!File)
1066+
return File.takeError();
1067+
1068+
auto InsertPair = SeenContents.insert(
1069+
std::make_pair(File->getFilenameRef(), File->getContentsRef()));
1070+
if (!InsertPair.second) {
1071+
if (InsertPair.first->second != File->getContentsRef())
1072+
return diagnoseFileChange(*File, InsertPair.first->second);
1073+
continue;
1074+
}
1075+
1076+
auto FilenameBlob = File->getFilename();
1077+
if (!FilenameBlob)
1078+
return FilenameBlob.takeError();
1079+
1080+
SmallString<128> Filename(FilenameBlob->getData());
1081+
// Strip './' in the filename to match the behaviour of ASTWriter; we
1082+
// also strip './' in IncludeTreeFileSystem::getPath.
1083+
assert(Filename != ".");
1084+
llvm::sys::path::remove_dots(Filename);
1085+
1086+
StringRef DirName = llvm::sys::path::parent_path(Filename);
1087+
if (DirName.empty())
1088+
DirName = ".";
1089+
auto &DirEntry = IncludeTreeFS->Directories[DirName];
1090+
if (DirEntry == llvm::sys::fs::UniqueID()) {
1091+
DirEntry = llvm::vfs::getNextVirtualUniqueID();
1092+
}
1093+
1094+
IncludeTreeFS->Files.insert(std::make_pair(
1095+
Filename,
1096+
IncludeTreeFileSystem::FileEntry{File->getContentsRef(), Entry.Size,
10821097
llvm::vfs::getNextVirtualUniqueID()}));
1083-
return llvm::Error::success();
1084-
});
1085-
if (E)
1086-
return std::move(E);
1098+
}
10871099

10881100
return IncludeTreeFS;
10891101
}

clang/unittests/CAS/IncludeTreeTest.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,9 @@ TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
313313
llvm::Succeeded());
314314
Files.push_back({File->getRef(), I});
315315
}
316-
std::optional<IncludeTree::FileList> FileList;
317-
ASSERT_THAT_ERROR(
318-
IncludeTree::FileList::create(*DB, Files, {}).moveInto(FileList),
319-
llvm::Succeeded());
320316
IntrusiveRefCntPtr<llvm::vfs::FileSystem> IncludeTreeFS;
321317
ASSERT_THAT_ERROR(
322-
createIncludeTreeFileSystem(*DB, *FileList).moveInto(IncludeTreeFS),
318+
createIncludeTreeFileSystem(*DB, Files).moveInto(IncludeTreeFS),
323319
llvm::Succeeded());
324320

325321
auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();

0 commit comments

Comments
 (0)