xref: /minix3/external/bsd/llvm/dist/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===-- DWARFDebugAbbrev.cpp ----------------------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10*0a6a1f1dSLionel Sambuc #include "llvm/DebugInfo/DWARFDebugAbbrev.h"
11f4a2713aSLionel Sambuc #include "llvm/Support/Format.h"
12f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
13f4a2713aSLionel Sambuc using namespace llvm;
14f4a2713aSLionel Sambuc 
DWARFAbbreviationDeclarationSet()15*0a6a1f1dSLionel Sambuc DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
16f4a2713aSLionel Sambuc   clear();
17*0a6a1f1dSLionel Sambuc }
18*0a6a1f1dSLionel Sambuc 
clear()19*0a6a1f1dSLionel Sambuc void DWARFAbbreviationDeclarationSet::clear() {
20*0a6a1f1dSLionel Sambuc   Offset = 0;
21*0a6a1f1dSLionel Sambuc   FirstAbbrCode = 0;
22*0a6a1f1dSLionel Sambuc   Decls.clear();
23*0a6a1f1dSLionel Sambuc }
24*0a6a1f1dSLionel Sambuc 
extract(DataExtractor Data,uint32_t * OffsetPtr)25*0a6a1f1dSLionel Sambuc bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
26*0a6a1f1dSLionel Sambuc                                               uint32_t *OffsetPtr) {
27*0a6a1f1dSLionel Sambuc   clear();
28*0a6a1f1dSLionel Sambuc   const uint32_t BeginOffset = *OffsetPtr;
29*0a6a1f1dSLionel Sambuc   Offset = BeginOffset;
30*0a6a1f1dSLionel Sambuc   DWARFAbbreviationDeclaration AbbrDecl;
31*0a6a1f1dSLionel Sambuc   uint32_t PrevAbbrCode = 0;
32*0a6a1f1dSLionel Sambuc   while (AbbrDecl.extract(Data, OffsetPtr)) {
33*0a6a1f1dSLionel Sambuc     if (FirstAbbrCode == 0) {
34*0a6a1f1dSLionel Sambuc       FirstAbbrCode = AbbrDecl.getCode();
35f4a2713aSLionel Sambuc     } else {
36*0a6a1f1dSLionel Sambuc       if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
37*0a6a1f1dSLionel Sambuc         // Codes are not consecutive, can't do O(1) lookups.
38*0a6a1f1dSLionel Sambuc         FirstAbbrCode = UINT32_MAX;
39f4a2713aSLionel Sambuc       }
40f4a2713aSLionel Sambuc     }
41*0a6a1f1dSLionel Sambuc     PrevAbbrCode = AbbrDecl.getCode();
42*0a6a1f1dSLionel Sambuc     Decls.push_back(std::move(AbbrDecl));
43*0a6a1f1dSLionel Sambuc   }
44*0a6a1f1dSLionel Sambuc   return BeginOffset != *OffsetPtr;
45f4a2713aSLionel Sambuc }
46f4a2713aSLionel Sambuc 
dump(raw_ostream & OS) const47f4a2713aSLionel Sambuc void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
48*0a6a1f1dSLionel Sambuc   for (const auto &Decl : Decls)
49*0a6a1f1dSLionel Sambuc     Decl.dump(OS);
50f4a2713aSLionel Sambuc }
51f4a2713aSLionel Sambuc 
52f4a2713aSLionel Sambuc const DWARFAbbreviationDeclaration *
getAbbreviationDeclaration(uint32_t AbbrCode) const53*0a6a1f1dSLionel Sambuc DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
54*0a6a1f1dSLionel Sambuc     uint32_t AbbrCode) const {
55*0a6a1f1dSLionel Sambuc   if (FirstAbbrCode == UINT32_MAX) {
56*0a6a1f1dSLionel Sambuc     for (const auto &Decl : Decls) {
57*0a6a1f1dSLionel Sambuc       if (Decl.getCode() == AbbrCode)
58*0a6a1f1dSLionel Sambuc         return &Decl;
59f4a2713aSLionel Sambuc     }
60*0a6a1f1dSLionel Sambuc     return nullptr;
61f4a2713aSLionel Sambuc   }
62*0a6a1f1dSLionel Sambuc   if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
63*0a6a1f1dSLionel Sambuc     return nullptr;
64*0a6a1f1dSLionel Sambuc   return &Decls[AbbrCode - FirstAbbrCode];
65f4a2713aSLionel Sambuc }
66f4a2713aSLionel Sambuc 
DWARFDebugAbbrev()67*0a6a1f1dSLionel Sambuc DWARFDebugAbbrev::DWARFDebugAbbrev() {
68*0a6a1f1dSLionel Sambuc   clear();
69*0a6a1f1dSLionel Sambuc }
70f4a2713aSLionel Sambuc 
clear()71*0a6a1f1dSLionel Sambuc void DWARFDebugAbbrev::clear() {
72*0a6a1f1dSLionel Sambuc   AbbrDeclSets.clear();
73*0a6a1f1dSLionel Sambuc   PrevAbbrOffsetPos = AbbrDeclSets.end();
74*0a6a1f1dSLionel Sambuc }
75f4a2713aSLionel Sambuc 
extract(DataExtractor Data)76*0a6a1f1dSLionel Sambuc void DWARFDebugAbbrev::extract(DataExtractor Data) {
77*0a6a1f1dSLionel Sambuc   clear();
78f4a2713aSLionel Sambuc 
79*0a6a1f1dSLionel Sambuc   uint32_t Offset = 0;
80*0a6a1f1dSLionel Sambuc   DWARFAbbreviationDeclarationSet AbbrDecls;
81*0a6a1f1dSLionel Sambuc   while (Data.isValidOffset(Offset)) {
82*0a6a1f1dSLionel Sambuc     uint32_t CUAbbrOffset = Offset;
83*0a6a1f1dSLionel Sambuc     if (!AbbrDecls.extract(Data, &Offset))
84f4a2713aSLionel Sambuc       break;
85*0a6a1f1dSLionel Sambuc     AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls);
86f4a2713aSLionel Sambuc   }
87f4a2713aSLionel Sambuc }
88f4a2713aSLionel Sambuc 
dump(raw_ostream & OS) const89f4a2713aSLionel Sambuc void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
90*0a6a1f1dSLionel Sambuc   if (AbbrDeclSets.empty()) {
91f4a2713aSLionel Sambuc     OS << "< EMPTY >\n";
92f4a2713aSLionel Sambuc     return;
93f4a2713aSLionel Sambuc   }
94f4a2713aSLionel Sambuc 
95*0a6a1f1dSLionel Sambuc   for (const auto &I : AbbrDeclSets) {
96*0a6a1f1dSLionel Sambuc     OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
97*0a6a1f1dSLionel Sambuc     I.second.dump(OS);
98f4a2713aSLionel Sambuc   }
99f4a2713aSLionel Sambuc }
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc const DWARFAbbreviationDeclarationSet*
getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const102*0a6a1f1dSLionel Sambuc DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
103*0a6a1f1dSLionel Sambuc   const auto End = AbbrDeclSets.end();
104*0a6a1f1dSLionel Sambuc   if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
105f4a2713aSLionel Sambuc     return &(PrevAbbrOffsetPos->second);
106f4a2713aSLionel Sambuc   }
107f4a2713aSLionel Sambuc 
108*0a6a1f1dSLionel Sambuc   const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
109*0a6a1f1dSLionel Sambuc   if (Pos != End) {
110*0a6a1f1dSLionel Sambuc     PrevAbbrOffsetPos = Pos;
111*0a6a1f1dSLionel Sambuc     return &(Pos->second);
112*0a6a1f1dSLionel Sambuc   }
113*0a6a1f1dSLionel Sambuc 
114*0a6a1f1dSLionel Sambuc   return nullptr;
115f4a2713aSLionel Sambuc }
116