xref: /llvm-project/clang/lib/IndexSerialization/SerializablePathCollection.cpp (revision f3dcc2351cff7b26c9870d737e5d431551542d9e)
14da126c3SJan Korous //===--- SerializablePathCollection.cpp -- Index of paths -------*- C++ -*-===//
24da126c3SJan Korous //
34da126c3SJan Korous // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44da126c3SJan Korous // See https://llvm.org/LICENSE.txt for license information.
54da126c3SJan Korous // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64da126c3SJan Korous //
74da126c3SJan Korous //===----------------------------------------------------------------------===//
84da126c3SJan Korous 
94da126c3SJan Korous #include "clang/IndexSerialization/SerializablePathCollection.h"
104da126c3SJan Korous #include "llvm/Support/Path.h"
114da126c3SJan Korous 
124da126c3SJan Korous using namespace llvm;
134da126c3SJan Korous using namespace clang;
144da126c3SJan Korous using namespace clang::index;
154da126c3SJan Korous 
add(StringRef Str)164da126c3SJan Korous StringPool::StringOffsetSize StringPool::add(StringRef Str) {
174da126c3SJan Korous   const std::size_t Offset = Buffer.size();
184da126c3SJan Korous   Buffer += Str;
194da126c3SJan Korous   return StringPool::StringOffsetSize(Offset, Str.size());
204da126c3SJan Korous }
214da126c3SJan Korous 
addFilePath(RootDirKind Root,const StringPool::StringOffsetSize & Dir,StringRef Filename)224da126c3SJan Korous size_t PathPool::addFilePath(RootDirKind Root,
234da126c3SJan Korous                              const StringPool::StringOffsetSize &Dir,
244da126c3SJan Korous                              StringRef Filename) {
254da126c3SJan Korous   FilePaths.emplace_back(DirPath(Root, Dir), Paths.add(Filename));
264da126c3SJan Korous   return FilePaths.size() - 1;
274da126c3SJan Korous }
284da126c3SJan Korous 
addDirPath(StringRef Dir)294da126c3SJan Korous StringPool::StringOffsetSize PathPool::addDirPath(StringRef Dir) {
304da126c3SJan Korous   return Paths.add(Dir);
314da126c3SJan Korous }
324da126c3SJan Korous 
getFilePaths() const334da126c3SJan Korous llvm::ArrayRef<PathPool::FilePath> PathPool::getFilePaths() const {
344da126c3SJan Korous   return FilePaths;
354da126c3SJan Korous }
364da126c3SJan Korous 
getPaths() const374da126c3SJan Korous StringRef PathPool::getPaths() const { return Paths.getBuffer(); }
384da126c3SJan Korous 
SerializablePathCollection(StringRef CurrentWorkDir,StringRef SysRoot,llvm::StringRef OutputFile)394da126c3SJan Korous SerializablePathCollection::SerializablePathCollection(
404da126c3SJan Korous     StringRef CurrentWorkDir, StringRef SysRoot, llvm::StringRef OutputFile)
414da126c3SJan Korous     : WorkDir(CurrentWorkDir),
424da126c3SJan Korous       SysRoot(llvm::sys::path::parent_path(SysRoot).empty() ? StringRef()
434da126c3SJan Korous                                                             : SysRoot),
444da126c3SJan Korous       WorkDirPath(Paths.addDirPath(WorkDir)),
454da126c3SJan Korous       SysRootPath(Paths.addDirPath(SysRoot)),
464da126c3SJan Korous       OutputFilePath(Paths.addDirPath(OutputFile)) {}
474da126c3SJan Korous 
tryStoreFilePath(FileEntryRef FE)48f1c08eebSJan Svoboda size_t SerializablePathCollection::tryStoreFilePath(FileEntryRef FE) {
49f1c08eebSJan Svoboda   auto FileIt = UniqueFiles.find(FE);
504da126c3SJan Korous   if (FileIt != UniqueFiles.end())
514da126c3SJan Korous     return FileIt->second;
524da126c3SJan Korous 
534da126c3SJan Korous   const auto Dir = tryStoreDirPath(sys::path::parent_path(FE.getName()));
544da126c3SJan Korous   const auto FileIdx =
554da126c3SJan Korous       Paths.addFilePath(Dir.Root, Dir.Path, sys::path::filename(FE.getName()));
564da126c3SJan Korous 
57f1c08eebSJan Svoboda   UniqueFiles.try_emplace(FE, FileIdx);
584da126c3SJan Korous   return FileIdx;
594da126c3SJan Korous }
604da126c3SJan Korous 
tryStoreDirPath(StringRef Dir)614da126c3SJan Korous PathPool::DirPath SerializablePathCollection::tryStoreDirPath(StringRef Dir) {
624da126c3SJan Korous   // We don't want to strip separator if Dir is "/" - so we check size > 1.
634da126c3SJan Korous   while (Dir.size() > 1 && llvm::sys::path::is_separator(Dir.back()))
644da126c3SJan Korous     Dir = Dir.drop_back();
654da126c3SJan Korous 
664da126c3SJan Korous   auto DirIt = UniqueDirs.find(Dir);
674da126c3SJan Korous   if (DirIt != UniqueDirs.end())
684da126c3SJan Korous     return DirIt->second;
694da126c3SJan Korous 
704da126c3SJan Korous   const std::string OrigDir = Dir.str();
714da126c3SJan Korous 
724da126c3SJan Korous   PathPool::RootDirKind Root = PathPool::RootDirKind::Regular;
73*f3dcc235SKazu Hirata   if (!SysRoot.empty() && Dir.starts_with(SysRoot) &&
744da126c3SJan Korous       llvm::sys::path::is_separator(Dir[SysRoot.size()])) {
754da126c3SJan Korous     Root = PathPool::RootDirKind::SysRoot;
764da126c3SJan Korous     Dir = Dir.drop_front(SysRoot.size());
77*f3dcc235SKazu Hirata   } else if (!WorkDir.empty() && Dir.starts_with(WorkDir) &&
784da126c3SJan Korous              llvm::sys::path::is_separator(Dir[WorkDir.size()])) {
794da126c3SJan Korous     Root = PathPool::RootDirKind::CurrentWorkDir;
804da126c3SJan Korous     Dir = Dir.drop_front(WorkDir.size());
814da126c3SJan Korous   }
824da126c3SJan Korous 
834da126c3SJan Korous   if (Root != PathPool::RootDirKind::Regular) {
844da126c3SJan Korous     while (!Dir.empty() && llvm::sys::path::is_separator(Dir.front()))
854da126c3SJan Korous       Dir = Dir.drop_front();
864da126c3SJan Korous   }
874da126c3SJan Korous 
884da126c3SJan Korous   PathPool::DirPath Result(Root, Paths.addDirPath(Dir));
894da126c3SJan Korous   UniqueDirs.try_emplace(OrigDir, Result);
904da126c3SJan Korous   return Result;
914da126c3SJan Korous }
92