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