LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugAbbrev.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 64 67 95.5 %
Date: 2018-10-20 13:21:21 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        3334 : DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
      20        3334 :   clear();
      21        3334 : }
      22             : 
      23        6946 : void DWARFAbbreviationDeclarationSet::clear() {
      24        6946 :   Offset = 0;
      25        6946 :   FirstAbbrCode = 0;
      26             :   Decls.clear();
      27        6946 : }
      28             : 
      29        3612 : bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
      30             :                                               uint32_t *OffsetPtr) {
      31        3612 :   clear();
      32        3612 :   const uint32_t BeginOffset = *OffsetPtr;
      33        3612 :   Offset = BeginOffset;
      34        3612 :   DWARFAbbreviationDeclaration AbbrDecl;
      35             :   uint32_t PrevAbbrCode = 0;
      36       31459 :   while (AbbrDecl.extract(Data, OffsetPtr)) {
      37       27847 :     if (FirstAbbrCode == 0) {
      38        3322 :       FirstAbbrCode = AbbrDecl.getCode();
      39             :     } else {
      40       24525 :       if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
      41             :         // Codes are not consecutive, can't do O(1) lookups.
      42           3 :         FirstAbbrCode = UINT32_MAX;
      43             :       }
      44             :     }
      45       27847 :     PrevAbbrCode = AbbrDecl.getCode();
      46       27847 :     Decls.push_back(std::move(AbbrDecl));
      47             :   }
      48        3612 :   return BeginOffset != *OffsetPtr;
      49             : }
      50             : 
      51         229 : void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
      52        1708 :   for (const auto &Decl : Decls)
      53        1479 :     Decl.dump(OS);
      54         229 : }
      55             : 
      56             : const DWARFAbbreviationDeclaration *
      57       31763 : DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
      58             :     uint32_t AbbrCode) const {
      59       31763 :   if (FirstAbbrCode == UINT32_MAX) {
      60          13 :     for (const auto &Decl : Decls) {
      61          13 :       if (Decl.getCode() == AbbrCode)
      62             :         return &Decl;
      63             :     }
      64             :     return nullptr;
      65             :   }
      66       31757 :   if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
      67             :     return nullptr;
      68       63514 :   return &Decls[AbbrCode - FirstAbbrCode];
      69             : }
      70             : 
      71        3374 : DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
      72             : 
      73        3374 : void DWARFDebugAbbrev::clear() {
      74             :   AbbrDeclSets.clear();
      75        3374 :   PrevAbbrOffsetPos = AbbrDeclSets.end();
      76        3374 : }
      77             : 
      78        1687 : void DWARFDebugAbbrev::extract(DataExtractor Data) {
      79        1687 :   clear();
      80             :   this->Data = Data;
      81        1687 : }
      82             : 
      83         249 : void DWARFDebugAbbrev::parse() const {
      84         249 :   if (!Data)
      85           0 :     return;
      86         249 :   uint32_t Offset = 0;
      87         249 :   DWARFAbbreviationDeclarationSet AbbrDecls;
      88             :   auto I = AbbrDeclSets.begin();
      89        1552 :   while (Data->isValidOffset(Offset)) {
      90         527 :     while (I != AbbrDeclSets.end() && I->first < Offset)
      91             :       ++I;
      92             :     uint32_t CUAbbrOffset = Offset;
      93         527 :     if (!AbbrDecls.extract(*Data, &Offset))
      94             :       break;
      95         527 :     AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
      96             :   }
      97             :   Data = None;
      98             : }
      99             : 
     100         217 : void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
     101         217 :   parse();
     102             : 
     103         217 :   if (AbbrDeclSets.empty()) {
     104           0 :     OS << "< EMPTY >\n";
     105           0 :     return;
     106             :   }
     107             : 
     108         446 :   for (const auto &I : AbbrDeclSets) {
     109         458 :     OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
     110         229 :     I.second.dump(OS);
     111             :   }
     112             : }
     113             : 
     114             : const DWARFAbbreviationDeclarationSet*
     115        4125 : DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
     116             :   const auto End = AbbrDeclSets.end();
     117        4125 :   if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
     118         803 :     return &(PrevAbbrOffsetPos->second);
     119             :   }
     120             : 
     121             :   const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
     122        3322 :   if (Pos != End) {
     123         236 :     PrevAbbrOffsetPos = Pos;
     124         236 :     return &(Pos->second);
     125             :   }
     126             : 
     127        3086 :   if (Data && CUAbbrOffset < Data->getData().size()) {
     128        3085 :     uint32_t Offset = CUAbbrOffset;
     129        3085 :     DWARFAbbreviationDeclarationSet AbbrDecls;
     130        3085 :     if (!AbbrDecls.extract(*Data, &Offset))
     131             :       return nullptr;
     132        3085 :     PrevAbbrOffsetPos =
     133        3085 :         AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
     134             :             .first;
     135        3085 :     return &PrevAbbrOffsetPos->second;
     136             :   }
     137             : 
     138             :   return nullptr;
     139             : }

Generated by: LCOV version 1.13