18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/DataTypes.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/Support/SwapByteOrder.h"
24 #include "llvm/Support/Debug.h"
27 using namespace clang;
34 const char *
S = Str.begin(), *
End = Str.end();
53 unsigned FileSize = FE->
getSize();
54 if (FileSize <=
sizeof(
HMapHeader))
return nullptr;
57 if (!FileBuffer || !*FileBuffer)
62 return new HeaderMap(std::move(*FileBuffer), NeedsByteSwap);
66 bool &NeedsByteSwap) {
67 if (File.getBufferSize() <=
sizeof(
HMapHeader))
69 const char *FileStart = File.getBufferStart();
78 NeedsByteSwap =
false;
90 uint32_t NumBuckets = NeedsByteSwap
91 ? llvm::sys::getSwappedBytes(Header->
NumBuckets)
93 if (!llvm::isPowerOf2_32(NumBuckets))
95 if (File.getBufferSize() <
110 return FileBuffer->getBufferIdentifier();
113 unsigned HeaderMapImpl::getEndianAdjustedWord(
unsigned X)
const {
114 if (!NeedsBSwap)
return X;
115 return llvm::ByteSwap_32(X);
120 const HMapHeader &HeaderMapImpl::getHeader()
const {
122 return *
reinterpret_cast<const HMapHeader*
>(FileBuffer->getBufferStart());
128 HMapBucket HeaderMapImpl::getBucket(
unsigned BucketNo)
const {
129 assert(FileBuffer->getBufferSize() >=
131 "Expected bucket to be in range");
137 reinterpret_cast<const HMapBucket*
>(FileBuffer->getBufferStart() +
139 const HMapBucket *BucketPtr = BucketArray+BucketNo;
142 Result.Key = getEndianAdjustedWord(BucketPtr->
Key);
143 Result.Prefix = getEndianAdjustedWord(BucketPtr->
Prefix);
144 Result.Suffix = getEndianAdjustedWord(BucketPtr->
Suffix);
150 StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);
153 if (StrTabIdx >= FileBuffer->getBufferSize())
156 const char *Data = FileBuffer->getBufferStart() + StrTabIdx;
157 unsigned MaxLen = FileBuffer->getBufferSize() - StrTabIdx;
158 unsigned Len = strnlen(Data, MaxLen);
161 if (Len == MaxLen && Data[Len - 1])
164 return StringRef(Data, Len);
174 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
176 llvm::dbgs() <<
"Header Map " <<
getFileName() <<
":\n " << NumBuckets
177 <<
", " << getEndianAdjustedWord(Hdr.
NumEntries) <<
"\n";
179 auto getStringOrInvalid = [
this](
unsigned Id) -> StringRef {
185 for (
unsigned i = 0; i != NumBuckets; ++i) {
189 StringRef Key = getStringOrInvalid(B.
Key);
190 StringRef Prefix = getStringOrInvalid(B.
Prefix);
191 StringRef Suffix = getStringOrInvalid(B.
Suffix);
192 llvm::dbgs() <<
" " << i <<
". " << Key <<
" -> '" << Prefix <<
"' '"
213 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
216 assert(llvm::isPowerOf2_32(NumBuckets) &&
"Expected power of 2");
225 if (LLVM_UNLIKELY(!Key))
227 if (!Filename.equals_lower(*Key))
236 if (LLVM_LIKELY(Prefix && Suffix)) {
237 DestPath.append(Prefix->begin(), Prefix->end());
238 DestPath.append(Suffix->begin(), Suffix->end());
240 return StringRef(DestPath.begin(), DestPath.size());
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
The result type of a method or function.
Cached information about one file (either on disk or in the virtual file system). ...
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const FileEntry *Entry, bool isVolatile=false, bool ShouldCloseOpenFile=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
static LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
llvm::TimeRecord * Bucket