1 //===-- DWARFDeclContext.cpp ----------------------------------------------===// 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 GetQualifiedName() const11const 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 operator ==(const DWARFDeclContext & rhs) const54bool 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 } 88