//===-- DWARFASTParserGo.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DWARFASTParserGo.h"

#include "DWARFASTParserGo.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
#include "DWARFDIE.h"
#include "DWARFDIECollection.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"

#include "clang/Basic/Specifiers.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/TypeList.h"

//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN

#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif

#define DW_AT_go_kind 0x2900
#define DW_AT_go_key 0x2901
#define DW_AT_go_elem 0x2902

using namespace lldb;
using namespace lldb_private;
DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast)
    : m_ast(ast)
{
}

DWARFASTParserGo::~DWARFASTParserGo()
{
}

TypeSP
DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
                                     bool *type_is_new_ptr)
{
    TypeSP type_sp;

    if (type_is_new_ptr)
        *type_is_new_ptr = false;

    if (die)
    {
        SymbolFileDWARF *dwarf = die.GetDWARF();
        if (log)
        {
            dwarf->GetObjectFile()->GetModule()->LogMessage(
                log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = '%s')", die.GetOffset(),
                DW_TAG_value_to_name(die.Tag()), die.GetName());
        }

        Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
        TypeList *type_list = dwarf->GetTypeList();
        if (type_ptr == NULL)
        {
            if (type_is_new_ptr)
                *type_is_new_ptr = true;

            const dw_tag_t tag = die.Tag();

            bool is_forward_declaration = false;
            DWARFAttributes attributes;
            const char *type_name_cstr = NULL;
            ConstString type_name_const_str;
            Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
            uint64_t byte_size = 0;
            uint64_t go_kind = 0;
            Declaration decl;

            Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
            CompilerType compiler_type;
            DWARFFormValue form_value;

            dw_attr_t attr;

            switch (tag)
            {
                case DW_TAG_base_type:
                case DW_TAG_pointer_type:
                case DW_TAG_typedef:
                case DW_TAG_unspecified_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

                    const size_t num_attributes = die.GetAttributes(attributes);
                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;

                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i = 0; i < num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(i, form_value))
                            {
                                switch (attr)
                                {
                                    case DW_AT_name:
                                        type_name_cstr = form_value.AsCString();
                                        if (type_name_cstr)
                                            type_name_const_str.SetCString(type_name_cstr);
                                        break;
                                    case DW_AT_byte_size:
                                        byte_size = form_value.Unsigned();
                                        break;
                                    case DW_AT_encoding:
                                        // = form_value.Unsigned();
                                        break;
                                    case DW_AT_type:
                                        encoding_uid = form_value.Reference();
                                        break;
                                    case DW_AT_go_kind:
                                        go_kind = form_value.Unsigned();
                                        break;
                                    default:
                                        // Do we care about DW_AT_go_key or DW_AT_go_elem?
                                        break;
                                }
                            }
                        }
                    }

                    DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", dwarf->MakeUserID(die.GetOffset()),
                                 DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);

                    switch (tag)
                    {
                        default:
                            break;

                        case DW_TAG_unspecified_type:
                            resolve_state = Type::eResolveStateFull;
                            compiler_type = m_ast.CreateVoidType(type_name_const_str);
                            break;

                        case DW_TAG_base_type:
                            resolve_state = Type::eResolveStateFull;
                            compiler_type = m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
                            break;

                        case DW_TAG_pointer_type:
                            encoding_data_type = Type::eEncodingIsPointerUID;
                            break;
                        case DW_TAG_typedef:
                            encoding_data_type = Type::eEncodingIsTypedefUID;
                            CompilerType impl;
                            Type *type = dwarf->ResolveTypeUID(encoding_uid);
                            if (type)
                            {
                                if (go_kind == 0 && type->GetName() == type_name_const_str)
                                {
                                    // Go emits extra typedefs as a forward declaration. Ignore these.
                                    dwarf->m_die_to_type[die.GetDIE()] = type;
                                    return type->shared_from_this();
                                }
                                impl = type->GetForwardCompilerType();
                                compiler_type = m_ast.CreateTypedefType (go_kind, type_name_const_str, impl);
                            }
                            break;
                    }

                    type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, byte_size,
                                           NULL, encoding_uid, encoding_data_type, &decl, compiler_type, resolve_state));

                    dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
                }
                break;

                case DW_TAG_structure_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
                    bool byte_size_valid = false;

                    const size_t num_attributes = die.GetAttributes(attributes);
                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i = 0; i < num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(i, form_value))
                            {
                                switch (attr)
                                {
                                    case DW_AT_name:
                                        type_name_cstr = form_value.AsCString();
                                        type_name_const_str.SetCString(type_name_cstr);
                                        break;

                                    case DW_AT_byte_size:
                                        byte_size = form_value.Unsigned();
                                        byte_size_valid = true;
                                        break;

                                    case DW_AT_go_kind:
                                        go_kind = form_value.Unsigned();
                                        break;

                                    // TODO: Should we use SLICETYPE's DW_AT_go_elem?
                                    default:
                                        break;
                                }
                            }
                        }
                    }

                    // TODO(ribrdb): Do we need this?

                    // UniqueDWARFASTType is large, so don't create a local variables on the
                    // stack, put it on the heap. This function is often called recursively
                    // and clang isn't good and sharing the stack space for variables in different blocks.
                    std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());

                    // Only try and unique the type if it has a name.
                    if (type_name_const_str &&
                        dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
                                                               byte_size_valid ? byte_size : -1, *unique_ast_entry_ap))
                    {
                        // We have already parsed this type or from another
                        // compile unit. GCC loves to use the "one definition
                        // rule" which can result in multiple definitions
                        // of the same class over and over in each compile
                        // unit.
                        type_sp = unique_ast_entry_ap->m_type_sp;
                        if (type_sp)
                        {
                            dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
                            return type_sp;
                        }
                    }

                    DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
                                 DW_TAG_value_to_name(tag), type_name_cstr);

                    bool compiler_type_was_created = false;
                    compiler_type.SetCompilerType(&m_ast, dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
                    if (!compiler_type)
                    {
                        compiler_type_was_created = true;
                        compiler_type = m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
                    }

                    type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, byte_size,
                                           NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
                                           Type::eResolveStateForward));

                    // Add our type to the unique type map so we don't
                    // end up creating many copies of the same type over
                    // and over in the ASTContext for our module
                    unique_ast_entry_ap->m_type_sp = type_sp;
                    unique_ast_entry_ap->m_die = die;
                    unique_ast_entry_ap->m_declaration = decl;
                    unique_ast_entry_ap->m_byte_size = byte_size;
                    dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str, *unique_ast_entry_ap);

                    if (!is_forward_declaration)
                    {
                        // Always start the definition for a class type so that
                        // if the class has child classes or types that require
                        // the class to be created for use as their decl contexts
                        // the class will be ready to accept these child definitions.
                        if (die.HasChildren() == false)
                        {
                            // No children for this struct/union/class, lets finish it
                            m_ast.CompleteStructType(compiler_type);
                        }
                        else if (compiler_type_was_created)
                        {
                            // Leave this as a forward declaration until we need
                            // to know the details of the type. lldb_private::Type
                            // will automatically call the SymbolFile virtual function
                            // "SymbolFileDWARF::CompleteType(Type *)"
                            // When the definition needs to be defined.
                            dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = compiler_type.GetOpaqueQualType();
                            dwarf->m_forward_decl_clang_type_to_die[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
                            // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
                        }
                    }
                }
                break;

                case DW_TAG_subprogram:
                case DW_TAG_subroutine_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

                    bool is_variadic = false;
                    clang::StorageClass storage = clang::SC_None; //, Extern, Static, PrivateExtern

                    const size_t num_attributes = die.GetAttributes(attributes);
                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i = 0; i < num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(i, form_value))
                            {
                                switch (attr)
                                {
                                    case DW_AT_name:
                                        type_name_cstr = form_value.AsCString();
                                        type_name_const_str.SetCString(type_name_cstr);
                                        break;

                                    case DW_AT_external:
                                        if (form_value.Unsigned())
                                        {
                                            if (storage == clang::SC_None)
                                                storage = clang::SC_Extern;
                                            else
                                                storage = clang::SC_PrivateExtern;
                                        }
                                        break;

                                    case DW_AT_high_pc:
                                    case DW_AT_low_pc:
                                        break;
                                }
                            }
                        }
                    }

                    DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
                                 DW_TAG_value_to_name(tag), type_name_cstr);

                    std::vector<CompilerType> function_param_types;

                    // Parse the function children for the parameters

                    if (die.HasChildren())
                    {
                        ParseChildParameters(sc, die, is_variadic, function_param_types);
                    }

                    // compiler_type will get the function prototype clang type after this call
                    compiler_type = m_ast.CreateFunctionType(type_name_const_str, function_param_types.data(),
                                                          function_param_types.size(), is_variadic);

                    type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, 0, NULL,
                                           LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
                                           Type::eResolveStateFull));
                    assert(type_sp.get());
                }
                break;

                case DW_TAG_array_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
                    int64_t first_index = 0;
                    uint32_t byte_stride = 0;
                    uint32_t bit_stride = 0;
                    const size_t num_attributes = die.GetAttributes(attributes);

                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i = 0; i < num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(i, form_value))
                            {
                                switch (attr)
                                {
                                    case DW_AT_name:
                                        type_name_cstr = form_value.AsCString();
                                        type_name_const_str.SetCString(type_name_cstr);
                                        break;

                                    case DW_AT_type:
                                        type_die_offset = form_value.Reference();
                                        break;
                                    case DW_AT_byte_size:
                                        break; // byte_size = form_value.Unsigned(); break;
                                    case DW_AT_go_kind:
                                        go_kind = form_value.Unsigned();
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }

                        DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
                                     DW_TAG_value_to_name(tag), type_name_cstr);

                        Type *element_type = dwarf->ResolveTypeUID(type_die_offset);

                        if (element_type)
                        {
                            std::vector<uint64_t> element_orders;
                            ParseChildArrayInfo(sc, die, first_index, element_orders, byte_stride, bit_stride);
                            if (byte_stride == 0)
                                byte_stride = element_type->GetByteSize();
                            CompilerType array_element_type = element_type->GetForwardCompilerType();
                            if (element_orders.size() > 0)
                            {
                                if (element_orders.size() > 1)
                                    printf("golang: unsupported multi-dimensional array %s\n", type_name_cstr);
                                compiler_type =
                                    m_ast.CreateArrayType(type_name_const_str, array_element_type, element_orders[0]);
                            }
                            else
                            {
                                compiler_type = m_ast.CreateArrayType(type_name_const_str, array_element_type, 0);
                            }
                            type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str,
                                                   byte_stride, NULL, type_die_offset, Type::eEncodingIsUID, &decl,
                                                   compiler_type, Type::eResolveStateFull));
                            type_sp->SetEncodingType(element_type);
                        }
                    }
                }
                break;

                default:
                    dwarf->GetObjectFile()->GetModule()->ReportError("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), "
                                                                     "please file a bug and attach the file at the "
                                                                     "start of this error message",
                                                                     die.GetOffset(), tag, DW_TAG_value_to_name(tag));
                    break;
            }

            if (type_sp.get())
            {
                DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
                dw_tag_t sc_parent_tag = sc_parent_die.Tag();

                SymbolContextScope *symbol_context_scope = NULL;
                if (sc_parent_tag == DW_TAG_compile_unit)
                {
                    symbol_context_scope = sc.comp_unit;
                }
                else if (sc.function != NULL && sc_parent_die)
                {
                    symbol_context_scope =
                        sc.function->GetBlock(true).FindBlockByID(dwarf->MakeUserID(sc_parent_die.GetOffset()));
                    if (symbol_context_scope == NULL)
                        symbol_context_scope = sc.function;
                }

                if (symbol_context_scope != NULL)
                {
                    type_sp->SetSymbolContextScope(symbol_context_scope);
                }

                // We are ready to put this type into the uniqued list up at the module level
                type_list->Insert(type_sp);

                dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
            }
        }
        else if (type_ptr != DIE_IS_BEING_PARSED)
        {
            type_sp = type_ptr->shared_from_this();
        }
    }
    return type_sp;
}

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

bool
DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &compiler_type)
{
    if (!die)
        return false;

    const dw_tag_t tag = die.Tag();

    SymbolFileDWARF *dwarf = die.GetDWARF();
    Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
    if (log)
        dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
            log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", dwarf->MakeUserID(die.GetOffset()),
            DW_TAG_value_to_name(tag), type->GetName().AsCString());
    assert(compiler_type);
    DWARFAttributes attributes;

    switch (tag)
    {
        case DW_TAG_structure_type:
        {
            {
                if (die.HasChildren())
                {
                    SymbolContext sc(die.GetLLDBCompileUnit());

                    ParseChildMembers(sc, die, compiler_type);
                }
            }
            m_ast.CompleteStructType(compiler_type);
            return (bool)compiler_type;
        }

        default:
            assert(false && "not a forward go type decl!");
            break;
    }

    return false;
}

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

Function *
DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, const DWARFDIE &die)
{
    DWARFRangeList func_ranges;
    const char *name = NULL;
    const char *mangled = NULL;
    int decl_file = 0;
    int decl_line = 0;
    int decl_column = 0;
    int call_file = 0;
    int call_line = 0;
    int call_column = 0;
    DWARFExpression frame_base(die.GetCU());

    assert(die.Tag() == DW_TAG_subprogram);

    if (die.Tag() != DW_TAG_subprogram)
        return NULL;

    if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
                                 call_column, &frame_base))
    {
        // Union of all ranges in the function DIE (if the function is discontiguous)
        AddressRange func_range;
        lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
        lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
        {
            ModuleSP module_sp(die.GetModule());
            func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
            if (func_range.GetBaseAddress().IsValid())
                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
        }

        if (func_range.GetBaseAddress().IsValid())
        {
            Mangled func_name;
            func_name.SetValue(ConstString(name), false);

            FunctionSP func_sp;
            std::unique_ptr<Declaration> decl_ap;
            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
                decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
                                              decl_column));

            SymbolFileDWARF *dwarf = die.GetDWARF();
            // Supply the type _only_ if it has already been parsed
            Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());

            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);

            if (dwarf->FixupAddress(func_range.GetBaseAddress()))
            {
                const user_id_t func_user_id = dwarf->MakeUserID(die.GetOffset());
                func_sp.reset(new Function(sc.comp_unit,
                                           dwarf->MakeUserID(func_user_id), // UserID is the DIE offset
                                           dwarf->MakeUserID(func_user_id), func_name, func_type,
                                           func_range)); // first address range

                if (func_sp.get() != NULL)
                {
                    if (frame_base.IsValid())
                        func_sp->GetFrameBaseExpression() = frame_base;
                    sc.comp_unit->AddFunction(func_sp);
                    return func_sp.get();
                }
            }
        }
    }
    return NULL;
}
