blob: e63e28997ed06bb1f95d2e5126114f894c36a18d [file] [log] [blame]
Benjamin Krameraa2f78f2011-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
Zachary Turner82af9432015-01-30 18:07:45 +000010#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000011#include "llvm/Support/Format.h"
12#include "llvm/Support/raw_ostream.h"
13using namespace llvm;
14
Alexey Samsonov4316df52014-04-25 21:10:56 +000015DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000016 clear();
Alexey Samsonov4316df52014-04-25 21:10:56 +000017}
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)) {
Alexey Samsonov4316df52014-04-25 21:10:56 +000033 if (FirstAbbrCode == 0) {
34 FirstAbbrCode = AbbrDecl.getCode();
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000035 } else {
Alexey Samsonov4316df52014-04-25 21:10:56 +000036 if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
37 // Codes are not consecutive, can't do O(1) lookups.
38 FirstAbbrCode = UINT32_MAX;
39 }
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000040 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000041 PrevAbbrCode = AbbrDecl.getCode();
Benjamin Kramerc6cc58e2014-10-04 16:55:56 +000042 Decls.push_back(std::move(AbbrDecl));
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000043 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000044 return BeginOffset != *OffsetPtr;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000045}
46
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000047void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000048 for (const auto &Decl : Decls)
49 Decl.dump(OS);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000050}
51
Alexey Samsonov4316df52014-04-25 21:10:56 +000052const DWARFAbbreviationDeclaration *
53DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
54 uint32_t AbbrCode) const {
55 if (FirstAbbrCode == UINT32_MAX) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000056 for (const auto &Decl : Decls) {
Alexey Samsonov4316df52014-04-25 21:10:56 +000057 if (Decl.getCode() == AbbrCode)
Alexey Samsonov1eabf982014-03-13 07:52:54 +000058 return &Decl;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000059 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000060 return nullptr;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000061 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000062 if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
63 return nullptr;
64 return &Decls[AbbrCode - FirstAbbrCode];
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000065}
66
Alexey Samsonov4316df52014-04-25 21:10:56 +000067DWARFDebugAbbrev::DWARFDebugAbbrev() {
68 clear();
69}
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000070
Alexey Samsonov4316df52014-04-25 21:10:56 +000071void DWARFDebugAbbrev::clear() {
72 AbbrDeclSets.clear();
73 PrevAbbrOffsetPos = AbbrDeclSets.end();
74}
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000075
Alexey Samsonov4316df52014-04-25 21:10:56 +000076void DWARFDebugAbbrev::extract(DataExtractor Data) {
77 clear();
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000078
Alexey Samsonov4316df52014-04-25 21:10:56 +000079 uint32_t Offset = 0;
80 DWARFAbbreviationDeclarationSet AbbrDecls;
81 while (Data.isValidOffset(Offset)) {
82 uint32_t CUAbbrOffset = Offset;
83 if (!AbbrDecls.extract(Data, &Offset))
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000084 break;
Benjamin Kramerc6cc58e2014-10-04 16:55:56 +000085 AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000086 }
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000087}
88
89void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
Alexey Samsonov4316df52014-04-25 21:10:56 +000090 if (AbbrDeclSets.empty()) {
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000091 OS << "< EMPTY >\n";
92 return;
93 }
94
Alexey Samsonov4316df52014-04-25 21:10:56 +000095 for (const auto &I : AbbrDeclSets) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000096 OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
97 I.second.dump(OS);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000098 }
99}
100
101const DWARFAbbreviationDeclarationSet*
Alexey Samsonov9a5c95a2014-04-24 22:41:09 +0000102DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
Alexey Samsonov4316df52014-04-25 21:10:56 +0000103 const auto End = AbbrDeclSets.end();
Alexey Samsonov9a5c95a2014-04-24 22:41:09 +0000104 if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
Benjamin Kramereaa74332011-09-13 21:47:32 +0000105 return &(PrevAbbrOffsetPos->second);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000106 }
107
Alexey Samsonov4316df52014-04-25 21:10:56 +0000108 const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
Alexey Samsonov9a5c95a2014-04-24 22:41:09 +0000109 if (Pos != End) {
110 PrevAbbrOffsetPos = Pos;
111 return &(Pos->second);
112 }
113
Craig Topper2617dcc2014-04-15 06:32:26 +0000114 return nullptr;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000115}