[cfe-commits] r45124 - /cfe/trunk/Lex/HeaderMap.cpp
Chris Lattner
sabre at nondot.org
Mon Dec 17 13:38:05 PST 2007
Author: lattner
Date: Mon Dec 17 15:38:04 2007
New Revision: 45124
URL: http://llvm.org/viewvc/llvm-project?rev=45124&view=rev
Log:
implement HeaderMap::LookupFile. I think headermaps are done now. All that is
left is this crazy thing called "testing".
Modified:
cfe/trunk/Lex/HeaderMap.cpp
Modified: cfe/trunk/Lex/HeaderMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/HeaderMap.cpp?rev=45124&r1=45123&r2=45124&view=diff
==============================================================================
--- cfe/trunk/Lex/HeaderMap.cpp (original)
+++ cfe/trunk/Lex/HeaderMap.cpp Mon Dec 17 15:38:04 2007
@@ -14,6 +14,7 @@
#include "clang/Lex/HeaderMap.h"
#include "clang/Basic/FileManager.h"
#include "llvm/ADT/scoped_ptr.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -51,6 +52,19 @@
};
} // end namespace clang.
+/// HashHMapKey - This is the 'well known' hash function required by the file
+/// format, used to look up keys in the hash table. The hash table uses simple
+/// linear probing based on this function.
+static inline unsigned HashHMapKey(const char *S, const char *End) {
+ unsigned Result = 0;
+
+ for (; S != End; S++)
+ Result += tolower(*S) * 13;
+ return Result;
+}
+
+
+
//===----------------------------------------------------------------------===//
// Verification and Construction
//===----------------------------------------------------------------------===//
@@ -155,6 +169,17 @@
return FileBuffer->getBufferStart()+StrTabIdx;
}
+/// StringsEqualWithoutCase - Compare the specified two strings for case-
+/// insensitive equality, returning true if they are equal. Both strings are
+/// known to have the same length.
+static bool StringsEqualWithoutCase(const char *S1, const char *S2,
+ unsigned Len) {
+ for (; Len; ++S1, ++S2, --Len)
+ if (tolower(*S1) != tolower(*S2))
+ return false;
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// The Main Drivers
//===----------------------------------------------------------------------===//
@@ -184,6 +209,34 @@
const FileEntry *HeaderMap::LookupFile(const char *FilenameStart,
const char *FilenameEnd,
FileManager &FM) const {
- // FIXME: this needs work.
- return 0;
+ const HMapHeader &Hdr = getHeader();
+ unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
+
+ // If the number of buckets is not a power of two, the headermap is corrupt.
+ // Don't probe infinitely.
+ if (NumBuckets & (NumBuckets-1))
+ return 0;
+
+ // Linearly probe the hash table.
+ for (unsigned Bucket = HashHMapKey(FilenameStart, FilenameEnd);; ++Bucket) {
+ HMapBucket B = getBucket(Bucket & (NumBuckets-1));
+ if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss.
+
+ // See if the key matches. If not, probe on.
+ const char *Key = getString(B.Key);
+ unsigned BucketKeyLen = strlen(Key);
+ if (BucketKeyLen != unsigned(FilenameEnd-FilenameStart))
+ continue;
+
+ // See if the actual strings equal.
+ if (!StringsEqualWithoutCase(FilenameStart, Key, BucketKeyLen))
+ continue;
+
+ // If so, we have a match in the hash table. Construct the destination
+ // path.
+ llvm::SmallString<1024> DestPath;
+ DestPath += getString(B.Prefix);
+ DestPath += getString(B.Suffix);
+ return FM.getFile(DestPath.begin(), DestPath.end());
+ }
}
More information about the cfe-commits
mailing list