Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
Line
Count
Source
1
//===- TypeHashing.cpp -------------------------------------------*- C++-*-===//
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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
10
11
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
12
#include "llvm/Support/SHA1.h"
13
14
using namespace llvm;
15
using namespace llvm::codeview;
16
17
LocallyHashedType DenseMapInfo<LocallyHashedType>::Empty{0, {}};
18
LocallyHashedType DenseMapInfo<LocallyHashedType>::Tombstone{hash_code(-1), {}};
19
20
static std::array<uint8_t, 8> EmptyHash = {
21
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
22
static std::array<uint8_t, 8> TombstoneHash = {
23
    {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
24
25
GloballyHashedType DenseMapInfo<GloballyHashedType>::Empty{EmptyHash};
26
GloballyHashedType DenseMapInfo<GloballyHashedType>::Tombstone{TombstoneHash};
27
28
11
LocallyHashedType LocallyHashedType::hashType(ArrayRef<uint8_t> RecordData) {
29
11
  return {llvm::hash_value(RecordData), RecordData};
30
11
}
31
32
GloballyHashedType
33
GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
34
                             ArrayRef<GloballyHashedType> PreviousTypes,
35
3.61k
                             ArrayRef<GloballyHashedType> PreviousIds) {
36
3.61k
  SmallVector<TiReference, 4> Refs;
37
3.61k
  discoverTypeIndices(RecordData, Refs);
38
3.61k
  SHA1 S;
39
3.61k
  S.init();
40
3.61k
  uint32_t Off = 0;
41
3.61k
  S.update(RecordData.take_front(sizeof(RecordPrefix)));
42
3.61k
  RecordData = RecordData.drop_front(sizeof(RecordPrefix));
43
4.54k
  for (const auto &Ref : Refs) {
44
4.54k
    // Hash any data that comes before this TiRef.
45
4.54k
    uint32_t PreLen = Ref.Offset - Off;
46
4.54k
    ArrayRef<uint8_t> PreData = RecordData.slice(Off, PreLen);
47
4.54k
    S.update(PreData);
48
4.54k
    auto Prev = (Ref.Kind == TiRefKind::IndexRef) ? 
PreviousIds1.37k
:
PreviousTypes3.16k
;
49
4.54k
50
4.54k
    auto RefData = RecordData.slice(Ref.Offset, Ref.Count * sizeof(TypeIndex));
51
4.54k
    // For each type index referenced, add in the previously computed hash
52
4.54k
    // value of that type.
53
4.54k
    ArrayRef<TypeIndex> Indices(
54
4.54k
        reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
55
6.70k
    for (TypeIndex TI : Indices) {
56
6.70k
      ArrayRef<uint8_t> BytesToHash;
57
6.70k
      if (TI.isSimple() || 
TI.isNoneType()3.31k
) {
58
3.39k
        const uint8_t *IndexBytes = reinterpret_cast<const uint8_t *>(&TI);
59
3.39k
        BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex));
60
3.39k
      } else {
61
3.31k
        if (TI.toArrayIndex() >= Prev.size() ||
62
3.31k
            
Prev[TI.toArrayIndex()].empty()3.31k
) {
63
10
          // There are references to yet-unhashed records. Suspend hashing for
64
10
          // this record until all the other records are processed.
65
10
          return {};
66
10
        }
67
3.30k
        BytesToHash = Prev[TI.toArrayIndex()].Hash;
68
3.30k
      }
69
6.70k
      S.update(BytesToHash);
70
6.69k
    }
71
4.54k
72
4.54k
    Off = Ref.Offset + Ref.Count * sizeof(TypeIndex);
73
4.53k
  }
74
3.61k
75
3.61k
  // Don't forget to add in any trailing bytes.
76
3.61k
  auto TrailingBytes = RecordData.drop_front(Off);
77
3.60k
  S.update(TrailingBytes);
78
3.60k
79
3.60k
  return {S.final().take_back(8)};
80
3.61k
}