1 | //===--- HeaderMap.h - A file that acts like dir of symlinks ----*- 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 | // This file defines the HeaderMap interface. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_LEX_HEADERMAP_H |
14 | #define |
15 | |
16 | #include "clang/Basic/FileManager.h" |
17 | #include "clang/Basic/LLVM.h" |
18 | #include "clang/Lex/HeaderMapTypes.h" |
19 | #include "llvm/ADT/StringMap.h" |
20 | #include "llvm/Support/Compiler.h" |
21 | #include "llvm/Support/MemoryBuffer.h" |
22 | #include <memory> |
23 | #include <optional> |
24 | |
25 | namespace clang { |
26 | |
27 | struct HMapBucket; |
28 | struct ; |
29 | |
30 | /// Implementation for \a HeaderMap that doesn't depend on \a FileManager. |
31 | class { |
32 | std::unique_ptr<const llvm::MemoryBuffer> ; |
33 | bool ; |
34 | mutable llvm::StringMap<StringRef> ; |
35 | |
36 | public: |
37 | (std::unique_ptr<const llvm::MemoryBuffer> File, bool NeedsBSwap) |
38 | : FileBuffer(std::move(File)), NeedsBSwap(NeedsBSwap) {} |
39 | |
40 | // Check for a valid header and extract the byte swap. |
41 | static bool (const llvm::MemoryBuffer &File, bool &NeedsByteSwap); |
42 | |
43 | // Make a call for every Key in the map. |
44 | template <typename Func> void (Func Callback) const { |
45 | const HMapHeader &Hdr = getHeader(); |
46 | unsigned NumBuckets = getEndianAdjustedWord(X: Hdr.NumBuckets); |
47 | |
48 | for (unsigned Bucket = 0; Bucket < NumBuckets; ++Bucket) { |
49 | HMapBucket B = getBucket(BucketNo: Bucket); |
50 | if (B.Key != HMAP_EmptyBucketKey) |
51 | if (std::optional<StringRef> Key = getString(StrTabIdx: B.Key)) |
52 | Callback(*Key); |
53 | } |
54 | } |
55 | |
56 | /// If the specified relative filename is located in this HeaderMap return |
57 | /// the filename it is mapped to, otherwise return an empty StringRef. |
58 | StringRef (StringRef Filename, |
59 | SmallVectorImpl<char> &DestPath) const; |
60 | |
61 | /// Return the filename of the headermap. |
62 | StringRef () const; |
63 | |
64 | /// Print the contents of this headermap to stderr. |
65 | void () const; |
66 | |
67 | /// Return key for specifed path. |
68 | StringRef (StringRef DestPath) const; |
69 | |
70 | private: |
71 | unsigned (unsigned X) const; |
72 | const HMapHeader &() const; |
73 | HMapBucket (unsigned BucketNo) const; |
74 | |
75 | /// Look up the specified string in the string table. If the string index is |
76 | /// not valid, return std::nullopt. |
77 | std::optional<StringRef> (unsigned StrTabIdx) const; |
78 | }; |
79 | |
80 | /// This class represents an Apple concept known as a 'header map'. To the |
81 | /// \#include file resolution process, it basically acts like a directory of |
82 | /// symlinks to files. Its advantages are that it is dense and more efficient |
83 | /// to create and process than a directory of symlinks. |
84 | class : private HeaderMapImpl { |
85 | (std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap) |
86 | : HeaderMapImpl(std::move(File), BSwap) {} |
87 | |
88 | public: |
89 | /// This attempts to load the specified file as a header map. If it doesn't |
90 | /// look like a HeaderMap, it gives up and returns null. |
91 | static std::unique_ptr<HeaderMap> (FileEntryRef FE, FileManager &FM); |
92 | |
93 | using HeaderMapImpl::dump; |
94 | using HeaderMapImpl::forEachKey; |
95 | using HeaderMapImpl::getFileName; |
96 | using HeaderMapImpl::lookupFilename; |
97 | using HeaderMapImpl::reverseLookupFilename; |
98 | }; |
99 | |
100 | } // end namespace clang. |
101 | |
102 | #endif |
103 | |