void DWARFASTParserGo::ParseChildArrayInfo(const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, std::vector<uint64_t> &element_orders, uint32_t &byte_stride, uint32_t &bit_stride) { if (!parent_die) return; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { const dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_subrange_type: { DWARFAttributes attributes; const size_t num_child_attributes = die.GetAttributes(attributes); if (num_child_attributes > 0) { uint64_t num_elements = 0; uint32_t i; for (i = 0; i < num_child_attributes; ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_count: num_elements = form_value.Unsigned(); break; default: case DW_AT_type: break; } } } element_orders.push_back(num_elements); } } break; } } }
size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_compiler_type) { size_t count = 0; uint32_t member_idx = 0; ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem()); if (ast == nullptr) return 0; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_member: { DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); if (num_attributes > 0) { Declaration decl; const char *name = NULL; lldb::user_id_t encoding_uid = LLDB_INVALID_UID; uint32_t member_byte_offset = UINT32_MAX; uint32_t i; for (i = 0; i < num_attributes; ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_name: name = form_value.AsCString(); break; case DW_AT_type: encoding_uid = form_value.Reference(); break; case DW_AT_data_member_location: if (form_value.BlockData()) { Value initialValue(0); Value memberOffset(0); const DWARFDataExtractor &debug_info_data = die.GetDWARF()->get_debug_info_data(); uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); if (DWARFExpression::Evaluate(NULL, // ExecutionContext * NULL, // ClangExpressionVariableList * NULL, // ClangExpressionDeclMap * NULL, // RegisterContext * module_sp, debug_info_data, die.GetCU(), block_offset, block_length, eRegisterKindDWARF, &initialValue, NULL, memberOffset, NULL)) { member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); } } else { // With DWARF 3 and later, if the value is an integer constant, // this form value is the offset in bytes from the beginning // of the containing entity. member_byte_offset = form_value.Unsigned(); } break; default: break; } } } Type *member_type = die.ResolveTypeUID(encoding_uid); if (member_type) { CompilerType member_go_type = member_type->GetFullCompilerType(); ConstString name_const_str(name); m_ast.AddFieldToStruct(class_compiler_type, name_const_str, member_go_type, member_byte_offset); } } ++member_idx; } break; default: break; } } return count; }
size_t DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc, const DWARFDIE &parent_die, bool &is_variadic, std::vector<CompilerType> &function_param_types) { if (!parent_die) return 0; size_t arg_idx = 0; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_formal_parameter: { DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); if (num_attributes > 0) { Declaration decl; dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; uint32_t i; for (i = 0; i < num_attributes; ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_name: // = form_value.AsCString(); break; case DW_AT_type: param_type_die_offset = form_value.Reference(); break; case DW_AT_location: // if (form_value.BlockData()) // { // const DWARFDataExtractor& debug_info_data = // debug_info(); // uint32_t block_length = form_value.Unsigned(); // DWARFDataExtractor location(debug_info_data, // form_value.BlockData() - debug_info_data.GetDataStart(), // block_length); // } // else // { // } // break; default: break; } } } Type *type = parent_die.ResolveTypeUID(param_type_die_offset); if (type) { function_param_types.push_back(type->GetForwardCompilerType()); } } arg_idx++; } break; case DW_TAG_unspecified_parameters: is_variadic = true; break; default: break; } } return arg_idx; }
void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type) { DWARFCompileUnit *dwarf_cu = parent_die.GetCU(); for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { switch (die.Tag()) { case DW_TAG_member: { const char *name = nullptr; DWARFFormValue encoding_uid; uint32_t member_byte_offset = UINT32_MAX; DWARFExpression member_location_expression(dwarf_cu); bool artificial = true; DWARFAttributes attributes; size_t num_attributes = die.GetAttributes(attributes); for (size_t i = 0; i < num_attributes; ++i) { DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attributes.AttributeAtIndex(i)) { case DW_AT_name: name = form_value.AsCString(); break; case DW_AT_type: encoding_uid = form_value; break; case DW_AT_data_member_location: if (form_value.BlockData()) member_location_expression.CopyOpcodeData( form_value.BlockData(), form_value.Unsigned(), dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize()); else member_byte_offset = form_value.Unsigned(); break; case DW_AT_artificial: artificial = form_value.Boolean(); break; case DW_AT_accessibility: // TODO: Handle when needed break; default: assert(false && "Unhandled attribute for DW_TAG_member"); break; } } } if (strcmp(name, ".dynamic_type") == 0) m_ast.SetDynamicTypeId(compiler_type, member_location_expression); else { if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid))) m_ast.AddMemberToObject(compiler_type, ConstString(name), member_type->GetFullCompilerType(), member_byte_offset); } break; } case DW_TAG_inheritance: { DWARFFormValue encoding_uid; uint32_t member_byte_offset = UINT32_MAX; DWARFAttributes attributes; size_t num_attributes = die.GetAttributes(attributes); for (size_t i = 0; i < num_attributes; ++i) { DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attributes.AttributeAtIndex(i)) { case DW_AT_type: encoding_uid = form_value; break; case DW_AT_data_member_location: member_byte_offset = form_value.Unsigned(); break; case DW_AT_accessibility: // In java all base class is public so we can ignore this attribute break; default: assert(false && "Unhandled attribute for DW_TAG_member"); break; } } } if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid))) m_ast.AddBaseClassToObject(compiler_type, base_type->GetFullCompilerType(), member_byte_offset); break; } default: break; } } }