1*9ab99eecSDuncan P. N. Exon Smith //===- unittests/Lex/HeaderMapTest.cpp - HeaderMap tests ----------===//
2*9ab99eecSDuncan P. N. Exon Smith //
3*9ab99eecSDuncan P. N. Exon Smith //                     The LLVM Compiler Infrastructure
4*9ab99eecSDuncan P. N. Exon Smith //
5*9ab99eecSDuncan P. N. Exon Smith // This file is distributed under the University of Illinois Open Source
6*9ab99eecSDuncan P. N. Exon Smith // License. See LICENSE.TXT for details.
7*9ab99eecSDuncan P. N. Exon Smith //
8*9ab99eecSDuncan P. N. Exon Smith //===--------------------------------------------------------------===//
9*9ab99eecSDuncan P. N. Exon Smith 
10*9ab99eecSDuncan P. N. Exon Smith #include "clang/Lex/HeaderMap.h"
11*9ab99eecSDuncan P. N. Exon Smith #include "clang/Lex/HeaderMapTypes.h"
12*9ab99eecSDuncan P. N. Exon Smith #include "llvm/Support/SwapByteOrder.h"
13*9ab99eecSDuncan P. N. Exon Smith #include "gtest/gtest.h"
14*9ab99eecSDuncan P. N. Exon Smith 
15*9ab99eecSDuncan P. N. Exon Smith using namespace clang;
16*9ab99eecSDuncan P. N. Exon Smith using namespace llvm;
17*9ab99eecSDuncan P. N. Exon Smith 
18*9ab99eecSDuncan P. N. Exon Smith namespace {
19*9ab99eecSDuncan P. N. Exon Smith 
20*9ab99eecSDuncan P. N. Exon Smith // Lay out a header file for testing.
21*9ab99eecSDuncan P. N. Exon Smith template <unsigned NumBuckets, unsigned NumBytes> struct MapFile {
22*9ab99eecSDuncan P. N. Exon Smith   HMapHeader Header;
23*9ab99eecSDuncan P. N. Exon Smith   HMapBucket Buckets[NumBuckets];
24*9ab99eecSDuncan P. N. Exon Smith   unsigned char Bytes[NumBytes];
25*9ab99eecSDuncan P. N. Exon Smith 
26*9ab99eecSDuncan P. N. Exon Smith   void init() {
27*9ab99eecSDuncan P. N. Exon Smith     memset(this, 0, sizeof(MapFile));
28*9ab99eecSDuncan P. N. Exon Smith     Header.Magic = HMAP_HeaderMagicNumber;
29*9ab99eecSDuncan P. N. Exon Smith     Header.Version = HMAP_HeaderVersion;
30*9ab99eecSDuncan P. N. Exon Smith     Header.NumBuckets = NumBuckets;
31*9ab99eecSDuncan P. N. Exon Smith     Header.StringsOffset = sizeof(Header) + sizeof(Buckets);
32*9ab99eecSDuncan P. N. Exon Smith   }
33*9ab99eecSDuncan P. N. Exon Smith 
34*9ab99eecSDuncan P. N. Exon Smith   void swapBytes() {
35*9ab99eecSDuncan P. N. Exon Smith     using llvm::sys::getSwappedBytes;
36*9ab99eecSDuncan P. N. Exon Smith     Header.Magic = getSwappedBytes(Header.Magic);
37*9ab99eecSDuncan P. N. Exon Smith     Header.Version = getSwappedBytes(Header.Version);
38*9ab99eecSDuncan P. N. Exon Smith     Header.NumBuckets = getSwappedBytes(Header.NumBuckets);
39*9ab99eecSDuncan P. N. Exon Smith     Header.StringsOffset = getSwappedBytes(Header.StringsOffset);
40*9ab99eecSDuncan P. N. Exon Smith   }
41*9ab99eecSDuncan P. N. Exon Smith 
42*9ab99eecSDuncan P. N. Exon Smith   std::unique_ptr<const MemoryBuffer> getBuffer() const {
43*9ab99eecSDuncan P. N. Exon Smith     return MemoryBuffer::getMemBuffer(
44*9ab99eecSDuncan P. N. Exon Smith         StringRef(reinterpret_cast<const char *>(this), sizeof(MapFile)),
45*9ab99eecSDuncan P. N. Exon Smith         "header",
46*9ab99eecSDuncan P. N. Exon Smith         /* RequresNullTerminator */ false);
47*9ab99eecSDuncan P. N. Exon Smith   }
48*9ab99eecSDuncan P. N. Exon Smith };
49*9ab99eecSDuncan P. N. Exon Smith 
50*9ab99eecSDuncan P. N. Exon Smith TEST(HeaderMapTest, checkHeaderEmpty) {
51*9ab99eecSDuncan P. N. Exon Smith   bool NeedsSwap;
52*9ab99eecSDuncan P. N. Exon Smith   ASSERT_FALSE(HeaderMapImpl::checkHeader(
53*9ab99eecSDuncan P. N. Exon Smith       *MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap));
54*9ab99eecSDuncan P. N. Exon Smith   ASSERT_FALSE(HeaderMapImpl::checkHeader(
55*9ab99eecSDuncan P. N. Exon Smith       *MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap));
56*9ab99eecSDuncan P. N. Exon Smith }
57*9ab99eecSDuncan P. N. Exon Smith 
58*9ab99eecSDuncan P. N. Exon Smith TEST(HeaderMapTest, checkHeaderMagic) {
59*9ab99eecSDuncan P. N. Exon Smith   MapFile<1, 1> File;
60*9ab99eecSDuncan P. N. Exon Smith   File.init();
61*9ab99eecSDuncan P. N. Exon Smith   File.Header.Magic = 0;
62*9ab99eecSDuncan P. N. Exon Smith   bool NeedsSwap;
63*9ab99eecSDuncan P. N. Exon Smith   ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
64*9ab99eecSDuncan P. N. Exon Smith }
65*9ab99eecSDuncan P. N. Exon Smith 
66*9ab99eecSDuncan P. N. Exon Smith TEST(HeaderMapTest, checkHeaderReserved) {
67*9ab99eecSDuncan P. N. Exon Smith   MapFile<1, 1> File;
68*9ab99eecSDuncan P. N. Exon Smith   File.init();
69*9ab99eecSDuncan P. N. Exon Smith   File.Header.Reserved = 1;
70*9ab99eecSDuncan P. N. Exon Smith   bool NeedsSwap;
71*9ab99eecSDuncan P. N. Exon Smith   ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
72*9ab99eecSDuncan P. N. Exon Smith }
73*9ab99eecSDuncan P. N. Exon Smith 
74*9ab99eecSDuncan P. N. Exon Smith TEST(HeaderMapTest, checkHeaderVersion) {
75*9ab99eecSDuncan P. N. Exon Smith   MapFile<1, 1> File;
76*9ab99eecSDuncan P. N. Exon Smith   File.init();
77*9ab99eecSDuncan P. N. Exon Smith   ++File.Header.Version;
78*9ab99eecSDuncan P. N. Exon Smith   bool NeedsSwap;
79*9ab99eecSDuncan P. N. Exon Smith   ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
80*9ab99eecSDuncan P. N. Exon Smith }
81*9ab99eecSDuncan P. N. Exon Smith 
82*9ab99eecSDuncan P. N. Exon Smith TEST(HeaderMapTest, checkHeaderValidButEmpty) {
83*9ab99eecSDuncan P. N. Exon Smith   MapFile<1, 1> File;
84*9ab99eecSDuncan P. N. Exon Smith   File.init();
85*9ab99eecSDuncan P. N. Exon Smith   bool NeedsSwap;
86*9ab99eecSDuncan P. N. Exon Smith   ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
87*9ab99eecSDuncan P. N. Exon Smith   ASSERT_FALSE(NeedsSwap);
88*9ab99eecSDuncan P. N. Exon Smith 
89*9ab99eecSDuncan P. N. Exon Smith   File.swapBytes();
90*9ab99eecSDuncan P. N. Exon Smith   ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
91*9ab99eecSDuncan P. N. Exon Smith   ASSERT_TRUE(NeedsSwap);
92*9ab99eecSDuncan P. N. Exon Smith }
93*9ab99eecSDuncan P. N. Exon Smith 
94*9ab99eecSDuncan P. N. Exon Smith } // end namespace
95