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"
154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Lex/HeaderMapTypes.h"
16223f0ff6a9a5d0eaf63b98b3aa92888b4c088868Jordan Rose#include "clang/Basic/CharInfo.h"
171bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "clang/Basic/FileManager.h"
185fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner#include "llvm/ADT/SmallString.h"
194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/Compiler.h"
2003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h"
211bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "llvm/Support/MathExtras.h"
221bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner#include "llvm/Support/MemoryBuffer.h"
234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/SwapByteOrder.h"
244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/Debug.h"
254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include <cstring>
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
270f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattnerusing namespace clang;
280f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner
295fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner/// HashHMapKey - This is the 'well known' hash function required by the file
305fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner/// format, used to look up keys in the hash table.  The hash table uses simple
315fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner/// linear probing based on this function.
325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic inline unsigned HashHMapKey(StringRef Str) {
335fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  unsigned Result = 0;
34a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  const char *S = Str.begin(), *End = Str.end();
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
365fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  for (; S != End; S++)
37223f0ff6a9a5d0eaf63b98b3aa92888b4c088868Jordan Rose    Result += toLowercase(*S) * 13;
385fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  return Result;
395fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner}
405fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner
415fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner
425fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner
431adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===//
441adbf6349d4701771a814542008386ad39e3d614Chris Lattner// Verification and Construction
451adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===//
461bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner
471bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// HeaderMap::Create - This attempts to load the specified file as a header
481bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// map.  If it doesn't look like a HeaderMap, it gives up and returns null.
491bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// If it looks like a HeaderMap but is obviously corrupted, it puts a reason
501bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner/// into the string error argument and returns null.
5139b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattnerconst HeaderMap *HeaderMap::Create(const FileEntry *FE, FileManager &FM) {
521bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  // If the file is too small to be a header map, ignore it.
531bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  unsigned FileSize = FE->getSize();
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (FileSize <= sizeof(HMapHeader)) return nullptr;
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto FileBuffer = FM.getBufferForFile(FE);
574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!FileBuffer || !*FileBuffer)
584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return nullptr;
594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsByteSwap;
604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!checkHeader(**FileBuffer, NeedsByteSwap))
614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return nullptr;
624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return new HeaderMap(std::move(*FileBuffer), NeedsByteSwap);
634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool HeaderMapImpl::checkHeader(const llvm::MemoryBuffer &File,
664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                bool &NeedsByteSwap) {
674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (File.getBufferSize() <= sizeof(HMapHeader))
684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const char *FileStart = File.getBufferStart();
701bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner
711bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  // We know the file is at least as big as the header, check it now.
721bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart);
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74ba8326517548d1d7773c4040aef4a4d91bb99df0Chris Lattner  // Sniff it to see if it's a headermap by checking the magic number and
75ba8326517548d1d7773c4040aef4a4d91bb99df0Chris Lattner  // version.
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (Header->Magic == HMAP_HeaderMagicNumber &&
771adbf6349d4701771a814542008386ad39e3d614Chris Lattner      Header->Version == HMAP_HeaderVersion)
781bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner    NeedsByteSwap = false;
791adbf6349d4701771a814542008386ad39e3d614Chris Lattner  else if (Header->Magic == llvm::ByteSwap_32(HMAP_HeaderMagicNumber) &&
801adbf6349d4701771a814542008386ad39e3d614Chris Lattner           Header->Version == llvm::ByteSwap_16(HMAP_HeaderVersion))
811bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner    NeedsByteSwap = true;  // Mixed endianness headermap.
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  else
834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;  // Not a header map.
844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (Header->Reserved != 0)
864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Check the number of buckets.  It should be a power of two, and there
894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // should be enough space in the file for all of them.
904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  uint32_t NumBuckets = NeedsByteSwap
914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            ? llvm::sys::getSwappedBytes(Header->NumBuckets)
924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            : Header->NumBuckets;
934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!llvm::isPowerOf2_32(NumBuckets))
944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (File.getBufferSize() <
964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      sizeof(HMapHeader) + sizeof(HMapBucket) * NumBuckets)
974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Okay, everything looks good.
1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return true;
10198751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner}
10298751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner
1031adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===//
1041adbf6349d4701771a814542008386ad39e3d614Chris Lattner//  Utility Methods
1051adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===//
1061adbf6349d4701771a814542008386ad39e3d614Chris Lattner
10798751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner
10898751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner/// getFileName - Return the filename of the headermap.
1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarconst char *HeaderMapImpl::getFileName() const {
11098751314c4ba596860b574c3d3551030f01ff7d8Chris Lattner  return FileBuffer->getBufferIdentifier();
1110f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner}
1120f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner
1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarunsigned HeaderMapImpl::getEndianAdjustedWord(unsigned X) const {
1141adbf6349d4701771a814542008386ad39e3d614Chris Lattner  if (!NeedsBSwap) return X;
1151adbf6349d4701771a814542008386ad39e3d614Chris Lattner  return llvm::ByteSwap_32(X);
1161adbf6349d4701771a814542008386ad39e3d614Chris Lattner}
1171adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1181adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// getHeader - Return a reference to the file header, in unbyte-swapped form.
1191adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// This method cannot fail.
1204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarconst HMapHeader &HeaderMapImpl::getHeader() const {
1211adbf6349d4701771a814542008386ad39e3d614Chris Lattner  // We know the file is at least as big as the header.  Return it.
1221adbf6349d4701771a814542008386ad39e3d614Chris Lattner  return *reinterpret_cast<const HMapHeader*>(FileBuffer->getBufferStart());
1231adbf6349d4701771a814542008386ad39e3d614Chris Lattner}
1241adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1251adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// getBucket - Return the specified hash table bucket from the header map,
1261adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// bswap'ing its fields as appropriate.  If the bucket number is not valid,
1271adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// this return a bucket with an empty key (0).
1284967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarHMapBucket HeaderMapImpl::getBucket(unsigned BucketNo) const {
1294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(FileBuffer->getBufferSize() >=
1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             sizeof(HMapHeader) + sizeof(HMapBucket) * BucketNo &&
1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar         "Expected bucket to be in range");
1324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1331adbf6349d4701771a814542008386ad39e3d614Chris Lattner  HMapBucket Result;
1341adbf6349d4701771a814542008386ad39e3d614Chris Lattner  Result.Key = HMAP_EmptyBucketKey;
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const HMapBucket *BucketArray =
1371adbf6349d4701771a814542008386ad39e3d614Chris Lattner    reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() +
1381adbf6349d4701771a814542008386ad39e3d614Chris Lattner                                        sizeof(HMapHeader));
1391adbf6349d4701771a814542008386ad39e3d614Chris Lattner  const HMapBucket *BucketPtr = BucketArray+BucketNo;
1401adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Load the values, bswapping as needed.
1421adbf6349d4701771a814542008386ad39e3d614Chris Lattner  Result.Key    = getEndianAdjustedWord(BucketPtr->Key);
1431adbf6349d4701771a814542008386ad39e3d614Chris Lattner  Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix);
1441adbf6349d4701771a814542008386ad39e3d614Chris Lattner  Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix);
1451adbf6349d4701771a814542008386ad39e3d614Chris Lattner  return Result;
1461adbf6349d4701771a814542008386ad39e3d614Chris Lattner}
1471adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarOptional<StringRef> HeaderMapImpl::getString(unsigned StrTabIdx) const {
1491adbf6349d4701771a814542008386ad39e3d614Chris Lattner  // Add the start of the string table to the idx.
1501adbf6349d4701771a814542008386ad39e3d614Chris Lattner  StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1521adbf6349d4701771a814542008386ad39e3d614Chris Lattner  // Check for invalid index.
1531adbf6349d4701771a814542008386ad39e3d614Chris Lattner  if (StrTabIdx >= FileBuffer->getBufferSize())
1544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return None;
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const char *Data = FileBuffer->getBufferStart() + StrTabIdx;
1574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned MaxLen = FileBuffer->getBufferSize() - StrTabIdx;
1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned Len = strnlen(Data, MaxLen);
1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Check whether the buffer is null-terminated.
1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (Len == MaxLen && Data[Len - 1])
1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return None;
1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return StringRef(Data, Len);
1651adbf6349d4701771a814542008386ad39e3d614Chris Lattner}
1661adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1671adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===//
1681adbf6349d4701771a814542008386ad39e3d614Chris Lattner// The Main Drivers
1691adbf6349d4701771a814542008386ad39e3d614Chris Lattner//===----------------------------------------------------------------------===//
1701adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1711adbf6349d4701771a814542008386ad39e3d614Chris Lattner/// dump - Print the contents of this headermap to stderr.
1724967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarLLVM_DUMP_METHOD void HeaderMapImpl::dump() const {
1731adbf6349d4701771a814542008386ad39e3d614Chris Lattner  const HMapHeader &Hdr = getHeader();
1741adbf6349d4701771a814542008386ad39e3d614Chris Lattner  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::dbgs() << "Header Map " << getFileName() << ":\n  " << NumBuckets
1774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               << ", " << getEndianAdjustedWord(Hdr.NumEntries) << "\n";
1784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto getStringOrInvalid = [this](unsigned Id) -> StringRef {
1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Optional<StringRef> S = getString(Id))
1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return *S;
1824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return "<invalid>";
1834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1851adbf6349d4701771a814542008386ad39e3d614Chris Lattner  for (unsigned i = 0; i != NumBuckets; ++i) {
1861adbf6349d4701771a814542008386ad39e3d614Chris Lattner    HMapBucket B = getBucket(i);
1871adbf6349d4701771a814542008386ad39e3d614Chris Lattner    if (B.Key == HMAP_EmptyBucketKey) continue;
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    StringRef Key = getStringOrInvalid(B.Key);
1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    StringRef Prefix = getStringOrInvalid(B.Prefix);
1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    StringRef Suffix = getStringOrInvalid(B.Suffix);
1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::dbgs() << "  " << i << ". " << Key << " -> '" << Prefix << "' '"
1934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                 << Suffix << "'\n";
1941adbf6349d4701771a814542008386ad39e3d614Chris Lattner  }
1951adbf6349d4701771a814542008386ad39e3d614Chris Lattner}
1961adbf6349d4701771a814542008386ad39e3d614Chris Lattner
1970f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner/// LookupFile - Check to see if the specified relative filename is located in
1980f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner/// this HeaderMap.  If so, open it and return its FileEntry.
199b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *HeaderMap::LookupFile(
2005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef Filename, FileManager &FM) const {
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SmallString<1024> Path;
2034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  StringRef Dest = HeaderMapImpl::lookupFilename(Filename, Path);
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Dest.empty())
2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return FM.getFile(Dest);
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2104967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarStringRef HeaderMapImpl::lookupFilename(StringRef Filename,
2114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        SmallVectorImpl<char> &DestPath) const {
2125fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  const HMapHeader &Hdr = getHeader();
2135fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
2145fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner
2154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Don't probe infinitely.  This should be checked before constructing.
2164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(llvm::isPowerOf2_32(NumBuckets) && "Expected power of 2");
2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2185fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  // Linearly probe the hash table.
219a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
2205fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    HMapBucket B = getBucket(Bucket & (NumBuckets-1));
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss.
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2235fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    // See if the key matches.  If not, probe on.
2244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Optional<StringRef> Key = getString(B.Key);
2254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (LLVM_UNLIKELY(!Key))
2264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      continue;
2274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!Filename.equals_lower(*Key))
2285fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner      continue;
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2305fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    // If so, we have a match in the hash table.  Construct the destination
2315fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner    // path.
2324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Optional<StringRef> Prefix = getString(B.Prefix);
2334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Optional<StringRef> Suffix = getString(B.Suffix);
2344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DestPath.clear();
2364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (LLVM_LIKELY(Prefix && Suffix)) {
2374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DestPath.append(Prefix->begin(), Prefix->end());
2384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DestPath.append(Suffix->begin(), Suffix->end());
2394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StringRef(DestPath.begin(), DestPath.size());
2415fb125c2556cb9d914493b1ef1bd5eee2d2843afChris Lattner  }
2420f441ab20ccd8d21fd3d034de866bfcaf6cb72b2Chris Lattner}
243