LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugAbbrev.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 65 68 95.6 %
Date: 2018-06-17 00:07:59 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFDebugAbbrev.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/DWARF/DWARFDebugAbbrev.h"
      11             : #include "llvm/Support/Format.h"
      12             : #include "llvm/Support/raw_ostream.h"
      13             : #include <algorithm>
      14             : #include <cinttypes>
      15             : #include <cstdint>
      16             : 
      17             : using namespace llvm;
      18             : 
      19        3259 : DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
      20        3259 :   clear();
      21        3259 : }
      22             : 
      23        6795 : void DWARFAbbreviationDeclarationSet::clear() {
      24        6795 :   Offset = 0;
      25        6795 :   FirstAbbrCode = 0;
      26        6795 :   Decls.clear();
      27        6795 : }
      28             : 
      29        3536 : bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
      30             :                                               uint32_t *OffsetPtr) {
      31        3536 :   clear();
      32        3536 :   const uint32_t BeginOffset = *OffsetPtr;
      33        3536 :   Offset = BeginOffset;
      34        3536 :   DWARFAbbreviationDeclaration AbbrDecl;
      35             :   uint32_t PrevAbbrCode = 0;
      36       30938 :   while (AbbrDecl.extract(Data, OffsetPtr)) {
      37       27402 :     if (FirstAbbrCode == 0) {
      38        3246 :       FirstAbbrCode = AbbrDecl.getCode();
      39             :     } else {
      40       24156 :       if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
      41             :         // Codes are not consecutive, can't do O(1) lookups.
      42           3 :         FirstAbbrCode = UINT32_MAX;
      43             :       }
      44             :     }
      45       27402 :     PrevAbbrCode = AbbrDecl.getCode();
      46       27402 :     Decls.push_back(std::move(AbbrDecl));
      47             :   }
      48        7072 :   return BeginOffset != *OffsetPtr;
      49             : }
      50             : 
      51         212 : void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
      52         212 :   for (const auto &Decl : Decls)
      53        1416 :     Decl.dump(OS);
      54         212 : }
      55             : 
      56             : const DWARFAbbreviationDeclaration *
      57       30958 : DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
      58             :     uint32_t AbbrCode) const {
      59       30958 :   if (FirstAbbrCode == UINT32_MAX) {
      60           6 :     for (const auto &Decl : Decls) {
      61          13 :       if (Decl.getCode() == AbbrCode)
      62             :         return &Decl;
      63             :     }
      64             :     return nullptr;
      65             :   }
      66       61904 :   if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
      67             :     return nullptr;
      68       61904 :   return &Decls[AbbrCode - FirstAbbrCode];
      69             : }
      70             : 
      71        4118 : DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
      72             : 
      73        4118 : void DWARFDebugAbbrev::clear() {
      74             :   AbbrDeclSets.clear();
      75        4118 :   PrevAbbrOffsetPos = AbbrDeclSets.end();
      76        4118 : }
      77             : 
      78        2059 : void DWARFDebugAbbrev::extract(DataExtractor Data) {
      79        2059 :   clear();
      80             :   this->Data = Data;
      81        2059 : }
      82             : 
      83         233 : void DWARFDebugAbbrev::parse() const {
      84         233 :   if (!Data)
      85           0 :     return;
      86         233 :   uint32_t Offset = 0;
      87         233 :   DWARFAbbreviationDeclarationSet AbbrDecls;
      88             :   auto I = AbbrDeclSets.begin();
      89        1996 :   while (Data->isValidOffset(Offset)) {
      90         510 :     while (I != AbbrDeclSets.end() && I->first < Offset)
      91             :       ++I;
      92             :     uint32_t CUAbbrOffset = Offset;
      93         510 :     if (!AbbrDecls.extract(*Data, &Offset))
      94             :       break;
      95         510 :     AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
      96             :   }
      97             :   Data = None;
      98             : }
      99             : 
     100         201 : void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
     101         201 :   parse();
     102             : 
     103         201 :   if (AbbrDeclSets.empty()) {
     104           0 :     OS << "< EMPTY >\n";
     105           0 :     return;
     106             :   }
     107             : 
     108         413 :   for (const auto &I : AbbrDeclSets) {
     109         424 :     OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
     110         212 :     I.second.dump(OS);
     111             :   }
     112             : }
     113             : 
     114             : const DWARFAbbreviationDeclarationSet*
     115        3973 : DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
     116             :   const auto End = AbbrDeclSets.end();
     117        3973 :   if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
     118         729 :     return &(PrevAbbrOffsetPos->second);
     119             :   }
     120             : 
     121             :   const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
     122        3244 :   if (Pos != End) {
     123         217 :     PrevAbbrOffsetPos = Pos;
     124         217 :     return &(Pos->second);
     125             :   }
     126             : 
     127        3027 :   if (Data && CUAbbrOffset < Data->getData().size()) {
     128        3026 :     uint32_t Offset = CUAbbrOffset;
     129        3026 :     DWARFAbbreviationDeclarationSet AbbrDecls;
     130        3026 :     if (!AbbrDecls.extract(*Data, &Offset))
     131             :       return nullptr;
     132        3026 :     PrevAbbrOffsetPos =
     133        3026 :         AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
     134             :             .first;
     135        3026 :     return &PrevAbbrOffsetPos->second;
     136             :   }
     137             : 
     138             :   return nullptr;
     139             : }

Generated by: LCOV version 1.13