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 bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
17                                   const lldb_private::Declaration &decl,
18                                   const int32_t byte_size,
19                                   UniqueDWARFASTType &entry) const {
20   for (const UniqueDWARFASTType &udt : m_collection) {
21     // Make sure the tags match
22     if (udt.m_die.Tag() == die.Tag()) {
23       // Validate byte sizes of both types only if both are valid.
24       if (udt.m_byte_size < 0 || byte_size < 0 ||
25           udt.m_byte_size == byte_size) {
26         // Make sure the file and line match
27         if (udt.m_declaration == decl) {
28           // The type has the same name, and was defined on the same file and
29           // line. Now verify all of the parent DIEs match.
30           DWARFDIE parent_arg_die = die.GetParent();
31           DWARFDIE parent_pos_die = udt.m_die.GetParent();
32           bool match = true;
33           bool done = false;
34           while (!done && match && parent_arg_die && parent_pos_die) {
35             const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
36             const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
37             if (parent_arg_tag == parent_pos_tag) {
38               switch (parent_arg_tag) {
39               case DW_TAG_class_type:
40               case DW_TAG_structure_type:
41               case DW_TAG_union_type:
42               case DW_TAG_namespace: {
43                 const char *parent_arg_die_name = parent_arg_die.GetName();
44                 if (parent_arg_die_name ==
45                     nullptr) // Anonymous (i.e. no-name) struct
46                 {
47                   match = false;
48                 } else {
49                   const char *parent_pos_die_name = parent_pos_die.GetName();
50                   if (parent_pos_die_name == nullptr ||
51                       ((parent_arg_die_name != parent_pos_die_name) &&
52                        strcmp(parent_arg_die_name, parent_pos_die_name)))
53                     match = false;
54                 }
55               } break;
56 
57               case DW_TAG_compile_unit:
58               case DW_TAG_partial_unit:
59                 done = true;
60                 break;
61               default:
62                 break;
63               }
64             }
65             parent_arg_die = parent_arg_die.GetParent();
66             parent_pos_die = parent_pos_die.GetParent();
67           }
68 
69           if (match) {
70             entry = udt;
71             return true;
72           }
73         }
74       }
75     }
76   }
77   return false;
78 }
79