DWARFDeclContext.cpp revision 355940
1169689Skan//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===//
2169689Skan//
3169689Skan// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4169689Skan// See https://llvm.org/LICENSE.txt for license information.
5169689Skan// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6169689Skan//
7169689Skan//===----------------------------------------------------------------------===//
8169689Skan
9169689Skan#include "DWARFDeclContext.h"
10169689Skan
11169689Skanconst char *DWARFDeclContext::GetQualifiedName() const {
12169689Skan  if (m_qualified_name.empty()) {
13169689Skan    // The declaration context array for a class named "foo" in namespace
14169689Skan    // "a::b::c" will be something like:
15169689Skan    //  [0] DW_TAG_class_type "foo"
16169689Skan    //  [1] DW_TAG_namespace "c"
17169689Skan    //  [2] DW_TAG_namespace "b"
18169689Skan    //  [3] DW_TAG_namespace "a"
19169689Skan    if (!m_entries.empty()) {
20169689Skan      if (m_entries.size() == 1) {
21169689Skan        if (m_entries[0].name) {
22169689Skan          m_qualified_name.append("::");
23169689Skan          m_qualified_name.append(m_entries[0].name);
24169689Skan        }
25169689Skan      } else {
26169689Skan        collection::const_reverse_iterator pos;
27169689Skan        collection::const_reverse_iterator begin = m_entries.rbegin();
28169689Skan        collection::const_reverse_iterator end = m_entries.rend();
29169689Skan        for (pos = begin; pos != end; ++pos) {
30169689Skan          if (pos != begin)
31169689Skan            m_qualified_name.append("::");
32169689Skan          if (pos->name == nullptr) {
33169689Skan            if (pos->tag == DW_TAG_namespace)
34169689Skan              m_qualified_name.append("(anonymous namespace)");
35169689Skan            else if (pos->tag == DW_TAG_class_type)
36169689Skan              m_qualified_name.append("(anonymous class)");
37169689Skan            else if (pos->tag == DW_TAG_structure_type)
38169689Skan              m_qualified_name.append("(anonymous struct)");
39169689Skan            else if (pos->tag == DW_TAG_union_type)
40169689Skan              m_qualified_name.append("(anonymous union)");
41169689Skan            else
42169689Skan              m_qualified_name.append("(anonymous)");
43169689Skan          } else
44169689Skan            m_qualified_name.append(pos->name);
45169689Skan        }
46169689Skan      }
47169689Skan    }
48169689Skan  }
49169689Skan  if (m_qualified_name.empty())
50169689Skan    return nullptr;
51169689Skan  return m_qualified_name.c_str();
52169689Skan}
53169689Skan
54169689Skanbool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
55169689Skan  if (m_entries.size() != rhs.m_entries.size())
56169689Skan    return false;
57169689Skan
58169689Skan  collection::const_iterator pos;
59169689Skan  collection::const_iterator begin = m_entries.begin();
60169689Skan  collection::const_iterator end = m_entries.end();
61169689Skan
62169689Skan  collection::const_iterator rhs_pos;
63169689Skan  collection::const_iterator rhs_begin = rhs.m_entries.begin();
64169689Skan  // The two entry arrays have the same size
65169689Skan
66169689Skan  // First compare the tags before we do expensive name compares
67169689Skan  for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
68169689Skan    if (pos->tag != rhs_pos->tag) {
69169689Skan      // Check for DW_TAG_structure_type and DW_TAG_class_type as they are
70169689Skan      // often used interchangeably in GCC
71169689Skan      if (pos->tag == DW_TAG_structure_type &&
72169689Skan          rhs_pos->tag == DW_TAG_class_type)
73169689Skan        continue;
74169689Skan      if (pos->tag == DW_TAG_class_type &&
75169689Skan          rhs_pos->tag == DW_TAG_structure_type)
76169689Skan        continue;
77169689Skan      return false;
78169689Skan    }
79169689Skan  }
80169689Skan  // The tags all match, now compare the names
81169689Skan  for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
82169689Skan    if (!pos->NameMatches(*rhs_pos))
83169689Skan      return false;
84169689Skan  }
85169689Skan  // All tags and names match
86169689Skan  return true;
87169689Skan}
88169689Skan