LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Native - TpiHashing.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 28 31 90.3 %
Date: 2018-02-23 15:42:53 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- TpiHashing.cpp -----------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
      11             : 
      12             : #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
      13             : #include "llvm/DebugInfo/PDB/Native/Hash.h"
      14             : #include "llvm/Support/JamCRC.h"
      15             : 
      16             : using namespace llvm;
      17             : using namespace llvm::codeview;
      18             : using namespace llvm::pdb;
      19             : 
      20             : // Corresponds to `fUDTAnon`.
      21         154 : static bool isAnonymous(StringRef Name) {
      22             :   return Name == "<unnamed-tag>" || Name == "__unnamed" ||
      23         154 :          Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");
      24             : }
      25             : 
      26             : // Computes the hash for a user-defined type record. This could be a struct,
      27             : // class, union, or enum.
      28         154 : static uint32_t getHashForUdt(const TagRecord &Rec,
      29             :                               ArrayRef<uint8_t> FullRecord) {
      30         154 :   ClassOptions Opts = Rec.getOptions();
      31             :   bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
      32             :   bool Scoped = bool(Opts & ClassOptions::Scoped);
      33         154 :   bool HasUniqueName = bool(Opts & ClassOptions::HasUniqueName);
      34         154 :   bool IsAnon = HasUniqueName && isAnonymous(Rec.getName());
      35             : 
      36         154 :   if (!ForwardRef && !Scoped && !IsAnon)
      37         101 :     return hashStringV1(Rec.getName());
      38          53 :   if (!ForwardRef && HasUniqueName && !IsAnon)
      39           0 :     return hashStringV1(Rec.getUniqueName());
      40          53 :   return hashBufferV8(FullRecord);
      41             : }
      42             : 
      43             : template <typename T>
      44         154 : static Expected<uint32_t> getHashForUdt(const CVType &Rec) {
      45             :   T Deserialized;
      46         308 :   if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
      47             :                                                Deserialized))
      48             :     return std::move(E);
      49         154 :   return getHashForUdt(Deserialized, Rec.data());
      50             : }
      51             : 
      52             : template <typename T>
      53          95 : static Expected<uint32_t> getSourceLineHash(const CVType &Rec) {
      54             :   T Deserialized;
      55         190 :   if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
      56             :                                                Deserialized))
      57             :     return std::move(E);
      58             :   char Buf[4];
      59         190 :   support::endian::write32le(Buf, Deserialized.getUDT().getIndex());
      60         190 :   return hashStringV1(StringRef(Buf, 4));
      61             : }
      62             : 
      63        1048 : Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
      64        1048 :   switch (Rec.kind()) {
      65         106 :   case LF_CLASS:
      66             :   case LF_STRUCTURE:
      67             :   case LF_INTERFACE:
      68         106 :     return getHashForUdt<ClassRecord>(Rec);
      69           0 :   case LF_UNION:
      70           0 :     return getHashForUdt<UnionRecord>(Rec);
      71          48 :   case LF_ENUM:
      72          48 :     return getHashForUdt<EnumRecord>(Rec);
      73             : 
      74          88 :   case LF_UDT_SRC_LINE:
      75          88 :     return getSourceLineHash<UdtSourceLineRecord>(Rec);
      76           7 :   case LF_UDT_MOD_SRC_LINE:
      77           7 :     return getSourceLineHash<UdtModSourceLineRecord>(Rec);
      78             : 
      79             :   default:
      80             :     break;
      81             :   }
      82             : 
      83             :   // Run CRC32 over the bytes. This corresponds to `hashBufv8`.
      84             :   JamCRC JC(/*Init=*/0U);
      85             :   ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()),
      86             :                        Rec.data().size());
      87         799 :   JC.update(Bytes);
      88             :   return JC.getCRC();
      89             : }

Generated by: LCOV version 1.13