LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Native - TpiHashing.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 37 42 88.1 %
Date: 2017-09-14 15:23:50 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          72 : static bool isAnonymous(StringRef Name) {
      22         144 :   return Name == "<unnamed-tag>" || Name == "__unnamed" ||
      23         216 :          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          72 : static uint32_t getHashForUdt(const TagRecord &Rec,
      29             :                               ArrayRef<uint8_t> FullRecord) {
      30          72 :   ClassOptions Opts = Rec.getOptions();
      31          72 :   bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
      32          72 :   bool Scoped = bool(Opts & ClassOptions::Scoped);
      33          72 :   bool HasUniqueName = bool(Opts & ClassOptions::HasUniqueName);
      34          72 :   bool IsAnon = HasUniqueName && isAnonymous(Rec.getName());
      35             : 
      36          72 :   if (!ForwardRef && !Scoped && !IsAnon)
      37          48 :     return hashStringV1(Rec.getName());
      38          24 :   if (!ForwardRef && HasUniqueName && !IsAnon)
      39           0 :     return hashStringV1(Rec.getUniqueName());
      40          24 :   return hashBufferV8(FullRecord);
      41             : }
      42             : 
      43             : template <typename T>
      44          72 : static Expected<uint32_t> getHashForUdt(const CVType &Rec) {
      45          72 :   T Deserialized;
      46         216 :   if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
      47             :                                                Deserialized))
      48           0 :     return std::move(E);
      49         144 :   return getHashForUdt(Deserialized, Rec.data());
      50             : }
      51             : 
      52             : template <typename T>
      53          41 : static Expected<uint32_t> getSourceLineHash(const CVType &Rec) {
      54          41 :   T Deserialized;
      55         123 :   if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
      56             :                                                Deserialized))
      57           0 :     return std::move(E);
      58             :   char Buf[4];
      59         164 :   support::endian::write32le(Buf, Deserialized.getUDT().getIndex());
      60          82 :   return hashStringV1(StringRef(Buf, 4));
      61             : }
      62             : 
      63         569 : Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
      64         569 :   switch (Rec.kind()) {
      65          48 :   case LF_CLASS:
      66             :   case LF_STRUCTURE:
      67             :   case LF_INTERFACE:
      68          48 :     return getHashForUdt<ClassRecord>(Rec);
      69           0 :   case LF_UNION:
      70           0 :     return getHashForUdt<UnionRecord>(Rec);
      71          24 :   case LF_ENUM:
      72          24 :     return getHashForUdt<EnumRecord>(Rec);
      73             : 
      74          34 :   case LF_UDT_SRC_LINE:
      75          34 :     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         456 :   JamCRC JC(/*Init=*/0U);
      85         456 :   ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()),
      86         912 :                        Rec.data().size());
      87         456 :   JC.update(Bytes);
      88         912 :   return JC.getCRC();
      89             : }

Generated by: LCOV version 1.13