1//===--- SerializablePathCollection.h -- 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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_INDEX_SerializablePathCollection_H
10#define LLVM_CLANG_INDEX_SerializablePathCollection_H
11
12#include "clang/Basic/FileManager.h"
13#include "llvm/ADT/APInt.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/Optional.h"
16#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/iterator.h"
20
21#include <string>
22#include <vector>
23
24namespace clang {
25namespace index {
26
27/// Pool of strings
28class StringPool {
29  llvm::SmallString<512> Buffer;
30
31public:
32  struct StringOffsetSize {
33    std::size_t Offset;
34    std::size_t Size;
35
36    StringOffsetSize(size_t Offset, size_t Size) : Offset(Offset), Size(Size) {}
37  };
38
39  StringOffsetSize add(StringRef Str);
40  StringRef getBuffer() const { return Buffer; }
41};
42
43/// Pool of filesystem paths backed by a StringPool
44class PathPool {
45public:
46  /// Special root directory of a filesystem path.
47  enum class RootDirKind {
48    Regular = 0,
49    CurrentWorkDir = 1,
50    SysRoot = 2,
51  };
52
53  struct DirPath {
54    RootDirKind Root;
55    StringPool::StringOffsetSize Path;
56
57    DirPath(RootDirKind Root, const StringPool::StringOffsetSize &Path)
58        : Root(Root), Path(Path) {}
59  };
60
61  struct FilePath {
62    DirPath Dir;
63    StringPool::StringOffsetSize Filename;
64
65    FilePath(const DirPath &Dir, const StringPool::StringOffsetSize &Filename)
66        : Dir(Dir), Filename(Filename) {}
67  };
68
69  /// \returns index of the newly added file in FilePaths.
70  size_t addFilePath(RootDirKind Root, const StringPool::StringOffsetSize &Dir,
71                     StringRef Filename);
72
73  /// \returns offset in Paths and size of newly added directory.
74  StringPool::StringOffsetSize addDirPath(StringRef Dir);
75
76  llvm::ArrayRef<FilePath> getFilePaths() const;
77
78  StringRef getPaths() const;
79
80private:
81  StringPool Paths;
82  std::vector<FilePath> FilePaths;
83};
84
85/// Stores file paths and produces serialization-friendly representation.
86class SerializablePathCollection {
87  std::string WorkDir;
88  std::string SysRoot;
89
90  PathPool Paths;
91  llvm::DenseMap<const clang::FileEntry *, std::size_t> UniqueFiles;
92  llvm::StringMap<PathPool::DirPath, llvm::BumpPtrAllocator> UniqueDirs;
93
94public:
95  const StringPool::StringOffsetSize WorkDirPath;
96  const StringPool::StringOffsetSize SysRootPath;
97  const StringPool::StringOffsetSize OutputFilePath;
98
99  SerializablePathCollection(llvm::StringRef CurrentWorkDir,
100                             llvm::StringRef SysRoot,
101                             llvm::StringRef OutputFile);
102
103  /// \returns buffer containing all the paths.
104  llvm::StringRef getPathsBuffer() const { return Paths.getPaths(); }
105
106  /// \returns file paths (no directories) backed by buffer exposed in
107  /// getPathsBuffer.
108  ArrayRef<PathPool::FilePath> getFilePaths() const {
109    return Paths.getFilePaths();
110  }
111
112  /// Stores path to \p FE if it hasn't been stored yet.
113  /// \returns index to array exposed by getPathsBuffer().
114  size_t tryStoreFilePath(const clang::FileEntry &FE);
115
116private:
117  /// Stores \p Path if it is non-empty.
118  /// Warning: this method doesn't check for uniqueness.
119  /// \returns offset of \p Path value begin in buffer with stored paths.
120  StringPool::StringOffsetSize storePath(llvm::StringRef Path);
121
122  /// Stores \p dirStr path if it hasn't been stored yet.
123  PathPool::DirPath tryStoreDirPath(llvm::StringRef dirStr);
124};
125
126} // namespace index
127} // namespace clang
128
129#endif // LLVM_CLANG_INDEX_SerializablePathCollection_H
130