LLVM API Documentation
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 }