DWARFDeclContext.cpp revision 314564
1//===-- DWARFDeclContext.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 "DWARFDeclContext.h"
11
12const char *DWARFDeclContext::GetQualifiedName() const {
13  if (m_qualified_name.empty()) {
14    // The declaration context array for a class named "foo" in namespace
15    // "a::b::c" will be something like:
16    //  [0] DW_TAG_class_type "foo"
17    //  [1] DW_TAG_namespace "c"
18    //  [2] DW_TAG_namespace "b"
19    //  [3] DW_TAG_namespace "a"
20    if (!m_entries.empty()) {
21      if (m_entries.size() == 1) {
22        if (m_entries[0].name) {
23          m_qualified_name.append("::");
24          m_qualified_name.append(m_entries[0].name);
25        }
26      } else {
27        collection::const_reverse_iterator pos;
28        collection::const_reverse_iterator begin = m_entries.rbegin();
29        collection::const_reverse_iterator end = m_entries.rend();
30        for (pos = begin; pos != end; ++pos) {
31          if (pos != begin)
32            m_qualified_name.append("::");
33          if (pos->name == NULL) {
34            if (pos->tag == DW_TAG_namespace)
35              m_qualified_name.append("(anonymous namespace)");
36            else if (pos->tag == DW_TAG_class_type)
37              m_qualified_name.append("(anonymous class)");
38            else if (pos->tag == DW_TAG_structure_type)
39              m_qualified_name.append("(anonymous struct)");
40            else if (pos->tag == DW_TAG_union_type)
41              m_qualified_name.append("(anonymous union)");
42            else
43              m_qualified_name.append("(anonymous)");
44          } else
45            m_qualified_name.append(pos->name);
46        }
47      }
48    }
49  }
50  if (m_qualified_name.empty())
51    return NULL;
52  return m_qualified_name.c_str();
53}
54
55bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
56  if (m_entries.size() != rhs.m_entries.size())
57    return false;
58
59  collection::const_iterator pos;
60  collection::const_iterator begin = m_entries.begin();
61  collection::const_iterator end = m_entries.end();
62
63  collection::const_iterator rhs_pos;
64  collection::const_iterator rhs_begin = rhs.m_entries.begin();
65  // The two entry arrays have the same size
66
67  // First compare the tags before we do expensive name compares
68  for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
69    if (pos->tag != rhs_pos->tag) {
70      // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
71      // used interchangeably in GCC
72      if (pos->tag == DW_TAG_structure_type &&
73          rhs_pos->tag == DW_TAG_class_type)
74        continue;
75      if (pos->tag == DW_TAG_class_type &&
76          rhs_pos->tag == DW_TAG_structure_type)
77        continue;
78      return false;
79    }
80  }
81  // The tags all match, now compare the names
82  for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
83    if (!pos->NameMatches(*rhs_pos))
84      return false;
85  }
86  // All tags and names match
87  return true;
88}
89