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