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();
54 unsigned FileSize = FE->
getSize();
55 if (FileSize <=
sizeof(
HMapHeader))
return nullptr;
58 if (!FileBuffer || !*FileBuffer)
63 return std::unique_ptr<HeaderMap>(
new HeaderMap(std::move(*FileBuffer), NeedsByteSwap));
67 bool &NeedsByteSwap) {
68 if (File.getBufferSize() <=
sizeof(
HMapHeader))
70 const char *FileStart = File.getBufferStart();
79 NeedsByteSwap =
false;
91 uint32_t NumBuckets = NeedsByteSwap
92 ? llvm::sys::getSwappedBytes(Header->
NumBuckets)
94 if (!llvm::isPowerOf2_32(NumBuckets))
96 if (File.getBufferSize() <
111 return FileBuffer->getBufferIdentifier();
114 unsigned HeaderMapImpl::getEndianAdjustedWord(
unsigned X)
const {
115 if (!NeedsBSwap)
return X;
116 return llvm::ByteSwap_32(X);
121 const HMapHeader &HeaderMapImpl::getHeader()
const {
123 return *
reinterpret_cast<const HMapHeader*
>(FileBuffer->getBufferStart());
129 HMapBucket HeaderMapImpl::getBucket(
unsigned BucketNo)
const {
130 assert(FileBuffer->getBufferSize() >=
132 "Expected bucket to be in range");
138 reinterpret_cast<const HMapBucket*
>(FileBuffer->getBufferStart() +
140 const HMapBucket *BucketPtr = BucketArray+BucketNo;
143 Result.
Key = getEndianAdjustedWord(BucketPtr->
Key);
144 Result.Prefix = getEndianAdjustedWord(BucketPtr->
Prefix);
145 Result.Suffix = getEndianAdjustedWord(BucketPtr->
Suffix);
151 StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);
154 if (StrTabIdx >= FileBuffer->getBufferSize())
157 const char *Data = FileBuffer->getBufferStart() + StrTabIdx;
158 unsigned MaxLen = FileBuffer->getBufferSize() - StrTabIdx;
159 unsigned Len = strnlen(Data, MaxLen);
162 if (Len == MaxLen && Data[Len - 1])
165 return StringRef(Data, Len);
175 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
177 llvm::dbgs() <<
"Header Map " <<
getFileName() <<
":\n " << NumBuckets
178 <<
", " << getEndianAdjustedWord(Hdr.
NumEntries) <<
"\n";
180 auto getStringOrInvalid = [
this](
unsigned Id) -> StringRef {
186 for (
unsigned i = 0; i != NumBuckets; ++i) {
190 StringRef Key = getStringOrInvalid(B.
Key);
191 StringRef Prefix = getStringOrInvalid(B.
Prefix);
192 StringRef Suffix = getStringOrInvalid(B.
Suffix);
193 llvm::dbgs() <<
" " << i <<
". " << Key <<
" -> '" << Prefix <<
"' '" 214 unsigned NumBuckets = getEndianAdjustedWord(Hdr.
NumBuckets);
217 assert(llvm::isPowerOf2_32(NumBuckets) &&
"Expected power of 2");
220 for (
unsigned Bucket =
HashHMapKey(Filename);; ++Bucket) {
221 HMapBucket B = getBucket(Bucket & (NumBuckets-1));
226 if (LLVM_UNLIKELY(!Key))
228 if (!Filename.equals_lower(*Key))
237 if (LLVM_LIKELY(Prefix && Suffix)) {
238 DestPath.append(Prefix->begin(), Prefix->end());
239 DestPath.append(Suffix->begin(), Suffix->end());
241 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.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
Cached information about one file (either on disk or in the virtual file system). ...
Dataflow Directional Tag Classes.
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 ...