//===-- 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 "DWARFDIE.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.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",
                     die.GetID(), 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(die.GetID(), 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", die.GetID(),
                     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(die.GetID(), 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", die.GetID(),
                     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(die.GetID(), 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", die.GetID(),
                       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(die.GetID(), 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(sc_parent_die.GetID());
          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;
        DWARFFormValue param_type_die_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;
              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(DIERef(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...",
        die.GetID(), 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;

        DWARFFormValue encoding_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;
              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(DIERef(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 = die.GetID();
        func_sp.reset(new Function(sc.comp_unit,
                                   func_user_id, // UserID is the DIE offset
                                   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;
}
