1 //===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFASTParserJava.h"
11 #include "DWARFAttribute.h"
12 #include "DWARFCompileUnit.h"
13 #include "DWARFDebugInfoEntry.h"
14 #include "DWARFDebugInfoEntry.h"
15 #include "DWARFDeclContext.h"
16 #include "SymbolFileDWARF.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/SymbolContextScope.h"
21 #include "lldb/Symbol/TypeList.h"
24 using namespace lldb_private;
26 DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {}
28 DWARFASTParserJava::~DWARFASTParserJava() {}
30 TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) {
31 SymbolFileDWARF *dwarf = die.GetDWARF();
32 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
34 ConstString type_name;
35 uint64_t byte_size = 0;
37 DWARFAttributes attributes;
38 const size_t num_attributes = die.GetAttributes(attributes);
39 for (uint32_t i = 0; i < num_attributes; ++i) {
40 DWARFFormValue form_value;
41 dw_attr_t attr = attributes.AttributeAtIndex(i);
42 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
45 type_name.SetCString(form_value.AsCString());
48 byte_size = form_value.Unsigned();
53 assert(false && "Unsupported attribute for DW_TAG_base_type");
59 CompilerType compiler_type = m_ast.CreateBaseType(type_name);
60 return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
61 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
62 decl, compiler_type, Type::eResolveStateFull);
65 TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) {
66 SymbolFileDWARF *dwarf = die.GetDWARF();
67 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
69 ConstString linkage_name;
70 DWARFFormValue type_attr_value;
71 lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
72 DWARFExpression length_expression(die.GetCU());
74 DWARFAttributes attributes;
75 const size_t num_attributes = die.GetAttributes(attributes);
76 for (uint32_t i = 0; i < num_attributes; ++i) {
77 DWARFFormValue form_value;
78 dw_attr_t attr = attributes.AttributeAtIndex(i);
79 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
81 case DW_AT_linkage_name:
82 linkage_name.SetCString(form_value.AsCString());
85 type_attr_value = form_value;
87 case DW_AT_data_member_location:
88 data_offset = form_value.Unsigned();
90 case DW_AT_declaration:
93 assert(false && "Unsupported attribute for DW_TAG_array_type");
98 for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
99 child_die = child_die.GetSibling()) {
100 if (child_die.Tag() == DW_TAG_subrange_type) {
101 DWARFAttributes attributes;
102 const size_t num_attributes = child_die.GetAttributes(attributes);
103 for (uint32_t i = 0; i < num_attributes; ++i) {
104 DWARFFormValue form_value;
105 dw_attr_t attr = attributes.AttributeAtIndex(i);
106 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
109 if (form_value.BlockData())
110 length_expression.CopyOpcodeData(
111 form_value.BlockData(), form_value.Unsigned(),
112 child_die.GetCU()->GetByteOrder(),
113 child_die.GetCU()->GetAddressByteSize());
116 assert(false && "Unsupported attribute for DW_TAG_subrange_type");
121 assert(false && "Unsupported child for DW_TAG_array_type");
125 DIERef type_die_ref(type_attr_value);
126 Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
130 CompilerType element_compiler_type = element_type->GetForwardCompilerType();
131 CompilerType array_compiler_type = m_ast.CreateArrayType(
132 linkage_name, element_compiler_type, length_expression, data_offset);
135 TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(),
136 -1, nullptr, type_die_ref.GetUID(dwarf),
137 Type::eEncodingIsUID, &decl, array_compiler_type,
138 Type::eResolveStateFull));
139 type_sp->SetEncodingType(element_type);
143 TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) {
144 SymbolFileDWARF *dwarf = die.GetDWARF();
145 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
148 DWARFFormValue type_attr_value;
150 DWARFAttributes attributes;
151 const size_t num_attributes = die.GetAttributes(attributes);
152 for (uint32_t i = 0; i < num_attributes; ++i) {
153 DWARFFormValue form_value;
154 dw_attr_t attr = attributes.AttributeAtIndex(i);
155 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
158 type_attr_value = form_value;
161 assert(false && "Unsupported attribute for DW_TAG_array_type");
166 DIERef type_die_ref(type_attr_value);
167 Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
171 CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
172 CompilerType reference_compiler_type =
173 m_ast.CreateReferenceType(pointee_compiler_type);
175 new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1,
176 nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
177 reference_compiler_type, Type::eResolveStateFull));
178 type_sp->SetEncodingType(pointee_type);
182 lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die,
184 SymbolFileDWARF *dwarf = die.GetDWARF();
185 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
189 ConstString linkage_name;
190 bool is_forward_declaration = false;
191 uint32_t byte_size = 0;
193 DWARFAttributes attributes;
194 const size_t num_attributes = die.GetAttributes(attributes);
195 for (uint32_t i = 0; i < num_attributes; ++i) {
196 DWARFFormValue form_value;
197 dw_attr_t attr = attributes.AttributeAtIndex(i);
198 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
201 name.SetCString(form_value.AsCString());
203 case DW_AT_declaration:
204 is_forward_declaration = form_value.Boolean();
206 case DW_AT_byte_size:
207 byte_size = form_value.Unsigned();
209 case DW_AT_linkage_name:
210 linkage_name.SetCString(form_value.AsCString());
213 assert(false && "Unsupported attribute for DW_TAG_class_type");
218 UniqueDWARFASTType unique_ast_entry;
220 std::string qualified_name;
221 if (die.GetQualifiedName(qualified_name)) {
222 name.SetCString(qualified_name.c_str());
223 if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1,
225 if (unique_ast_entry.m_type_sp) {
226 dwarf->GetDIEToType()[die.GetDIE()] =
227 unique_ast_entry.m_type_sp.get();
229 return unique_ast_entry.m_type_sp;
235 if (is_forward_declaration) {
236 DWARFDeclContext die_decl_ctx;
237 die.GetDWARFDeclContext(die_decl_ctx);
239 TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
241 // We found a real definition for this type elsewhere so lets use it
242 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
248 CompilerType compiler_type(
249 &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
251 compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
254 TypeSP type_sp(new Type(die.GetID(), dwarf, name,
255 -1, // byte size isn't specified
256 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
257 &decl, compiler_type, Type::eResolveStateForward));
259 // Add our type to the unique type map
260 unique_ast_entry.m_type_sp = type_sp;
261 unique_ast_entry.m_die = die;
262 unique_ast_entry.m_declaration = decl;
263 unique_ast_entry.m_byte_size = -1;
264 dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
266 if (!is_forward_declaration) {
267 // Leave this as a forward declaration until we need to know the details of
269 dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
270 compiler_type.GetOpaqueQualType();
271 dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] =
277 lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
278 const lldb_private::SymbolContext &sc, const DWARFDIE &die,
279 lldb_private::Log *log, bool *type_is_new_ptr) {
281 *type_is_new_ptr = false;
286 SymbolFileDWARF *dwarf = die.GetDWARF();
288 Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
289 if (type_ptr == DIE_IS_BEING_PARSED)
291 if (type_ptr != nullptr)
292 return type_ptr->shared_from_this();
296 *type_is_new_ptr = true;
299 case DW_TAG_base_type: {
300 type_sp = ParseBaseTypeFromDIE(die);
303 case DW_TAG_array_type: {
304 type_sp = ParseArrayTypeFromDIE(die);
307 case DW_TAG_class_type: {
308 bool is_new_type = false;
309 type_sp = ParseClassTypeFromDIE(die, is_new_type);
314 case DW_TAG_reference_type: {
315 type_sp = ParseReferenceTypeFromDIE(die);
323 DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
324 dw_tag_t sc_parent_tag = sc_parent_die.Tag();
326 SymbolContextScope *symbol_context_scope = nullptr;
327 if (sc_parent_tag == DW_TAG_compile_unit) {
328 symbol_context_scope = sc.comp_unit;
329 } else if (sc.function != nullptr && sc_parent_die) {
330 symbol_context_scope =
331 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
332 if (symbol_context_scope == nullptr)
333 symbol_context_scope = sc.function;
336 if (symbol_context_scope != nullptr)
337 type_sp->SetSymbolContextScope(symbol_context_scope);
339 dwarf->GetTypeList()->Insert(type_sp);
340 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
345 lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF(
346 const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
347 assert(die.Tag() == DW_TAG_subprogram);
349 const char *name = nullptr;
350 const char *mangled = nullptr;
357 DWARFRangeList func_ranges;
358 DWARFExpression frame_base(die.GetCU());
360 if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
361 decl_column, call_file, call_line, call_column,
363 // Union of all ranges in the function DIE (if the function is
365 AddressRange func_range;
366 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
367 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
368 if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
369 lowest_func_addr <= highest_func_addr) {
370 ModuleSP module_sp(die.GetModule());
371 func_range.GetBaseAddress().ResolveAddressUsingFileSections(
372 lowest_func_addr, module_sp->GetSectionList());
373 if (func_range.GetBaseAddress().IsValid())
374 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
377 if (func_range.GetBaseAddress().IsValid()) {
378 std::unique_ptr<Declaration> decl_ap;
379 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
380 decl_ap.reset(new Declaration(
381 sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
382 decl_line, decl_column));
384 if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) {
385 FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
386 Mangled(ConstString(name), false),
387 nullptr, // No function types in java
389 if (frame_base.IsValid())
390 func_sp->GetFrameBaseExpression() = frame_base;
391 sc.comp_unit->AddFunction(func_sp);
393 return func_sp.get();
400 bool DWARFASTParserJava::CompleteTypeFromDWARF(
401 const DWARFDIE &die, lldb_private::Type *type,
402 lldb_private::CompilerType &java_type) {
404 case DW_TAG_class_type: {
405 if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) {
406 if (die.HasChildren())
407 ParseChildMembers(die, java_type);
408 m_ast.CompleteObjectType(java_type);
409 return java_type.IsValid();
413 assert(false && "Not a forward java type declaration!");
419 void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die,
420 CompilerType &compiler_type) {
421 DWARFCompileUnit *dwarf_cu = parent_die.GetCU();
422 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
423 die = die.GetSibling()) {
425 case DW_TAG_member: {
426 const char *name = nullptr;
427 DWARFFormValue encoding_uid;
428 uint32_t member_byte_offset = UINT32_MAX;
429 DWARFExpression member_location_expression(dwarf_cu);
431 DWARFAttributes attributes;
432 size_t num_attributes = die.GetAttributes(attributes);
433 for (size_t i = 0; i < num_attributes; ++i) {
434 DWARFFormValue form_value;
435 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
436 switch (attributes.AttributeAtIndex(i)) {
438 name = form_value.AsCString();
441 encoding_uid = form_value;
443 case DW_AT_data_member_location:
444 if (form_value.BlockData())
445 member_location_expression.CopyOpcodeData(
446 form_value.BlockData(), form_value.Unsigned(),
447 dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize());
449 member_byte_offset = form_value.Unsigned();
451 case DW_AT_artificial:
452 static_cast<void>(form_value.Boolean());
454 case DW_AT_accessibility:
455 // TODO: Handle when needed
458 assert(false && "Unhandled attribute for DW_TAG_member");
464 if (strcmp(name, ".dynamic_type") == 0)
465 m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
467 if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
468 m_ast.AddMemberToObject(compiler_type, ConstString(name),
469 member_type->GetFullCompilerType(),
474 case DW_TAG_inheritance: {
475 DWARFFormValue encoding_uid;
476 uint32_t member_byte_offset = UINT32_MAX;
478 DWARFAttributes attributes;
479 size_t num_attributes = die.GetAttributes(attributes);
480 for (size_t i = 0; i < num_attributes; ++i) {
481 DWARFFormValue form_value;
482 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
483 switch (attributes.AttributeAtIndex(i)) {
485 encoding_uid = form_value;
487 case DW_AT_data_member_location:
488 member_byte_offset = form_value.Unsigned();
490 case DW_AT_accessibility:
491 // In java all base class is public so we can ignore this attribute
494 assert(false && "Unhandled attribute for DW_TAG_member");
499 if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
500 m_ast.AddBaseClassToObject(compiler_type,
501 base_type->GetFullCompilerType(),