1 //===-- DWARFDIE.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 "DWARFDIE.h" 11 12 #include "DWARFASTParser.h" 13 #include "DWARFDIECollection.h" 14 #include "DWARFDebugInfo.h" 15 #include "DWARFDebugInfoEntry.h" 16 #include "DWARFDeclContext.h" 17 #include "DWARFUnit.h" 18 19 using namespace lldb_private; 20 21 void DWARFDIE::ElaboratingDIEIterator::Next() { 22 assert(!m_worklist.empty() && "Incrementing end iterator?"); 23 24 // Pop the current item from the list. 25 DWARFDIE die = m_worklist.back(); 26 m_worklist.pop_back(); 27 28 // And add back any items that elaborate it. 29 for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) { 30 if (DWARFDIE d = die.GetReferencedDIE(attr)) 31 if (m_seen.insert(die.GetID()).second) 32 m_worklist.push_back(d); 33 } 34 } 35 36 DWARFDIE 37 DWARFDIE::GetParent() const { 38 if (IsValid()) 39 return DWARFDIE(m_cu, m_die->GetParent()); 40 else 41 return DWARFDIE(); 42 } 43 44 DWARFDIE 45 DWARFDIE::GetFirstChild() const { 46 if (IsValid()) 47 return DWARFDIE(m_cu, m_die->GetFirstChild()); 48 else 49 return DWARFDIE(); 50 } 51 52 DWARFDIE 53 DWARFDIE::GetSibling() const { 54 if (IsValid()) 55 return DWARFDIE(m_cu, m_die->GetSibling()); 56 else 57 return DWARFDIE(); 58 } 59 60 DWARFDIE 61 DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const { 62 const dw_offset_t die_offset = 63 GetAttributeValueAsReference(attr, DW_INVALID_OFFSET); 64 if (die_offset != DW_INVALID_OFFSET) 65 return GetDIE(die_offset); 66 else 67 return DWARFDIE(); 68 } 69 70 DWARFDIE 71 DWARFDIE::GetDIE(dw_offset_t die_offset) const { 72 if (IsValid()) 73 return m_cu->GetDIE(die_offset); 74 else 75 return DWARFDIE(); 76 } 77 78 DWARFDIE 79 DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const { 80 if (IsValid()) { 81 DWARFUnit *cu = GetCU(); 82 SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF(); 83 const bool check_specification_or_abstract_origin = true; 84 DWARFFormValue form_value; 85 if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr, 86 check_specification_or_abstract_origin)) 87 return dwarf->GetDIE(DIERef(form_value)); 88 } 89 return DWARFDIE(); 90 } 91 92 DWARFDIE 93 DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const { 94 if (IsValid()) { 95 SymbolFileDWARF *dwarf = GetDWARF(); 96 DWARFUnit *cu = GetCU(); 97 DWARFDebugInfoEntry *function_die = nullptr; 98 DWARFDebugInfoEntry *block_die = nullptr; 99 if (m_die->LookupAddress(file_addr, dwarf, cu, &function_die, &block_die)) { 100 if (block_die && block_die != function_die) { 101 if (cu->ContainsDIEOffset(block_die->GetOffset())) 102 return DWARFDIE(cu, block_die); 103 else 104 return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit( 105 DIERef(cu->GetOffset(), block_die->GetOffset())), 106 block_die); 107 } 108 } 109 } 110 return DWARFDIE(); 111 } 112 113 const char *DWARFDIE::GetMangledName() const { 114 if (IsValid()) 115 return m_die->GetMangledName(GetDWARF(), m_cu); 116 else 117 return nullptr; 118 } 119 120 const char *DWARFDIE::GetPubname() const { 121 if (IsValid()) 122 return m_die->GetPubname(GetDWARF(), m_cu); 123 else 124 return nullptr; 125 } 126 127 const char *DWARFDIE::GetQualifiedName(std::string &storage) const { 128 if (IsValid()) 129 return m_die->GetQualifiedName(GetDWARF(), m_cu, storage); 130 else 131 return nullptr; 132 } 133 134 lldb_private::Type *DWARFDIE::ResolveType() const { 135 if (IsValid()) 136 return GetDWARF()->ResolveType(*this, true); 137 else 138 return nullptr; 139 } 140 141 lldb_private::Type *DWARFDIE::ResolveTypeUID(const DIERef &die_ref) const { 142 SymbolFileDWARF *dwarf = GetDWARF(); 143 if (dwarf) 144 return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true); 145 else 146 return nullptr; 147 } 148 149 void DWARFDIE::GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const { 150 if (IsValid()) { 151 DWARFDIE parent_decl_ctx_die = 152 m_die->GetParentDeclContextDIE(GetDWARF(), GetCU()); 153 if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) { 154 decl_context_dies.Append(parent_decl_ctx_die); 155 parent_decl_ctx_die.GetDeclContextDIEs(decl_context_dies); 156 } 157 } 158 } 159 160 void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { 161 if (IsValid()) { 162 dwarf_decl_ctx.SetLanguage(GetLanguage()); 163 m_die->GetDWARFDeclContext(GetDWARF(), GetCU(), dwarf_decl_ctx); 164 } else { 165 dwarf_decl_ctx.Clear(); 166 } 167 } 168 169 void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const { 170 const dw_tag_t tag = Tag(); 171 if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) 172 return; 173 DWARFDIE parent = GetParent(); 174 if (parent) 175 parent.GetDWOContext(context); 176 switch (tag) { 177 case DW_TAG_module: 178 context.push_back( 179 CompilerContext(CompilerContextKind::Module, ConstString(GetName()))); 180 break; 181 case DW_TAG_namespace: 182 context.push_back(CompilerContext(CompilerContextKind::Namespace, 183 ConstString(GetName()))); 184 break; 185 case DW_TAG_structure_type: 186 context.push_back(CompilerContext(CompilerContextKind::Structure, 187 ConstString(GetName()))); 188 break; 189 case DW_TAG_union_type: 190 context.push_back( 191 CompilerContext(CompilerContextKind::Union, ConstString(GetName()))); 192 break; 193 case DW_TAG_class_type: 194 context.push_back( 195 CompilerContext(CompilerContextKind::Class, ConstString(GetName()))); 196 break; 197 case DW_TAG_enumeration_type: 198 context.push_back(CompilerContext(CompilerContextKind::Enumeration, 199 ConstString(GetName()))); 200 break; 201 case DW_TAG_subprogram: 202 context.push_back(CompilerContext(CompilerContextKind::Function, 203 ConstString(GetPubname()))); 204 break; 205 case DW_TAG_variable: 206 context.push_back(CompilerContext(CompilerContextKind::Variable, 207 ConstString(GetPubname()))); 208 break; 209 case DW_TAG_typedef: 210 context.push_back( 211 CompilerContext(CompilerContextKind::Typedef, ConstString(GetName()))); 212 break; 213 default: 214 break; 215 } 216 } 217 218 DWARFDIE 219 DWARFDIE::GetParentDeclContextDIE() const { 220 if (IsValid()) 221 return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu); 222 else 223 return DWARFDIE(); 224 } 225 226 bool DWARFDIE::IsStructUnionOrClass() const { 227 const dw_tag_t tag = Tag(); 228 return tag == DW_TAG_class_type || tag == DW_TAG_structure_type || 229 tag == DW_TAG_union_type; 230 } 231 232 bool DWARFDIE::IsMethod() const { 233 for (DWARFDIE d: elaborating_dies()) 234 if (d.GetParent().IsStructUnionOrClass()) 235 return true; 236 return false; 237 } 238 239 DWARFDIE 240 DWARFDIE::GetContainingDWOModuleDIE() const { 241 if (IsValid()) { 242 DWARFDIE top_module_die; 243 // Now make sure this DIE is scoped in a DW_TAG_module tag and return true 244 // if so 245 for (DWARFDIE parent = GetParent(); parent.IsValid(); 246 parent = parent.GetParent()) { 247 const dw_tag_t tag = parent.Tag(); 248 if (tag == DW_TAG_module) 249 top_module_die = parent; 250 else if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) 251 break; 252 } 253 254 return top_module_die; 255 } 256 return DWARFDIE(); 257 } 258 259 lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const { 260 if (IsValid()) { 261 DWARFDIE dwo_module_die = GetContainingDWOModuleDIE(); 262 263 if (dwo_module_die) { 264 const char *module_name = dwo_module_die.GetName(); 265 if (module_name) 266 return GetDWARF()->GetDWOModule(lldb_private::ConstString(module_name)); 267 } 268 } 269 return lldb::ModuleSP(); 270 } 271 272 bool DWARFDIE::GetDIENamesAndRanges( 273 const char *&name, const char *&mangled, DWARFRangeList &ranges, 274 int &decl_file, int &decl_line, int &decl_column, int &call_file, 275 int &call_line, int &call_column, 276 lldb_private::DWARFExpression *frame_base) const { 277 if (IsValid()) { 278 return m_die->GetDIENamesAndRanges( 279 GetDWARF(), GetCU(), name, mangled, ranges, decl_file, decl_line, 280 decl_column, call_file, call_line, call_column, frame_base); 281 } else 282 return false; 283 } 284 285 CompilerDecl DWARFDIE::GetDecl() const { 286 DWARFASTParser *dwarf_ast = GetDWARFParser(); 287 if (dwarf_ast) 288 return dwarf_ast->GetDeclForUIDFromDWARF(*this); 289 else 290 return CompilerDecl(); 291 } 292 293 CompilerDeclContext DWARFDIE::GetDeclContext() const { 294 DWARFASTParser *dwarf_ast = GetDWARFParser(); 295 if (dwarf_ast) 296 return dwarf_ast->GetDeclContextForUIDFromDWARF(*this); 297 else 298 return CompilerDeclContext(); 299 } 300 301 CompilerDeclContext DWARFDIE::GetContainingDeclContext() const { 302 DWARFASTParser *dwarf_ast = GetDWARFParser(); 303 if (dwarf_ast) 304 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this); 305 else 306 return CompilerDeclContext(); 307 } 308