Exemplo n.º 1
0
TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) {
  SymbolFileDWARF *dwarf = die.GetDWARF();
  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

  ConstString type_name;
  uint64_t byte_size = 0;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  for (uint32_t i = 0; i < num_attributes; ++i) {
    DWARFFormValue form_value;
    dw_attr_t attr = attributes.AttributeAtIndex(i);
    if (attributes.ExtractFormValueAtIndex(i, form_value)) {
      switch (attr) {
      case DW_AT_name:
        type_name.SetCString(form_value.AsCString());
        break;
      case DW_AT_byte_size:
        byte_size = form_value.Unsigned();
        break;
      case DW_AT_encoding:
        break;
      default:
        assert(false && "Unsupported attribute for DW_TAG_base_type");
      }
    }
  }

  Declaration decl;
  CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size);
  return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
                                nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
                                decl, compiler_type, Type::eResolveStateFull);
}
TypeSP
DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die)
{
    SymbolFileDWARF *dwarf = die.GetDWARF();
    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

    Declaration decl;
    DWARFFormValue type_attr_value;

    DWARFAttributes attributes;
    const size_t num_attributes = die.GetAttributes(attributes);
    for (uint32_t i = 0; i < num_attributes; ++i)
    {
        DWARFFormValue form_value;
        dw_attr_t attr = attributes.AttributeAtIndex(i);
        if (attributes.ExtractFormValueAtIndex(i, form_value))
        {
            switch (attr)
            {
                case DW_AT_type:
                    type_attr_value = form_value;
                    break;
                default:
                    assert(false && "Unsupported attribute for DW_TAG_array_type");
            }
        }
    }

    DIERef type_die_ref(type_attr_value);
    Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
    if (!pointee_type)
        return nullptr;

    CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
    CompilerType reference_compiler_type = m_ast.CreateReferenceType(pointee_compiler_type);
    TypeSP type_sp(new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1, nullptr,
                            type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
                            reference_compiler_type, Type::eResolveStateFull));
    type_sp->SetEncodingType(pointee_type);
    return type_sp;
}
TypeSP
DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die)
{
    SymbolFileDWARF *dwarf = die.GetDWARF();
    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

    ConstString linkage_name;
    DWARFFormValue type_attr_value;
    lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
    DWARFExpression length_expression(die.GetCU());

    DWARFAttributes attributes;
    const size_t num_attributes = die.GetAttributes(attributes);
    for (uint32_t i = 0; i < num_attributes; ++i)
    {
        DWARFFormValue form_value;
        dw_attr_t attr = attributes.AttributeAtIndex(i);
        if (attributes.ExtractFormValueAtIndex(i, form_value))
        {
            switch (attr)
            {
                case DW_AT_linkage_name:
                    linkage_name.SetCString(form_value.AsCString());
                    break;
                case DW_AT_type:
                    type_attr_value = form_value;
                    break;
                case DW_AT_data_member_location:
                    data_offset = form_value.Unsigned();
                    break;
                case DW_AT_declaration:
                    break;
                default:
                    assert(false && "Unsupported attribute for DW_TAG_array_type");
            }
        }
    }

    for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling())
    {
        if (child_die.Tag() == DW_TAG_subrange_type)
        {
            DWARFAttributes attributes;
            const size_t num_attributes = child_die.GetAttributes(attributes);
            for (uint32_t i = 0; i < num_attributes; ++i)
            {
                DWARFFormValue form_value;
                dw_attr_t attr = attributes.AttributeAtIndex(i);
                if (attributes.ExtractFormValueAtIndex(i, form_value))
                {
                    switch (attr)
                    {
                        case DW_AT_count:
                            if (form_value.BlockData())
                                length_expression.CopyOpcodeData(form_value.BlockData(), form_value.Unsigned(),
                                                                 child_die.GetCU()->GetByteOrder(),
                                                                 child_die.GetCU()->GetAddressByteSize());
                            break;
                        default:
                            assert(false && "Unsupported attribute for DW_TAG_subrange_type");
                    }
                }
            }
        }
        else
        {
            assert(false && "Unsupported child for DW_TAG_array_type");
        }
    }

    DIERef type_die_ref(type_attr_value);
    Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
    if (!element_type)
        return nullptr;

    CompilerType element_compiler_type = element_type->GetForwardCompilerType();
    CompilerType array_compiler_type =
        m_ast.CreateArrayType(element_compiler_type, length_expression, data_offset);

    Declaration decl;
    TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), -1, nullptr,
                            type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
                            array_compiler_type, Type::eResolveStateFull));
    type_sp->SetEncodingType(element_type);
    return type_sp;
}
lldb::TypeSP
DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type)
{
    SymbolFileDWARF *dwarf = die.GetDWARF();
    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

    Declaration decl;
    ConstString name;
    ConstString linkage_name;
    bool is_forward_declaration = false;
    uint32_t byte_size = 0;

    DWARFAttributes attributes;
    const size_t num_attributes = die.GetAttributes(attributes);
    for (uint32_t i = 0; i < num_attributes; ++i)
    {
        DWARFFormValue form_value;
        dw_attr_t attr = attributes.AttributeAtIndex(i);
        if (attributes.ExtractFormValueAtIndex(i, form_value))
        {
            switch (attr)
            {
                case DW_AT_name:
                    name.SetCString(form_value.AsCString());
                    break;
                case DW_AT_declaration:
                    is_forward_declaration = form_value.Boolean();
                    break;
                case DW_AT_byte_size:
                    byte_size = form_value.Unsigned();
                    break;
                case DW_AT_linkage_name:
                    linkage_name.SetCString(form_value.AsCString());
                    break;
                default:
                    assert(false && "Unsupported attribute for DW_TAG_class_type");
            }
        }
    }

    UniqueDWARFASTType unique_ast_entry;
    if (name)
    {
        std::string qualified_name;
        if (die.GetQualifiedName(qualified_name))
        {
            name.SetCString(qualified_name.c_str());
            if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1, unique_ast_entry))
            {
                if (unique_ast_entry.m_type_sp)
                {
                    dwarf->GetDIEToType()[die.GetDIE()] = unique_ast_entry.m_type_sp.get();
                    is_new_type = false;
                    return unique_ast_entry.m_type_sp;
                }
            }
        }
    }

    if (is_forward_declaration)
    {
        DWARFDeclContext die_decl_ctx;
        die.GetDWARFDeclContext(die_decl_ctx);

        TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
        if (type_sp)
        {
            // We found a real definition for this type elsewhere so lets use it
            dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
            is_new_type = false;
            return type_sp;
        }
    }

    CompilerType compiler_type(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
    if (!compiler_type)
        compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);

    is_new_type = true;
    TypeSP type_sp(new Type(die.GetID(), dwarf, name,
                            -1, // byte size isn't specified
                            nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
                            Type::eResolveStateForward));

    // Add our type to the unique type map
    unique_ast_entry.m_type_sp = type_sp;
    unique_ast_entry.m_die = die;
    unique_ast_entry.m_declaration = decl;
    unique_ast_entry.m_byte_size = -1;
    dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);

    if (!is_forward_declaration)
    {
        // Leave this as a forward declaration until we need to know the details of the type
        dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = compiler_type.GetOpaqueQualType();
        dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
    }
    return type_sp;
}