17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/Support/Compiler.h" 19 #include "llvm/Support/DataTypes.h" 20 #include "llvm/Support/MathExtras.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include "llvm/Support/SwapByteOrder.h" 23 #include "llvm/Support/Debug.h" 26 using namespace clang;
33 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 std::unique_ptr<HeaderMap>(
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");
219 for (
unsigned Bucket =
HashHMapKey(Filename);; ++Bucket) {
220 HMapBucket B = getBucket(Bucket & (NumBuckets-1));
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.
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 ...