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(const clang::FileEntry &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