1254721Semaste//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "DWARFDeclContext.h"
11254721Semaste
12254721Semasteconst char *
13254721SemasteDWARFDeclContext::GetQualifiedName () const
14254721Semaste{
15254721Semaste    if (m_qualified_name.empty())
16254721Semaste    {
17254721Semaste        // The declaration context array for a class named "foo" in namespace
18254721Semaste        // "a::b::c" will be something like:
19254721Semaste        //  [0] DW_TAG_class_type "foo"
20254721Semaste        //  [1] DW_TAG_namespace "c"
21254721Semaste        //  [2] DW_TAG_namespace "b"
22254721Semaste        //  [3] DW_TAG_namespace "a"
23254721Semaste        if (!m_entries.empty())
24254721Semaste        {
25254721Semaste            if (m_entries.size() == 1)
26254721Semaste            {
27254721Semaste                if (m_entries[0].name)
28254721Semaste                {
29254721Semaste                    m_qualified_name.append("::");
30254721Semaste                    m_qualified_name.append(m_entries[0].name);
31254721Semaste                }
32254721Semaste            }
33254721Semaste            else
34254721Semaste            {
35254721Semaste                collection::const_reverse_iterator pos;
36254721Semaste                collection::const_reverse_iterator begin = m_entries.rbegin();
37254721Semaste                collection::const_reverse_iterator end = m_entries.rend();
38254721Semaste                for (pos = begin; pos != end; ++pos)
39254721Semaste                {
40254721Semaste                    if (pos != begin)
41254721Semaste                        m_qualified_name.append("::");
42254721Semaste                    if (pos->name == NULL)
43254721Semaste                    {
44254721Semaste                        if (pos->tag == DW_TAG_namespace)
45254721Semaste                            m_qualified_name.append ("(anonymous namespace)");
46254721Semaste                        else if (pos->tag == DW_TAG_class_type)
47254721Semaste                            m_qualified_name.append ("(anonymous class)");
48254721Semaste                        else if (pos->tag == DW_TAG_structure_type)
49254721Semaste                            m_qualified_name.append ("(anonymous struct)");
50254721Semaste                        else if (pos->tag == DW_TAG_union_type)
51254721Semaste                            m_qualified_name.append ("(anonymous union)");
52254721Semaste                        else
53254721Semaste                            m_qualified_name.append ("(anonymous)");
54254721Semaste                    }
55254721Semaste                    else
56254721Semaste                        m_qualified_name.append(pos->name);
57254721Semaste                }
58254721Semaste            }
59254721Semaste        }
60254721Semaste    }
61254721Semaste    if (m_qualified_name.empty())
62254721Semaste        return NULL;
63254721Semaste    return m_qualified_name.c_str();
64254721Semaste}
65254721Semaste
66254721Semaste
67254721Semastebool
68254721SemasteDWARFDeclContext::operator==(const DWARFDeclContext& rhs) const
69254721Semaste{
70254721Semaste    if (m_entries.size() != rhs.m_entries.size())
71254721Semaste        return false;
72254721Semaste
73254721Semaste    collection::const_iterator pos;
74254721Semaste    collection::const_iterator begin = m_entries.begin();
75254721Semaste    collection::const_iterator end = m_entries.end();
76254721Semaste
77254721Semaste    collection::const_iterator rhs_pos;
78254721Semaste    collection::const_iterator rhs_begin = rhs.m_entries.begin();
79254721Semaste    // The two entry arrays have the same size
80254721Semaste
81254721Semaste    // First compare the tags before we do expensize name compares
82254721Semaste    for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
83254721Semaste    {
84254721Semaste        if (pos->tag != rhs_pos->tag)
85254721Semaste        {
86254721Semaste            // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
87254721Semaste            // used interchangeably in GCC
88254721Semaste            if (pos->tag == DW_TAG_structure_type && rhs_pos->tag == DW_TAG_class_type)
89254721Semaste                continue;
90254721Semaste            if (pos->tag == DW_TAG_class_type && rhs_pos->tag == DW_TAG_structure_type)
91254721Semaste                continue;
92254721Semaste            return false;
93254721Semaste        }
94254721Semaste    }
95254721Semaste    // The tags all match, now compare the names
96254721Semaste    for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
97254721Semaste    {
98254721Semaste        if (!pos->NameMatches (*rhs_pos))
99254721Semaste            return false;
100254721Semaste    }
101254721Semaste    // All tags and names match
102254721Semaste    return true;
103254721Semaste}
104254721Semaste
105