92 lines · cpp
1//===--- SerializablePathCollection.cpp -- Index of paths -------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/IndexSerialization/SerializablePathCollection.h"10#include "llvm/Support/Path.h"11 12using namespace llvm;13using namespace clang;14using namespace clang::index;15 16StringPool::StringOffsetSize StringPool::add(StringRef Str) {17 const std::size_t Offset = Buffer.size();18 Buffer += Str;19 return StringPool::StringOffsetSize(Offset, Str.size());20}21 22size_t PathPool::addFilePath(RootDirKind Root,23 const StringPool::StringOffsetSize &Dir,24 StringRef Filename) {25 FilePaths.emplace_back(DirPath(Root, Dir), Paths.add(Filename));26 return FilePaths.size() - 1;27}28 29StringPool::StringOffsetSize PathPool::addDirPath(StringRef Dir) {30 return Paths.add(Dir);31}32 33llvm::ArrayRef<PathPool::FilePath> PathPool::getFilePaths() const {34 return FilePaths;35}36 37StringRef PathPool::getPaths() const { return Paths.getBuffer(); }38 39SerializablePathCollection::SerializablePathCollection(40 StringRef CurrentWorkDir, StringRef SysRoot, llvm::StringRef OutputFile)41 : WorkDir(CurrentWorkDir),42 SysRoot(llvm::sys::path::parent_path(SysRoot).empty() ? StringRef()43 : SysRoot),44 WorkDirPath(Paths.addDirPath(WorkDir)),45 SysRootPath(Paths.addDirPath(SysRoot)),46 OutputFilePath(Paths.addDirPath(OutputFile)) {}47 48size_t SerializablePathCollection::tryStoreFilePath(FileEntryRef FE) {49 auto FileIt = UniqueFiles.find(FE);50 if (FileIt != UniqueFiles.end())51 return FileIt->second;52 53 const auto Dir = tryStoreDirPath(sys::path::parent_path(FE.getName()));54 const auto FileIdx =55 Paths.addFilePath(Dir.Root, Dir.Path, sys::path::filename(FE.getName()));56 57 UniqueFiles.try_emplace(FE, FileIdx);58 return FileIdx;59}60 61PathPool::DirPath SerializablePathCollection::tryStoreDirPath(StringRef Dir) {62 // We don't want to strip separator if Dir is "/" - so we check size > 1.63 while (Dir.size() > 1 && llvm::sys::path::is_separator(Dir.back()))64 Dir = Dir.drop_back();65 66 auto DirIt = UniqueDirs.find(Dir);67 if (DirIt != UniqueDirs.end())68 return DirIt->second;69 70 const std::string OrigDir = Dir.str();71 72 PathPool::RootDirKind Root = PathPool::RootDirKind::Regular;73 if (!SysRoot.empty() && Dir.starts_with(SysRoot) &&74 llvm::sys::path::is_separator(Dir[SysRoot.size()])) {75 Root = PathPool::RootDirKind::SysRoot;76 Dir = Dir.drop_front(SysRoot.size());77 } else if (!WorkDir.empty() && Dir.starts_with(WorkDir) &&78 llvm::sys::path::is_separator(Dir[WorkDir.size()])) {79 Root = PathPool::RootDirKind::CurrentWorkDir;80 Dir = Dir.drop_front(WorkDir.size());81 }82 83 if (Root != PathPool::RootDirKind::Regular) {84 while (!Dir.empty() && llvm::sys::path::is_separator(Dir.front()))85 Dir = Dir.drop_front();86 }87 88 PathPool::DirPath Result(Root, Paths.addDirPath(Dir));89 UniqueDirs.try_emplace(OrigDir, Result);90 return Result;91}92