10f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner//===--- HeaderMap.cpp - A file that acts like dir of symlinks ------------===// 20f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// 30f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// The LLVM Compiler Infrastructure 40f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 70f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// 80f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner//===----------------------------------------------------------------------===// 90f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// 100f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// This file implements the HeaderMap interface. 110f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner// 120f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner//===----------------------------------------------------------------------===// 130f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner 140f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner#include "clang/Lex/HeaderMap.h" 151bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "clang/Basic/FileManager.h" 16ee533641635fc3e10dd14072972b378be110b21dTed Kremenek#include "llvm/ADT/OwningPtr.h" 175fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner#include "llvm/ADT/SmallString.h" 1803013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h" 191bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "llvm/Support/MathExtras.h" 201bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "llvm/Support/MemoryBuffer.h" 21403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <cctype> 223daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio> 230f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattnerusing namespace clang; 240f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner 251adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 261adbf6349d4701771a814542008386ad39e3d614Chris Lattner// Data Structures and Manifest Constants 271adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 281adbf6349d4701771a814542008386ad39e3d614Chris Lattner 291bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattnerenum { 301adbf6349d4701771a814542008386ad39e3d614Chris Lattner HMAP_HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p', 311adbf6349d4701771a814542008386ad39e3d614Chris Lattner HMAP_HeaderVersion = 1, 321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump HMAP_EmptyBucketKey = 0 341adbf6349d4701771a814542008386ad39e3d614Chris Lattner}; 351adbf6349d4701771a814542008386ad39e3d614Chris Lattner 361adbf6349d4701771a814542008386ad39e3d614Chris Lattnernamespace clang { 371adbf6349d4701771a814542008386ad39e3d614Chris Lattnerstruct HMapBucket { 381adbf6349d4701771a814542008386ad39e3d614Chris Lattner uint32_t Key; // Offset (into strings) of key. 391adbf6349d4701771a814542008386ad39e3d614Chris Lattner 401adbf6349d4701771a814542008386ad39e3d614Chris Lattner uint32_t Prefix; // Offset (into strings) of value prefix. 411adbf6349d4701771a814542008386ad39e3d614Chris Lattner uint32_t Suffix; // Offset (into strings) of value suffix. 421bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner}; 431bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner 441bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattnerstruct HMapHeader { 451bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner uint32_t Magic; // Magic word, also indicates byte order. 461bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner uint16_t Version; // Version number -- currently 1. 471bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner uint16_t Reserved; // Reserved for future use - zero for now. 481bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner uint32_t StringsOffset; // Offset to start of string pool. 491adbf6349d4701771a814542008386ad39e3d614Chris Lattner uint32_t NumEntries; // Number of entries in the string table. 501adbf6349d4701771a814542008386ad39e3d614Chris Lattner uint32_t NumBuckets; // Number of buckets (always a power of 2). 511bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner uint32_t MaxValueLength; // Length of longest result path (excluding nul). 521adbf6349d4701771a814542008386ad39e3d614Chris Lattner // An array of 'NumBuckets' HMapBucket objects follows this header. 531bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner // Strings follow the buckets, at StringsOffset. 541bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner}; 551adbf6349d4701771a814542008386ad39e3d614Chris Lattner} // end namespace clang. 561bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner 575fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner/// HashHMapKey - This is the 'well known' hash function required by the file 585fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner/// format, used to look up keys in the hash table. The hash table uses simple 595fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner/// linear probing based on this function. 605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic inline unsigned HashHMapKey(StringRef Str) { 615fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner unsigned Result = 0; 62a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner const char *S = Str.begin(), *End = Str.end(); 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 645fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner for (; S != End; S++) 655fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner Result += tolower(*S) * 13; 665fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner return Result; 675fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner} 685fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner 695fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner 705fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner 711adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 721adbf6349d4701771a814542008386ad39e3d614Chris Lattner// Verification and Construction 731adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 741bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner 751bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// HeaderMap::Create - This attempts to load the specified file as a header 761bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// map. If it doesn't look like a HeaderMap, it gives up and returns null. 771bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// If it looks like a HeaderMap but is obviously corrupted, it puts a reason 781bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// into the string error argument and returns null. 7939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattnerconst HeaderMap *HeaderMap::Create(const FileEntry *FE, FileManager &FM) { 801bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner // If the file is too small to be a header map, ignore it. 811bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner unsigned FileSize = FE->getSize(); 821bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner if (FileSize <= sizeof(HMapHeader)) return 0; 831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 846f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<const llvm::MemoryBuffer> FileBuffer(FM.getBufferForFile(FE)); 8598751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner if (FileBuffer == 0) return 0; // Unreadable file? 8698751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner const char *FileStart = FileBuffer->getBufferStart(); 871bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner 881bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner // We know the file is at least as big as the header, check it now. 891bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart); 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 91ba8326517548d1d7773c4040aef4a4d91bb99df0Chris Lattner // Sniff it to see if it's a headermap by checking the magic number and 92ba8326517548d1d7773c4040aef4a4d91bb99df0Chris Lattner // version. 931bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner bool NeedsByteSwap; 941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Header->Magic == HMAP_HeaderMagicNumber && 951adbf6349d4701771a814542008386ad39e3d614Chris Lattner Header->Version == HMAP_HeaderVersion) 961bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner NeedsByteSwap = false; 971adbf6349d4701771a814542008386ad39e3d614Chris Lattner else if (Header->Magic == llvm::ByteSwap_32(HMAP_HeaderMagicNumber) && 981adbf6349d4701771a814542008386ad39e3d614Chris Lattner Header->Version == llvm::ByteSwap_16(HMAP_HeaderVersion)) 991bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner NeedsByteSwap = true; // Mixed endianness headermap. 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else 1011bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner return 0; // Not a header map. 1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 103ba8326517548d1d7773c4040aef4a4d91bb99df0Chris Lattner if (Header->Reserved != 0) return 0; 10498751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner 10598751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner // Okay, everything looks good, create the header map. 106ba8326517548d1d7773c4040aef4a4d91bb99df0Chris Lattner return new HeaderMap(FileBuffer.take(), NeedsByteSwap); 10798751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner} 10898751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner 10998751314c4ba596860b574c3d3551030f01ff7d8Chris LattnerHeaderMap::~HeaderMap() { 11098751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner delete FileBuffer; 11198751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner} 11298751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner 1131adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 1141adbf6349d4701771a814542008386ad39e3d614Chris Lattner// Utility Methods 1151adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 1161adbf6349d4701771a814542008386ad39e3d614Chris Lattner 11798751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner 11898751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner/// getFileName - Return the filename of the headermap. 11998751314c4ba596860b574c3d3551030f01ff7d8Chris Lattnerconst char *HeaderMap::getFileName() const { 12098751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner return FileBuffer->getBufferIdentifier(); 1210f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner} 1220f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner 1231adbf6349d4701771a814542008386ad39e3d614Chris Lattnerunsigned HeaderMap::getEndianAdjustedWord(unsigned X) const { 1241adbf6349d4701771a814542008386ad39e3d614Chris Lattner if (!NeedsBSwap) return X; 1251adbf6349d4701771a814542008386ad39e3d614Chris Lattner return llvm::ByteSwap_32(X); 1261adbf6349d4701771a814542008386ad39e3d614Chris Lattner} 1271adbf6349d4701771a814542008386ad39e3d614Chris Lattner 1281adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// getHeader - Return a reference to the file header, in unbyte-swapped form. 1291adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// This method cannot fail. 1301adbf6349d4701771a814542008386ad39e3d614Chris Lattnerconst HMapHeader &HeaderMap::getHeader() const { 1311adbf6349d4701771a814542008386ad39e3d614Chris Lattner // We know the file is at least as big as the header. Return it. 1321adbf6349d4701771a814542008386ad39e3d614Chris Lattner return *reinterpret_cast<const HMapHeader*>(FileBuffer->getBufferStart()); 1331adbf6349d4701771a814542008386ad39e3d614Chris Lattner} 1341adbf6349d4701771a814542008386ad39e3d614Chris Lattner 1351adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// getBucket - Return the specified hash table bucket from the header map, 1361adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// bswap'ing its fields as appropriate. If the bucket number is not valid, 1371adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// this return a bucket with an empty key (0). 1381adbf6349d4701771a814542008386ad39e3d614Chris LattnerHMapBucket HeaderMap::getBucket(unsigned BucketNo) const { 1391adbf6349d4701771a814542008386ad39e3d614Chris Lattner HMapBucket Result; 1401adbf6349d4701771a814542008386ad39e3d614Chris Lattner Result.Key = HMAP_EmptyBucketKey; 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const HMapBucket *BucketArray = 1431adbf6349d4701771a814542008386ad39e3d614Chris Lattner reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() + 1441adbf6349d4701771a814542008386ad39e3d614Chris Lattner sizeof(HMapHeader)); 1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1461adbf6349d4701771a814542008386ad39e3d614Chris Lattner const HMapBucket *BucketPtr = BucketArray+BucketNo; 14731ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky if ((const char*)(BucketPtr+1) > FileBuffer->getBufferEnd()) { 1488173dba2229e113052e762b4eda98f8edfdff173Ted Kremenek Result.Prefix = 0; 1498173dba2229e113052e762b4eda98f8edfdff173Ted Kremenek Result.Suffix = 0; 1501adbf6349d4701771a814542008386ad39e3d614Chris Lattner return Result; // Invalid buffer, corrupt hmap. 1518173dba2229e113052e762b4eda98f8edfdff173Ted Kremenek } 1521adbf6349d4701771a814542008386ad39e3d614Chris Lattner 1531adbf6349d4701771a814542008386ad39e3d614Chris Lattner // Otherwise, the bucket is valid. Load the values, bswapping as needed. 1541adbf6349d4701771a814542008386ad39e3d614Chris Lattner Result.Key = getEndianAdjustedWord(BucketPtr->Key); 1551adbf6349d4701771a814542008386ad39e3d614Chris Lattner Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix); 1561adbf6349d4701771a814542008386ad39e3d614Chris Lattner Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix); 1571adbf6349d4701771a814542008386ad39e3d614Chris Lattner return Result; 1581adbf6349d4701771a814542008386ad39e3d614Chris Lattner} 1591adbf6349d4701771a814542008386ad39e3d614Chris Lattner 1601adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// getString - Look up the specified string in the string table. If the string 1611adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// index is not valid, it returns an empty string. 1621adbf6349d4701771a814542008386ad39e3d614Chris Lattnerconst char *HeaderMap::getString(unsigned StrTabIdx) const { 1631adbf6349d4701771a814542008386ad39e3d614Chris Lattner // Add the start of the string table to the idx. 1641adbf6349d4701771a814542008386ad39e3d614Chris Lattner StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset); 1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1661adbf6349d4701771a814542008386ad39e3d614Chris Lattner // Check for invalid index. 1671adbf6349d4701771a814542008386ad39e3d614Chris Lattner if (StrTabIdx >= FileBuffer->getBufferSize()) 1681adbf6349d4701771a814542008386ad39e3d614Chris Lattner return 0; 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1701adbf6349d4701771a814542008386ad39e3d614Chris Lattner // Otherwise, we have a valid pointer into the file. Just return it. We know 1711adbf6349d4701771a814542008386ad39e3d614Chris Lattner // that the "string" can not overrun the end of the file, because the buffer 1721adbf6349d4701771a814542008386ad39e3d614Chris Lattner // is nul terminated by virtue of being a MemoryBuffer. 1731adbf6349d4701771a814542008386ad39e3d614Chris Lattner return FileBuffer->getBufferStart()+StrTabIdx; 1741adbf6349d4701771a814542008386ad39e3d614Chris Lattner} 1751adbf6349d4701771a814542008386ad39e3d614Chris Lattner 1761adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 1771adbf6349d4701771a814542008386ad39e3d614Chris Lattner// The Main Drivers 1781adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===// 1791adbf6349d4701771a814542008386ad39e3d614Chris Lattner 1801adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// dump - Print the contents of this headermap to stderr. 1811adbf6349d4701771a814542008386ad39e3d614Chris Lattnervoid HeaderMap::dump() const { 1821adbf6349d4701771a814542008386ad39e3d614Chris Lattner const HMapHeader &Hdr = getHeader(); 1831adbf6349d4701771a814542008386ad39e3d614Chris Lattner unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets); 1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump fprintf(stderr, "Header Map %s:\n %d buckets, %d entries\n", 1861adbf6349d4701771a814542008386ad39e3d614Chris Lattner getFileName(), NumBuckets, 1871adbf6349d4701771a814542008386ad39e3d614Chris Lattner getEndianAdjustedWord(Hdr.NumEntries)); 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1891adbf6349d4701771a814542008386ad39e3d614Chris Lattner for (unsigned i = 0; i != NumBuckets; ++i) { 1901adbf6349d4701771a814542008386ad39e3d614Chris Lattner HMapBucket B = getBucket(i); 1911adbf6349d4701771a814542008386ad39e3d614Chris Lattner if (B.Key == HMAP_EmptyBucketKey) continue; 1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1931adbf6349d4701771a814542008386ad39e3d614Chris Lattner const char *Key = getString(B.Key); 1941adbf6349d4701771a814542008386ad39e3d614Chris Lattner const char *Prefix = getString(B.Prefix); 1951adbf6349d4701771a814542008386ad39e3d614Chris Lattner const char *Suffix = getString(B.Suffix); 1961adbf6349d4701771a814542008386ad39e3d614Chris Lattner fprintf(stderr, " %d. %s -> '%s' '%s'\n", i, Key, Prefix, Suffix); 1971adbf6349d4701771a814542008386ad39e3d614Chris Lattner } 1981adbf6349d4701771a814542008386ad39e3d614Chris Lattner} 1991adbf6349d4701771a814542008386ad39e3d614Chris Lattner 2000f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner/// LookupFile - Check to see if the specified relative filename is located in 2010f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner/// this HeaderMap. If so, open it and return its FileEntry. 202b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *HeaderMap::LookupFile( 2035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, FileManager &FM) const { 2045fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner const HMapHeader &Hdr = getHeader(); 2055fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets); 2065fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner 2075fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner // If the number of buckets is not a power of two, the headermap is corrupt. 2085fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner // Don't probe infinitely. 2095fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner if (NumBuckets & (NumBuckets-1)) 2105fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner return 0; 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2125fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner // Linearly probe the hash table. 213a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) { 2145fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner HMapBucket B = getBucket(Bucket & (NumBuckets-1)); 2155fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss. 2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2175fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner // See if the key matches. If not, probe on. 218dbdaf83779e2ea1330686c5210b340c35d306bbaBenjamin Kramer if (!Filename.equals_lower(getString(B.Key))) 2195fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner continue; 2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2215fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner // If so, we have a match in the hash table. Construct the destination 2225fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner // path. 223f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> DestPath; 2245fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner DestPath += getString(B.Prefix); 2255fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner DestPath += getString(B.Suffix); 22639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner return FM.getFile(DestPath.str()); 2275fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner } 2280f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner} 229