Home | History | Annotate | Line # | Download | only in IndexSerialization
      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 
     24 namespace clang {
     25 namespace index {
     26 
     27 /// Pool of strings
     28 class StringPool {
     29   llvm::SmallString<512> Buffer;
     30 
     31 public:
     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
     44 class PathPool {
     45 public:
     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 
     80 private:
     81   StringPool Paths;
     82   std::vector<FilePath> FilePaths;
     83 };
     84 
     85 /// Stores file paths and produces serialization-friendly representation.
     86 class 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 
     94 public:
     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 
    116 private:
    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