100 lines · c
1//===- unittests/Lex/HeaderMapTestUtils.h - HeaderMap utils -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===--------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_UNITTESTS_LEX_HEADERMAPTESTUTILS_H10#define LLVM_CLANG_UNITTESTS_LEX_HEADERMAPTESTUTILS_H11 12#include "clang/Basic/CharInfo.h"13#include "clang/Lex/HeaderMap.h"14#include "clang/Lex/HeaderMapTypes.h"15#include "llvm/Support/SwapByteOrder.h"16#include <cassert>17 18namespace clang {19namespace test {20 21// Lay out a header file for testing.22template <unsigned NumBuckets, unsigned NumBytes> struct HMapFileMock {23 HMapHeader Header;24 HMapBucket Buckets[NumBuckets];25 unsigned char Bytes[NumBytes];26 27 void init() {28 memset(this, 0, sizeof(HMapFileMock));29 Header.Magic = HMAP_HeaderMagicNumber;30 Header.Version = HMAP_HeaderVersion;31 Header.NumBuckets = NumBuckets;32 Header.StringsOffset = sizeof(Header) + sizeof(Buckets);33 }34 35 void swapBytes() {36 Header.Magic = llvm::byteswap(Header.Magic);37 Header.Version = llvm::byteswap(Header.Version);38 Header.NumBuckets = llvm::byteswap(Header.NumBuckets);39 Header.StringsOffset = llvm::byteswap(Header.StringsOffset);40 }41 42 std::unique_ptr<llvm::MemoryBuffer> getBuffer() {43 return llvm::MemoryBuffer::getMemBuffer(44 StringRef(reinterpret_cast<char *>(this), sizeof(HMapFileMock)),45 "header",46 /* RequresNullTerminator */ false);47 }48};49 50template <class FileTy> struct HMapFileMockMaker {51 FileTy &File;52 unsigned SI = 1;53 unsigned BI = 0;54 HMapFileMockMaker(FileTy &File) : File(File) {}55 56 unsigned addString(StringRef S) {57 assert(SI + S.size() + 1 <= sizeof(File.Bytes));58 std::copy(S.begin(), S.end(), File.Bytes + SI);59 auto OldSI = SI;60 SI += S.size() + 1;61 return OldSI;62 }63 64 void addBucket(StringRef Str, unsigned Key, unsigned Prefix,65 unsigned Suffix) {66 addBucket(getHash(Str), Key, Prefix, Suffix);67 }68 69 void addBucket(unsigned Hash, unsigned Key, unsigned Prefix,70 unsigned Suffix) {71 assert(!(File.Header.NumBuckets & (File.Header.NumBuckets - 1)));72 unsigned I = Hash & (File.Header.NumBuckets - 1);73 do {74 if (!File.Buckets[I].Key) {75 File.Buckets[I].Key = Key;76 File.Buckets[I].Prefix = Prefix;77 File.Buckets[I].Suffix = Suffix;78 ++File.Header.NumEntries;79 return;80 }81 ++I;82 I &= File.Header.NumBuckets - 1;83 } while (I != (Hash & (File.Header.NumBuckets - 1)));84 llvm_unreachable("no empty buckets");85 }86 87 // The header map hash function.88 static unsigned getHash(StringRef Str) {89 unsigned Result = 0;90 for (char C : Str)91 Result += toLowercase(C) * 13;92 return Result;93 }94};95 96} // namespace test97} // namespace clang98 99#endif100