blob: 8426bf95beda9553acfbc9d467a0d2c1e385dfff [file] [log] [blame]
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +00001//===-- 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 "DWARFDebugAbbrev.h"
11#include "llvm/Support/Format.h"
12#include "llvm/Support/raw_ostream.h"
13using namespace llvm;
14
Stephen Hinesdce4a402014-05-29 02:49:00 -070015DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000016 clear();
Stephen Hinesdce4a402014-05-29 02:49:00 -070017}
18
19void DWARFAbbreviationDeclarationSet::clear() {
20 Offset = 0;
21 FirstAbbrCode = 0;
22 Decls.clear();
23}
24
25bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
26 uint32_t *OffsetPtr) {
27 clear();
28 const uint32_t BeginOffset = *OffsetPtr;
29 Offset = BeginOffset;
30 DWARFAbbreviationDeclaration AbbrDecl;
31 uint32_t PrevAbbrCode = 0;
32 while (AbbrDecl.extract(Data, OffsetPtr)) {
33 Decls.push_back(AbbrDecl);
34 if (FirstAbbrCode == 0) {
35 FirstAbbrCode = AbbrDecl.getCode();
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000036 } else {
Stephen Hinesdce4a402014-05-29 02:49:00 -070037 if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
38 // Codes are not consecutive, can't do O(1) lookups.
39 FirstAbbrCode = UINT32_MAX;
40 }
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000041 }
Stephen Hinesdce4a402014-05-29 02:49:00 -070042 PrevAbbrCode = AbbrDecl.getCode();
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000043 }
Stephen Hinesdce4a402014-05-29 02:49:00 -070044 return BeginOffset != *OffsetPtr;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000045}
46
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000047void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
Stephen Hines36b56882014-04-23 16:57:46 -070048 for (const auto &Decl : Decls)
49 Decl.dump(OS);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000050}
51
Stephen Hinesdce4a402014-05-29 02:49:00 -070052const DWARFAbbreviationDeclaration *
53DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
54 uint32_t AbbrCode) const {
55 if (FirstAbbrCode == UINT32_MAX) {
Stephen Hines36b56882014-04-23 16:57:46 -070056 for (const auto &Decl : Decls) {
Stephen Hinesdce4a402014-05-29 02:49:00 -070057 if (Decl.getCode() == AbbrCode)
Stephen Hines36b56882014-04-23 16:57:46 -070058 return &Decl;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000059 }
Stephen Hinesdce4a402014-05-29 02:49:00 -070060 return nullptr;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000061 }
Stephen Hinesdce4a402014-05-29 02:49:00 -070062 if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
63 return nullptr;
64 return &Decls[AbbrCode - FirstAbbrCode];
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000065}
66
Stephen Hinesdce4a402014-05-29 02:49:00 -070067DWARFDebugAbbrev::DWARFDebugAbbrev() {
68 clear();
69}
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000070
Stephen Hinesdce4a402014-05-29 02:49:00 -070071void DWARFDebugAbbrev::clear() {
72 AbbrDeclSets.clear();
73 PrevAbbrOffsetPos = AbbrDeclSets.end();
74}
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000075
Stephen Hinesdce4a402014-05-29 02:49:00 -070076void DWARFDebugAbbrev::extract(DataExtractor Data) {
77 clear();
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000078
Stephen Hinesdce4a402014-05-29 02:49:00 -070079 uint32_t Offset = 0;
80 DWARFAbbreviationDeclarationSet AbbrDecls;
81 while (Data.isValidOffset(Offset)) {
82 uint32_t CUAbbrOffset = Offset;
83 if (!AbbrDecls.extract(Data, &Offset))
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000084 break;
Stephen Hinesdce4a402014-05-29 02:49:00 -070085 AbbrDeclSets[CUAbbrOffset] = AbbrDecls;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000086 }
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000087}
88
89void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
Stephen Hinesdce4a402014-05-29 02:49:00 -070090 if (AbbrDeclSets.empty()) {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000091 OS << "< EMPTY >\n";
92 return;
93 }
94
Stephen Hinesdce4a402014-05-29 02:49:00 -070095 for (const auto &I : AbbrDeclSets) {
Stephen Hines36b56882014-04-23 16:57:46 -070096 OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
97 I.second.dump(OS);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000098 }
99}
100
101const DWARFAbbreviationDeclarationSet*
Stephen Hinesdce4a402014-05-29 02:49:00 -0700102DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
103 const auto End = AbbrDeclSets.end();
104 if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
Benjamin Kramer4aa3fea2011-09-13 21:47:32 +0000105 return &(PrevAbbrOffsetPos->second);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000106 }
107
Stephen Hinesdce4a402014-05-29 02:49:00 -0700108 const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
109 if (Pos != End) {
110 PrevAbbrOffsetPos = Pos;
111 return &(Pos->second);
112 }
113
114 return nullptr;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000115}