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"
15223f0ff6a9a5d0eaf63b98b3aa92888b4c088868Jordan Rose#include "clang/Basic/CharInfo.h"
161bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "clang/Basic/FileManager.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"
213daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio>
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
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++)
65223f0ff6a9a5d0eaf63b98b3aa92888b4c088868Jordan Rose    Result += toLowercase(*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();
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (FileSize <= sizeof(HMapHeader)) return nullptr;
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(FM.getBufferForFile(FE));
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!FileBuffer) return nullptr;  // 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
1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;  // Not a header map.
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (Header->Reserved != 0) return nullptr;
10498751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner
10598751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner  // Okay, everything looks good, create the header map.
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new HeaderMap(FileBuffer.release(), 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())
1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
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 {
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SmallString<1024> Path;
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef Dest = lookupFilename(Filename, Path);
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Dest.empty())
2086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return FM.getFile(Dest);
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
213651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesStringRef HeaderMap::lookupFilename(StringRef Filename,
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    SmallVectorImpl<char> &DestPath) const {
2155fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  const HMapHeader &Hdr = getHeader();
2165fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
2175fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner
2185fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  // If the number of buckets is not a power of two, the headermap is corrupt.
2195fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  // Don't probe infinitely.
2205fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  if (NumBuckets & (NumBuckets-1))
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StringRef();
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2235fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  // Linearly probe the hash table.
224a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
2255fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    HMapBucket B = getBucket(Bucket & (NumBuckets-1));
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss.
2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2285fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    // See if the key matches.  If not, probe on.
229dbdaf83779e2ea1330686c5210b340c35d306bbaBenjamin Kramer    if (!Filename.equals_lower(getString(B.Key)))
2305fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner      continue;
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2325fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    // If so, we have a match in the hash table.  Construct the destination
2335fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    // path.
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    StringRef Prefix = getString(B.Prefix);
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    StringRef Suffix = getString(B.Suffix);
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DestPath.clear();
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DestPath.append(Prefix.begin(), Prefix.end());
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DestPath.append(Suffix.begin(), Suffix.end());
239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StringRef(DestPath.begin(), DestPath.size());
2405fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  }
2410f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner}
242