reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "UniqueDWARFASTType.h"

#include "lldb/Symbol/Declaration.h"

bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
                                  const lldb_private::Declaration &decl,
                                  const int32_t byte_size,
                                  UniqueDWARFASTType &entry) const {
  for (const UniqueDWARFASTType &udt : m_collection) {
    // Make sure the tags match
    if (udt.m_die.Tag() == die.Tag()) {
      // Validate byte sizes of both types only if both are valid.
      if (udt.m_byte_size < 0 || byte_size < 0 ||
          udt.m_byte_size == byte_size) {
        // Make sure the file and line match
        if (udt.m_declaration == decl) {
          // The type has the same name, and was defined on the same file and
          // line. Now verify all of the parent DIEs match.
          DWARFDIE parent_arg_die = die.GetParent();
          DWARFDIE parent_pos_die = udt.m_die.GetParent();
          bool match = true;
          bool done = false;
          while (!done && match && parent_arg_die && parent_pos_die) {
            const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
            const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
            if (parent_arg_tag == parent_pos_tag) {
              switch (parent_arg_tag) {
              case DW_TAG_class_type:
              case DW_TAG_structure_type:
              case DW_TAG_union_type:
              case DW_TAG_namespace: {
                const char *parent_arg_die_name = parent_arg_die.GetName();
                if (parent_arg_die_name ==
                    nullptr) // Anonymous (i.e. no-name) struct
                {
                  match = false;
                } else {
                  const char *parent_pos_die_name = parent_pos_die.GetName();
                  if (parent_pos_die_name == nullptr ||
                      ((parent_arg_die_name != parent_pos_die_name) &&
                       strcmp(parent_arg_die_name, parent_pos_die_name)))
                    match = false;
                }
              } break;

              case DW_TAG_compile_unit:
              case DW_TAG_partial_unit:
                done = true;
                break;
              default:
                break;
              }
            }
            parent_arg_die = parent_arg_die.GetParent();
            parent_pos_die = parent_pos_die.GetParent();
          }

          if (match) {
            entry = udt;
            return true;
          }
        }
      }
    }
  }
  return false;
}