1//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "UniqueDWARFASTType.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Symbol/Declaration.h"
17
18#include "DWARFDebugInfoEntry.h"
19
20bool
21UniqueDWARFASTTypeList::Find
22(
23    SymbolFileDWARF *symfile,
24    const DWARFCompileUnit *cu,
25    const DWARFDebugInfoEntry *die,
26    const lldb_private::Declaration &decl,
27    const int32_t byte_size,
28    UniqueDWARFASTType &entry
29) const
30{
31    collection::const_iterator pos, end = m_collection.end();
32    for (pos = m_collection.begin(); pos != end; ++pos)
33    {
34        // Make sure the tags match
35        if (pos->m_die->Tag() == die->Tag())
36        {
37            // Validate byte sizes of both types only if both are valid.
38            if (pos->m_byte_size < 0 || byte_size < 0 || pos->m_byte_size == byte_size)
39            {
40                // Make sure the file and line match
41                if (pos->m_declaration == decl)
42                {
43                    // The type has the same name, and was defined on the same
44                    // file and line. Now verify all of the parent DIEs match.
45                    const DWARFDebugInfoEntry *parent_arg_die = die->GetParent();
46                    const DWARFDebugInfoEntry *parend_pos_die = pos->m_die->GetParent();
47                    bool match = true;
48                    bool done = false;
49                    while (!done && match && parent_arg_die && parend_pos_die)
50                    {
51                        if (parent_arg_die->Tag() == parend_pos_die->Tag())
52                        {
53                            const dw_tag_t tag = parent_arg_die->Tag();
54                            switch (tag)
55                            {
56                            case DW_TAG_class_type:
57                            case DW_TAG_structure_type:
58                            case DW_TAG_union_type:
59                            case DW_TAG_namespace:
60                                {
61                                    const char *parent_arg_die_name = parent_arg_die->GetName(symfile, cu);
62                                    if (parent_arg_die_name == NULL)  // Anonymous (i.e. no-name) struct
63                                    {
64                                        match = false;
65                                    }
66                                    else
67                                    {
68                                        const char *parent_pos_die_name = parend_pos_die->GetName(pos->m_symfile, pos->m_cu);
69                                        if (parent_pos_die_name == NULL || strcmp (parent_arg_die_name, parent_pos_die_name))
70                                            match = false;
71                                    }
72                                }
73                                break;
74
75                            case DW_TAG_compile_unit:
76                                done = true;
77                                break;
78                            }
79                        }
80                        parent_arg_die = parent_arg_die->GetParent();
81                        parend_pos_die = parend_pos_die->GetParent();
82                    }
83
84                    if (match)
85                    {
86                        entry = *pos;
87                        return true;
88                    }
89                }
90            }
91        }
92    }
93    return false;
94}
95