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