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