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;
}
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;
}
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;
        }
    }
}