]> granicus.if.org Git - clang/commitdiff
Lex: Add a test for HeaderMap::lookupFileName()
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sat, 20 Feb 2016 22:53:22 +0000 (22:53 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sat, 20 Feb 2016 22:53:22 +0000 (22:53 +0000)
Add a simple test for `HeaderMap::lookupFileName()`.  I'm planning to
add better error checking in a moment, and I'll add more tests like this
then.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261455 91177308-0d34-0410-b5e6-96231b3b80d8

unittests/Lex/HeaderMapTest.cpp

index 33befd8112f49db25108a8624e9f5e5fe9dbc584..57b51c219e89a5b5c9e15405b87457cfd2d6691e 100644 (file)
@@ -7,10 +7,13 @@
 //
 //===--------------------------------------------------------------===//
 
+#include "clang/Basic/CharInfo.h"
 #include "clang/Lex/HeaderMap.h"
 #include "clang/Lex/HeaderMapTypes.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/SwapByteOrder.h"
 #include "gtest/gtest.h"
+#include <cassert>
 
 using namespace clang;
 using namespace llvm;
@@ -47,6 +50,45 @@ template <unsigned NumBuckets, unsigned NumBytes> struct MapFile {
   }
 };
 
+// The header map hash function.
+static inline unsigned getHash(StringRef Str) {
+  unsigned Result = 0;
+  for (char C : Str)
+    Result += toLowercase(C) * 13;
+  return Result;
+}
+
+template <class FileTy> struct FileMaker {
+  FileTy &File;
+  unsigned SI = 1;
+  unsigned BI = 0;
+  FileMaker(FileTy &File) : File(File) {}
+
+  unsigned addString(StringRef S) {
+    assert(SI + S.size() + 1 <= sizeof(File.Bytes));
+    std::copy(S.begin(), S.end(), File.Bytes + SI);
+    auto OldSI = SI;
+    SI += S.size() + 1;
+    return OldSI;
+  }
+  void addBucket(unsigned Hash, unsigned Key, unsigned Prefix, unsigned Suffix) {
+    assert(!(File.Header.NumBuckets & (File.Header.NumBuckets - 1)));
+    unsigned I = Hash & (File.Header.NumBuckets - 1);
+    do {
+      if (!File.Buckets[I].Key) {
+        File.Buckets[I].Key = Key;
+        File.Buckets[I].Prefix = Prefix;
+        File.Buckets[I].Suffix = Suffix;
+        ++File.Header.NumEntries;
+        return;
+      }
+      ++I;
+      I &= File.Header.NumBuckets - 1;
+    } while (I != (Hash & (File.Header.NumBuckets - 1)));
+    llvm_unreachable("no empty buckets");
+  }
+};
+
 TEST(HeaderMapTest, checkHeaderEmpty) {
   bool NeedsSwap;
   ASSERT_FALSE(HeaderMapImpl::checkHeader(
@@ -108,4 +150,24 @@ TEST(HeaderMapTest, checkHeaderNotEnoughBuckets) {
   ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
 }
 
+TEST(HeaderMapTest, lookupFilename) {
+  typedef MapFile<2, 7> FileTy;
+  FileTy File;
+  File.init();
+
+  FileMaker<FileTy> Maker(File);
+  auto a = Maker.addString("a");
+  auto b = Maker.addString("b");
+  auto c = Maker.addString("c");
+  Maker.addBucket(getHash("a"), a, b, c);
+
+  bool NeedsSwap;
+  ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
+  ASSERT_FALSE(NeedsSwap);
+  HeaderMapImpl Map(File.getBuffer(), NeedsSwap);
+
+  SmallString<8> DestPath;
+  ASSERT_EQ("bc", Map.lookupFilename("a", DestPath));
+}
+
 } // end namespace