1104477Ssam//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
2104477Ssam//
3104477Ssam// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4104477Ssam// See https://llvm.org/LICENSE.txt for license information.
5104477Ssam// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6104477Ssam//
7104477Ssam//===----------------------------------------------------------------------===//
8104477Ssam
9104477Ssam#include "DWARFAbbreviationDeclaration.h"
10104477Ssam
11104477Ssam#include "lldb/Core/dwarf.h"
12104477Ssam#include "lldb/Utility/Stream.h"
13104477Ssam
14104477Ssam#include "llvm/Object/Error.h"
15104477Ssam
16104477Ssam#include "DWARFFormValue.h"
17104477Ssam
18104477Ssamusing namespace lldb_private;
19104477Ssam
20104477SsamDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
21104477Ssam    : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
22104477Ssam      m_attributes() {}
23104477Ssam
24104477SsamDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
25104477Ssam                                                           uint8_t has_children)
26104477Ssam    : m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
27104477Ssam      m_attributes() {}
28104477Ssam
29104477Ssamllvm::Expected<DWARFEnumState>
30104477SsamDWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
31104477Ssam                                      lldb::offset_t *offset_ptr) {
32104477Ssam  m_code = data.GetULEB128(offset_ptr);
33104477Ssam  if (m_code == 0)
34104477Ssam    return DWARFEnumState::Complete;
35104477Ssam
36104477Ssam  m_attributes.clear();
37104477Ssam  m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr));
38104477Ssam  if (m_tag == DW_TAG_null)
39104477Ssam    return llvm::make_error<llvm::object::GenericBinaryError>(
40104477Ssam        "abbrev decl requires non-null tag.");
41104477Ssam
42104477Ssam  m_has_children = data.GetU8(offset_ptr);
43104477Ssam
44104477Ssam  while (data.ValidOffset(*offset_ptr)) {
45104477Ssam    dw_attr_t attr = data.GetULEB128(offset_ptr);
46104477Ssam    dw_form_t form = data.GetULEB128(offset_ptr);
47104477Ssam
48104477Ssam    // This is the last attribute for this abbrev decl, but there may still be
49104477Ssam    // more abbrev decls, so return MoreItems to indicate to the caller that
50104477Ssam    // they should call this function again.
51104477Ssam    if (!attr && !form)
52104477Ssam      return DWARFEnumState::MoreItems;
53104477Ssam
54104477Ssam    if (!attr || !form)
55104477Ssam      return llvm::make_error<llvm::object::GenericBinaryError>(
56104477Ssam          "malformed abbreviation declaration attribute");
57104477Ssam
58104477Ssam    DWARFFormValue::ValueType val;
59104477Ssam
60104477Ssam    if (form == DW_FORM_implicit_const)
61104477Ssam      val.value.sval = data.GetULEB128(offset_ptr);
62104477Ssam
63104477Ssam    m_attributes.push_back(DWARFAttribute(attr, form, val));
64104477Ssam  }
65104477Ssam
66104477Ssam  return llvm::make_error<llvm::object::GenericBinaryError>(
67104477Ssam      "abbreviation declaration attribute list not terminated with a null "
68104477Ssam      "entry");
69104477Ssam}
70104477Ssam
71104477Ssambool DWARFAbbreviationDeclaration::IsValid() {
72104477Ssam  return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null;
73104477Ssam}
74104477Ssam
75104477Ssamuint32_t
76104477SsamDWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
77104477Ssam  uint32_t i;
78104477Ssam  const uint32_t kNumAttributes = m_attributes.size();
79104477Ssam  for (i = 0; i < kNumAttributes; ++i) {
80104477Ssam    if (m_attributes[i].get_attr() == attr)
81104477Ssam      return i;
82104477Ssam  }
83104477Ssam  return DW_INVALID_INDEX;
84104477Ssam}
85104477Ssam
86104477Ssambool DWARFAbbreviationDeclaration::
87104477Ssamoperator==(const DWARFAbbreviationDeclaration &rhs) const {
88104477Ssam  return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
89104477Ssam         m_attributes == rhs.m_attributes;
90104477Ssam}
91104477Ssam