17#include "llvm/Support/Compiler.h"
18#include "llvm/Support/Debug.h"
19#include "llvm/Support/MathExtras.h"
20#include "llvm/Support/MemoryBuffer.h"
31 const char *S = Str.begin(), *End = Str.end();
50 unsigned FileSize = FE.
getSize();
51 if (FileSize <=
sizeof(
HMapHeader))
return nullptr;
57 if (!FileBuffer || !*FileBuffer)
62 return std::unique_ptr<HeaderMap>(
new HeaderMap(std::move(*FileBuffer), NeedsByteSwap));
66 bool &NeedsByteSwap) {
69 const char *FileStart =
File.getBufferStart();
78 NeedsByteSwap =
false;
91 NeedsByteSwap ? llvm::byteswap(Header->
NumBuckets) : Header->NumBuckets;
92 if (!llvm::isPowerOf2_32(NumBuckets))
94 if (
File.getBufferSize() <
109 return FileBuffer->getBufferIdentifier();
112unsigned HeaderMapImpl::getEndianAdjustedWord(
unsigned X)
const {
113 if (!NeedsBSwap)
return X;
114 return llvm::byteswap<uint32_t>(
X);
119const HMapHeader &HeaderMapImpl::getHeader()
const {
121 return *
reinterpret_cast<const HMapHeader*
>(FileBuffer->getBufferStart());
127HMapBucket HeaderMapImpl::getBucket(
unsigned BucketNo)
const {
128 assert(FileBuffer->getBufferSize() >=
130 "Expected bucket to be in range");
136 reinterpret_cast<const HMapBucket*
>(FileBuffer->getBufferStart() +
138 const HMapBucket *BucketPtr = BucketArray+BucketNo;
141 Result.Key = getEndianAdjustedWord(BucketPtr->
Key);
142 Result.Prefix = getEndianAdjustedWord(BucketPtr->
Prefix);
143 Result.Suffix = getEndianAdjustedWord(BucketPtr->
Suffix);
147std::optional<StringRef> HeaderMapImpl::getString(
unsigned StrTabIdx)
const {
149 StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);
152 if (StrTabIdx >= FileBuffer->getBufferSize())
155 const char *
Data = FileBuffer->getBufferStart() + StrTabIdx;
156 unsigned MaxLen = FileBuffer->getBufferSize() - StrTabIdx;
161 unsigned Len = strnlen(
Data, MaxLen);
164 if (Len == MaxLen &&
Data[Len - 1])
167 return StringRef(
Data, Len);
177 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
179 llvm::dbgs() <<
"Header Map " <<
getFileName() <<
":\n " << NumBuckets
180 <<
", " << getEndianAdjustedWord(Hdr.
NumEntries) <<
"\n";
182 auto getStringOrInvalid = [
this](
unsigned Id) -> StringRef {
183 if (std::optional<StringRef> S = getString(
Id))
188 for (
unsigned i = 0; i != NumBuckets; ++i) {
192 StringRef Key = getStringOrInvalid(B.
Key);
193 StringRef Prefix = getStringOrInvalid(B.
Prefix);
194 StringRef Suffix = getStringOrInvalid(B.
Suffix);
195 llvm::dbgs() <<
" " << i <<
". " << Key <<
" -> '" << Prefix <<
"' '"
203 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
206 assert(llvm::isPowerOf2_32(NumBuckets) &&
"Expected power of 2");
210 HMapBucket B = getBucket(Bucket & (NumBuckets-1));
214 std::optional<StringRef> Key = getString(B.
Key);
215 if (LLVM_UNLIKELY(!Key))
217 if (!
Filename.equals_insensitive(*Key))
222 std::optional<StringRef> Prefix = getString(B.
Prefix);
223 std::optional<StringRef> Suffix = getString(B.
Suffix);
226 if (LLVM_LIKELY(Prefix && Suffix)) {
227 DestPath.append(Prefix->begin(), Prefix->end());
228 DestPath.append(Suffix->begin(), Suffix->end());
230 return StringRef(DestPath.begin(), DestPath.size());
235 if (!ReverseMap.empty())
236 return ReverseMap.lookup(DestPath);
239 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
241 for (
unsigned i = 0; i != NumBuckets; ++i) {
246 std::optional<StringRef> Key = getString(B.
Key);
247 std::optional<StringRef> Prefix = getString(B.
Prefix);
248 std::optional<StringRef> Suffix = getString(B.
Suffix);
249 if (LLVM_LIKELY(Key && Prefix && Suffix)) {
251 Buf.append(Prefix->begin(), Prefix->end());
252 Buf.append(Suffix->begin(), Suffix->end());
253 StringRef
Value(Buf.begin(), Buf.size());
254 ReverseMap[
Value] = *Key;
256 if (DestPath ==
Value)
Defines the clang::FileManager interface and associated types.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Implements support for file system lookup, file system caching, and directory search management.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
@ Result
The result type of a method or function.