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