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