1 //===-- UniqueDWARFASTType.cpp --------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "UniqueDWARFASTType.h" 10 11 #include "lldb/Core/Declaration.h" 12 13 using namespace lldb_private::dwarf; 14 using namespace lldb_private::plugin::dwarf; 15 16 static bool IsStructOrClassTag(llvm::dwarf::Tag Tag) { 17 return Tag == llvm::dwarf::Tag::DW_TAG_class_type || 18 Tag == llvm::dwarf::Tag::DW_TAG_structure_type; 19 } 20 21 UniqueDWARFASTType *UniqueDWARFASTTypeList::Find( 22 const DWARFDIE &die, const lldb_private::Declaration &decl, 23 const int32_t byte_size, bool is_forward_declaration) { 24 for (UniqueDWARFASTType &udt : m_collection) { 25 // Make sure the tags match 26 if (udt.m_die.Tag() == die.Tag() || (IsStructOrClassTag(udt.m_die.Tag()) && 27 IsStructOrClassTag(die.Tag()))) { 28 // If they are not both definition DIEs or both declaration DIEs, then 29 // don't check for byte size and declaration location, because declaration 30 // DIEs usually don't have those info. 31 bool matching_size_declaration = 32 udt.m_is_forward_declaration != is_forward_declaration 33 ? true 34 : (udt.m_byte_size < 0 || byte_size < 0 || 35 udt.m_byte_size == byte_size) && 36 udt.m_declaration == decl; 37 if (!matching_size_declaration) 38 continue; 39 // The type has the same name, and was defined on the same file and 40 // line. Now verify all of the parent DIEs match. 41 DWARFDIE parent_arg_die = die.GetParent(); 42 DWARFDIE parent_pos_die = udt.m_die.GetParent(); 43 bool match = true; 44 bool done = false; 45 while (!done && match && parent_arg_die && parent_pos_die) { 46 const dw_tag_t parent_arg_tag = parent_arg_die.Tag(); 47 const dw_tag_t parent_pos_tag = parent_pos_die.Tag(); 48 if (parent_arg_tag == parent_pos_tag || 49 (IsStructOrClassTag(parent_arg_tag) && 50 IsStructOrClassTag(parent_pos_tag))) { 51 switch (parent_arg_tag) { 52 case DW_TAG_class_type: 53 case DW_TAG_structure_type: 54 case DW_TAG_union_type: 55 case DW_TAG_namespace: { 56 const char *parent_arg_die_name = parent_arg_die.GetName(); 57 if (parent_arg_die_name == nullptr) { 58 // Anonymous (i.e. no-name) struct 59 match = false; 60 } else { 61 const char *parent_pos_die_name = parent_pos_die.GetName(); 62 if (parent_pos_die_name == nullptr || 63 ((parent_arg_die_name != parent_pos_die_name) && 64 strcmp(parent_arg_die_name, parent_pos_die_name))) 65 match = false; 66 } 67 } break; 68 69 case DW_TAG_compile_unit: 70 case DW_TAG_partial_unit: 71 done = true; 72 break; 73 default: 74 break; 75 } 76 } 77 parent_arg_die = parent_arg_die.GetParent(); 78 parent_pos_die = parent_pos_die.GetParent(); 79 } 80 81 if (match) { 82 return &udt; 83 } 84 } 85 } 86 return nullptr; 87 } 88