aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp b/contrib/llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp
new file mode 100644
index 000000000000..34663738088e
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp
@@ -0,0 +1,91 @@
+//===--- SerializablePathCollection.cpp -- Index of paths -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/IndexSerialization/SerializablePathCollection.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+using namespace clang;
+using namespace clang::index;
+
+StringPool::StringOffsetSize StringPool::add(StringRef Str) {
+ const std::size_t Offset = Buffer.size();
+ Buffer += Str;
+ return StringPool::StringOffsetSize(Offset, Str.size());
+}
+
+size_t PathPool::addFilePath(RootDirKind Root,
+ const StringPool::StringOffsetSize &Dir,
+ StringRef Filename) {
+ FilePaths.emplace_back(DirPath(Root, Dir), Paths.add(Filename));
+ return FilePaths.size() - 1;
+}
+
+StringPool::StringOffsetSize PathPool::addDirPath(StringRef Dir) {
+ return Paths.add(Dir);
+}
+
+llvm::ArrayRef<PathPool::FilePath> PathPool::getFilePaths() const {
+ return FilePaths;
+}
+
+StringRef PathPool::getPaths() const { return Paths.getBuffer(); }
+
+SerializablePathCollection::SerializablePathCollection(
+ StringRef CurrentWorkDir, StringRef SysRoot, llvm::StringRef OutputFile)
+ : WorkDir(CurrentWorkDir),
+ SysRoot(llvm::sys::path::parent_path(SysRoot).empty() ? StringRef()
+ : SysRoot),
+ WorkDirPath(Paths.addDirPath(WorkDir)),
+ SysRootPath(Paths.addDirPath(SysRoot)),
+ OutputFilePath(Paths.addDirPath(OutputFile)) {}
+
+size_t SerializablePathCollection::tryStoreFilePath(const FileEntry &FE) {
+ auto FileIt = UniqueFiles.find(&FE);
+ if (FileIt != UniqueFiles.end())
+ return FileIt->second;
+
+ const auto Dir = tryStoreDirPath(sys::path::parent_path(FE.getName()));
+ const auto FileIdx =
+ Paths.addFilePath(Dir.Root, Dir.Path, sys::path::filename(FE.getName()));
+
+ UniqueFiles.try_emplace(&FE, FileIdx);
+ return FileIdx;
+}
+
+PathPool::DirPath SerializablePathCollection::tryStoreDirPath(StringRef Dir) {
+ // We don't want to strip separator if Dir is "/" - so we check size > 1.
+ while (Dir.size() > 1 && llvm::sys::path::is_separator(Dir.back()))
+ Dir = Dir.drop_back();
+
+ auto DirIt = UniqueDirs.find(Dir);
+ if (DirIt != UniqueDirs.end())
+ return DirIt->second;
+
+ const std::string OrigDir = Dir.str();
+
+ PathPool::RootDirKind Root = PathPool::RootDirKind::Regular;
+ if (!SysRoot.empty() && Dir.startswith(SysRoot) &&
+ llvm::sys::path::is_separator(Dir[SysRoot.size()])) {
+ Root = PathPool::RootDirKind::SysRoot;
+ Dir = Dir.drop_front(SysRoot.size());
+ } else if (!WorkDir.empty() && Dir.startswith(WorkDir) &&
+ llvm::sys::path::is_separator(Dir[WorkDir.size()])) {
+ Root = PathPool::RootDirKind::CurrentWorkDir;
+ Dir = Dir.drop_front(WorkDir.size());
+ }
+
+ if (Root != PathPool::RootDirKind::Regular) {
+ while (!Dir.empty() && llvm::sys::path::is_separator(Dir.front()))
+ Dir = Dir.drop_front();
+ }
+
+ PathPool::DirPath Result(Root, Paths.addDirPath(Dir));
+ UniqueDirs.try_emplace(OrigDir, Result);
+ return Result;
+}