117721Speter//===-- UniqueDWARFASTType.cpp --------------------------------------------===//
2175261Sobrien//
3175261Sobrien// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4175261Sobrien// See https://llvm.org/LICENSE.txt for license information.
5175261Sobrien// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6175261Sobrien//
7175261Sobrien//===----------------------------------------------------------------------===//
8175261Sobrien
917721Speter#include "UniqueDWARFASTType.h"
1017721Speter
1132785Speter#include "lldb/Core/Declaration.h"
1217721Speter
1317721Speterusing namespace lldb_private::dwarf;
1432785Speterusing namespace lldb_private::plugin::dwarf;
1517721Speter
1625839Speterbool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
1717721Speter                                  const lldb_private::Declaration &decl,
1817721Speter                                  const int32_t byte_size,
1917721Speter                                  UniqueDWARFASTType &entry) const {
2017721Speter  for (const UniqueDWARFASTType &udt : m_collection) {
2117721Speter    // Make sure the tags match
2217721Speter    if (udt.m_die.Tag() == die.Tag()) {
2317721Speter      // Validate byte sizes of both types only if both are valid.
2417721Speter      if (udt.m_byte_size < 0 || byte_size < 0 ||
2517721Speter          udt.m_byte_size == byte_size) {
2617721Speter        // Make sure the file and line match
2717721Speter        if (udt.m_declaration == decl) {
2817721Speter          // The type has the same name, and was defined on the same file and
29128266Speter          // line. Now verify all of the parent DIEs match.
30128266Speter          DWARFDIE parent_arg_die = die.GetParent();
3117721Speter          DWARFDIE parent_pos_die = udt.m_die.GetParent();
3217721Speter          bool match = true;
33128266Speter          bool done = false;
3425839Speter          while (!done && match && parent_arg_die && parent_pos_die) {
3525839Speter            const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
3625839Speter            const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
3717721Speter            if (parent_arg_tag == parent_pos_tag) {
3817721Speter              switch (parent_arg_tag) {
3917721Speter              case DW_TAG_class_type:
4017721Speter              case DW_TAG_structure_type:
4117721Speter              case DW_TAG_union_type:
4217721Speter              case DW_TAG_namespace: {
4317721Speter                const char *parent_arg_die_name = parent_arg_die.GetName();
4417721Speter                if (parent_arg_die_name ==
4517721Speter                    nullptr) // Anonymous (i.e. no-name) struct
4625839Speter                {
4725839Speter                  match = false;
4817721Speter                } else {
4917721Speter                  const char *parent_pos_die_name = parent_pos_die.GetName();
5025839Speter                  if (parent_pos_die_name == nullptr ||
5117721Speter                      ((parent_arg_die_name != parent_pos_die_name) &&
5217721Speter                       strcmp(parent_arg_die_name, parent_pos_die_name)))
5317721Speter                    match = false;
5417721Speter                }
5517721Speter              } break;
5625839Speter
5717721Speter              case DW_TAG_compile_unit:
5825839Speter              case DW_TAG_partial_unit:
5917721Speter                done = true;
6025839Speter                break;
6125839Speter              default:
6225839Speter                break;
6325839Speter              }
6425839Speter            }
6525839Speter            parent_arg_die = parent_arg_die.GetParent();
6625839Speter            parent_pos_die = parent_pos_die.GetParent();
6725839Speter          }
6825839Speter
6925839Speter          if (match) {
7025839Speter            entry = udt;
7125839Speter            return true;
7225839Speter          }
7325839Speter        }
7425839Speter      }
7525839Speter    }
7625839Speter  }
7725839Speter  return false;
7825839Speter}
7925839Speter