LLVM API Documentation

DWARFDebugAbbrev.cpp
Go to the documentation of this file.
00001 //===-- DWARFDebugAbbrev.cpp ----------------------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "DWARFDebugAbbrev.h"
00011 #include "llvm/Support/Format.h"
00012 #include "llvm/Support/raw_ostream.h"
00013 using namespace llvm;
00014 
00015 DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
00016   clear();
00017 }
00018 
00019 void DWARFAbbreviationDeclarationSet::clear() {
00020   Offset = 0;
00021   FirstAbbrCode = 0;
00022   Decls.clear();
00023 }
00024 
00025 bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
00026                                               uint32_t *OffsetPtr) {
00027   clear();
00028   const uint32_t BeginOffset = *OffsetPtr;
00029   Offset = BeginOffset;
00030   DWARFAbbreviationDeclaration AbbrDecl;
00031   uint32_t PrevAbbrCode = 0;
00032   while (AbbrDecl.extract(Data, OffsetPtr)) {
00033     Decls.push_back(AbbrDecl);
00034     if (FirstAbbrCode == 0) {
00035       FirstAbbrCode = AbbrDecl.getCode();
00036     } else {
00037       if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
00038         // Codes are not consecutive, can't do O(1) lookups.
00039         FirstAbbrCode = UINT32_MAX;
00040       }
00041     }
00042     PrevAbbrCode = AbbrDecl.getCode();
00043   }
00044   return BeginOffset != *OffsetPtr;
00045 }
00046 
00047 void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
00048   for (const auto &Decl : Decls)
00049     Decl.dump(OS);
00050 }
00051 
00052 const DWARFAbbreviationDeclaration *
00053 DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
00054     uint32_t AbbrCode) const {
00055   if (FirstAbbrCode == UINT32_MAX) {
00056     for (const auto &Decl : Decls) {
00057       if (Decl.getCode() == AbbrCode)
00058         return &Decl;
00059     }
00060     return nullptr;
00061   }
00062   if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
00063     return nullptr;
00064   return &Decls[AbbrCode - FirstAbbrCode];
00065 }
00066 
00067 DWARFDebugAbbrev::DWARFDebugAbbrev() {
00068   clear();
00069 }
00070 
00071 void DWARFDebugAbbrev::clear() {
00072   AbbrDeclSets.clear();
00073   PrevAbbrOffsetPos = AbbrDeclSets.end();
00074 }
00075 
00076 void DWARFDebugAbbrev::extract(DataExtractor Data) {
00077   clear();
00078 
00079   uint32_t Offset = 0;
00080   DWARFAbbreviationDeclarationSet AbbrDecls;
00081   while (Data.isValidOffset(Offset)) {
00082     uint32_t CUAbbrOffset = Offset;
00083     if (!AbbrDecls.extract(Data, &Offset))
00084       break;
00085     AbbrDeclSets[CUAbbrOffset] = AbbrDecls;
00086   }
00087 }
00088 
00089 void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
00090   if (AbbrDeclSets.empty()) {
00091     OS << "< EMPTY >\n";
00092     return;
00093   }
00094 
00095   for (const auto &I : AbbrDeclSets) {
00096     OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
00097     I.second.dump(OS);
00098   }
00099 }
00100 
00101 const DWARFAbbreviationDeclarationSet*
00102 DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
00103   const auto End = AbbrDeclSets.end();
00104   if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
00105     return &(PrevAbbrOffsetPos->second);
00106   }
00107 
00108   const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
00109   if (Pos != End) {
00110     PrevAbbrOffsetPos = Pos;
00111     return &(Pos->second);
00112   }
00113 
00114   return nullptr;
00115 }