//===-- Function.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/Function.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorExtras.h"

using namespace lldb;
using namespace lldb_private;

// Basic function information is contained in the FunctionInfo class. It is
// designed to contain the name, linkage name, and declaration location.
FunctionInfo::FunctionInfo(const char *name, const Declaration *decl_ptr)
    : m_name(name), m_declaration(decl_ptr) {}

FunctionInfo::FunctionInfo(ConstString name, const Declaration *decl_ptr)
    : m_name(name), m_declaration(decl_ptr) {}

FunctionInfo::~FunctionInfo() = default;

void FunctionInfo::Dump(Stream *s, bool show_fullpaths) const {
  if (m_name)
    *s << ", name = \"" << m_name << "\"";
  m_declaration.Dump(s, show_fullpaths);
}

int FunctionInfo::Compare(const FunctionInfo &a, const FunctionInfo &b) {
  int result = ConstString::Compare(a.GetName(), b.GetName());
  if (result)
    return result;

  return Declaration::Compare(a.m_declaration, b.m_declaration);
}

Declaration &FunctionInfo::GetDeclaration() { return m_declaration; }

const Declaration &FunctionInfo::GetDeclaration() const {
  return m_declaration;
}

ConstString FunctionInfo::GetName() const { return m_name; }

InlineFunctionInfo::InlineFunctionInfo(const char *name,
                                       llvm::StringRef mangled,
                                       const Declaration *decl_ptr,
                                       const Declaration *call_decl_ptr)
    : FunctionInfo(name, decl_ptr), m_mangled(mangled),
      m_call_decl(call_decl_ptr) {}

InlineFunctionInfo::InlineFunctionInfo(ConstString name,
                                       const Mangled &mangled,
                                       const Declaration *decl_ptr,
                                       const Declaration *call_decl_ptr)
    : FunctionInfo(name, decl_ptr), m_mangled(mangled),
      m_call_decl(call_decl_ptr) {}

InlineFunctionInfo::~InlineFunctionInfo() = default;

void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const {
  FunctionInfo::Dump(s, show_fullpaths);
  if (m_mangled)
    m_mangled.Dump(s);
}

void InlineFunctionInfo::DumpStopContext(Stream *s) const {
  //    s->Indent("[inlined] ");
  s->Indent();
  if (m_mangled)
    s->PutCString(m_mangled.GetName());
  else
    s->PutCString(m_name);
}

ConstString InlineFunctionInfo::GetName() const {
  if (m_mangled)
    return m_mangled.GetName();
  return m_name;
}

ConstString InlineFunctionInfo::GetDisplayName() const {
  if (m_mangled)
    return m_mangled.GetDisplayDemangledName();
  return m_name;
}

Declaration &InlineFunctionInfo::GetCallSite() { return m_call_decl; }

const Declaration &InlineFunctionInfo::GetCallSite() const {
  return m_call_decl;
}

Mangled &InlineFunctionInfo::GetMangled() { return m_mangled; }

const Mangled &InlineFunctionInfo::GetMangled() const { return m_mangled; }

/// @name Call site related structures
/// @{

CallEdge::~CallEdge() = default;

CallEdge::CallEdge(AddrType caller_address_type, lldb::addr_t caller_address,
                   bool is_tail_call, CallSiteParameterArray &&parameters)
    : caller_address(caller_address), caller_address_type(caller_address_type),
      is_tail_call(is_tail_call), parameters(std::move(parameters)) {}

lldb::addr_t CallEdge::GetLoadAddress(lldb::addr_t unresolved_pc,
                                      Function &caller, Target &target) {
  Log *log = GetLog(LLDBLog::Step);

  const Address &caller_start_addr = caller.GetAddress();

  ModuleSP caller_module_sp = caller_start_addr.GetModule();
  if (!caller_module_sp) {
    LLDB_LOG(log, "GetLoadAddress: cannot get Module for caller");
    return LLDB_INVALID_ADDRESS;
  }

  SectionList *section_list = caller_module_sp->GetSectionList();
  if (!section_list) {
    LLDB_LOG(log, "GetLoadAddress: cannot get SectionList for Module");
    return LLDB_INVALID_ADDRESS;
  }

  Address the_addr = Address(unresolved_pc, section_list);
  lldb::addr_t load_addr = the_addr.GetLoadAddress(&target);
  return load_addr;
}

lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller,
                                          Target &target) const {
  return GetLoadAddress(GetUnresolvedReturnPCAddress(), caller, target);
}

Function *DirectCallEdge::ResolveCallee(ModuleList &images) {
  if (!m_symbol_name)
    return nullptr;

  Log *log = GetLog(LLDBLog::Step);
  LLDB_LOG(log, "DirectCallEdge: Lazily parsing the call graph for {0}",
           m_symbol_name);

  SymbolContextList sc_list;
  images.FindFunctionSymbols(ConstString(m_symbol_name), eFunctionNameTypeAuto,
                             sc_list);
  size_t num_matches = sc_list.GetSize();
  if (num_matches == 0 || !sc_list[0].symbol) {
    LLDB_LOG(log, "DirectCallEdge: Found no symbols for {0}, cannot resolve it",
             m_symbol_name);
    return nullptr;
  }

  Address callee_addr = sc_list[0].symbol->GetAddress();
  if (!callee_addr.IsValid()) {
    LLDB_LOG(log, "DirectCallEdge: Invalid symbol address");
    return nullptr;
  }

  Function *f = callee_addr.CalculateSymbolContextFunction();
  if (!f) {
    LLDB_LOG(log, "DirectCallEdge: Could not find complete function");
    return nullptr;
  }

  return f;
}

DirectCallEdge::DirectCallEdge(const char *symbol_name,
                               AddrType caller_address_type,
                               lldb::addr_t caller_address, bool is_tail_call,
                               CallSiteParameterArray &&parameters)
    : CallEdge(caller_address_type, caller_address, is_tail_call,
               std::move(parameters)),
      m_symbol_name(symbol_name) {}

Function *DirectCallEdge::GetCallee(ModuleList &images, ExecutionContext &) {
  std::call_once(m_resolved_flag,
                 [&] { m_callee_def = ResolveCallee(images); });
  return m_callee_def;
}

IndirectCallEdge::IndirectCallEdge(DWARFExpressionList call_target,
                                   AddrType caller_address_type,
                                   lldb::addr_t caller_address,
                                   bool is_tail_call,
                                   CallSiteParameterArray &&parameters)
    : CallEdge(caller_address_type, caller_address, is_tail_call,
               std::move(parameters)),
      call_target(std::move(call_target)) {}

Function *IndirectCallEdge::GetCallee(ModuleList &images,
                                      ExecutionContext &exe_ctx) {
  Log *log = GetLog(LLDBLog::Step);
  Status error;
  llvm::Expected<Value> callee_addr_val = call_target.Evaluate(
      &exe_ctx, exe_ctx.GetRegisterContext(), LLDB_INVALID_ADDRESS,
      /*initial_value_ptr=*/nullptr,
      /*object_address_ptr=*/nullptr);
  if (!callee_addr_val) {
    LLDB_LOG_ERROR(log, callee_addr_val.takeError(),
                   "IndirectCallEdge: Could not evaluate expression: {0}");
    return nullptr;
  }

  addr_t raw_addr =
      callee_addr_val->GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  if (raw_addr == LLDB_INVALID_ADDRESS) {
    LLDB_LOG(log, "IndirectCallEdge: Could not extract address from scalar");
    return nullptr;
  }

  if (auto *process = exe_ctx.GetProcessPtr()) {
    raw_addr = process->FixCodeAddress(raw_addr);
  } else {
    LLDB_LOG(log, "IndirectCallEdge: No Process available, unable to call "
                  "FixCodeAddress on function pointer");
  }

  Address callee_addr;
  if (!exe_ctx.GetTargetPtr()->ResolveLoadAddress(raw_addr, callee_addr)) {
    LLDB_LOG(log, "IndirectCallEdge: Could not resolve callee's load address");
    return nullptr;
  }

  Function *f = callee_addr.CalculateSymbolContextFunction();
  if (!f) {
    LLDB_LOG(log, "IndirectCallEdge: Could not find complete function");
    return nullptr;
  }

  return f;
}

/// @}

//
Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
                   lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
                   Address address, AddressRanges ranges)
    : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
      m_type(type), m_mangled(mangled), m_block(*this, func_uid),
      m_address(std::move(address)), m_prologue_byte_size(0) {
  assert(comp_unit != nullptr);
  lldb::addr_t base_file_addr = m_address.GetFileAddress();
  for (const AddressRange &range : ranges)
    m_block.AddRange(
        Block::Range(range.GetBaseAddress().GetFileAddress() - base_file_addr,
                     range.GetByteSize()));
  m_block.FinalizeRanges();
}

Function::~Function() = default;

bool Function::GetStartLineTableEntry(LineEntry &line_entry, uint32_t *index) {
  LineTable *line_table = m_comp_unit ? m_comp_unit->GetLineTable() : nullptr;
  if (line_table == nullptr)
    return false;

  uint32_t line_entry_idx = UINT32_MAX;
  if (line_table->FindLineEntryByAddress(GetAddress(), line_entry,
                                         &line_entry_idx)) {
    if (index)
      *index = line_entry_idx;
    return true;
  }

  // The entry point has no line row (e.g. a WebAssembly function's
  // locals-declaration header), so take the first row inside the function.
  AddressRange entry_range;
  if (!m_block.GetRangeContainingAddress(m_address, entry_range))
    return false;
  auto [first, last] = line_table->GetLineEntryIndexRange(entry_range);
  if (first == last)
    return false;
  if (!line_table->GetLineEntryAtIndex(first, line_entry))
    return false;
  if (index)
    *index = first;
  return true;
}

void Function::GetStartLineSourceInfo(SupportFileNSP &source_file_sp,
                                      uint32_t &line_no) {
  line_no = 0;
  source_file_sp = std::make_shared<SupportFile>();

  if (m_comp_unit == nullptr)
    return;

  // Initialize m_type if it hasn't been initialized already
  GetType();

  if (m_type != nullptr && m_type->GetDeclaration().GetLine() != 0) {
    source_file_sp =
        std::make_shared<SupportFile>(m_type->GetDeclaration().GetFile());
    line_no = m_type->GetDeclaration().GetLine();
  } else {
    LineEntry line_entry;
    if (GetStartLineTableEntry(line_entry)) {
      line_no = line_entry.line;
      source_file_sp = line_entry.file_sp;
    }
  }
}

llvm::Expected<std::pair<SupportFileNSP, Function::SourceRange>>
Function::GetSourceInfo() {
  SupportFileNSP source_file_sp = std::make_shared<SupportFile>();
  uint32_t start_line;
  GetStartLineSourceInfo(source_file_sp, start_line);
  LineTable *line_table = m_comp_unit->GetLineTable();
  if (start_line == 0 || !line_table) {
    return llvm::createStringErrorV(
        "Could not find line information for function \"{0}\".", GetName());
  }

  uint32_t end_line = start_line;
  for (const AddressRange &range : GetAddressRanges()) {
    for (auto [idx, end] = line_table->GetLineEntryIndexRange(range); idx < end;
         ++idx) {
      LineEntry entry;
      // Ignore entries belonging to inlined functions or #included files.
      if (line_table->GetLineEntryAtIndex(idx, entry) &&
          source_file_sp->Equal(*entry.file_sp,
                                SupportFile::eEqualFileSpecAndChecksumIfSet))
        end_line = std::max(end_line, entry.line);
    }
  }
  return std::make_pair(std::move(source_file_sp),
                        SourceRange(start_line, end_line - start_line));
}

llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetCallEdges() {
  std::lock_guard<std::mutex> guard(m_call_edges_lock);

  if (m_call_edges_resolved)
    return m_call_edges;

  Log *log = GetLog(LLDBLog::Step);
  LLDB_LOG(log, "GetCallEdges: Attempting to parse call site info for {0}",
           GetDisplayName());

  m_call_edges_resolved = true;

  // Find the SymbolFile which provided this function's definition.
  Block &block = GetBlock(/*can_create*/true);
  SymbolFile *sym_file = block.GetSymbolFile();
  if (!sym_file)
    return {};

  // Lazily read call site information from the SymbolFile.
  m_call_edges = sym_file->ParseCallEdgesInFunction(GetID());

  // Sort the call edges to speed up return_pc lookups.
  llvm::sort(m_call_edges, [](const std::unique_ptr<CallEdge> &LHS,
                              const std::unique_ptr<CallEdge> &RHS) {
    return LHS->GetSortKey() < RHS->GetSortKey();
  });

  return m_call_edges;
}

llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetTailCallingEdges() {
  // Tail calling edges are sorted at the end of the list. Find them by dropping
  // all non-tail-calls.
  return GetCallEdges().drop_until(
      [](const std::unique_ptr<CallEdge> &edge) { return edge->IsTailCall(); });
}

CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc,
                                                Target &target) {
  auto edges = GetCallEdges();
  auto edge_it =
      llvm::partition_point(edges, [&](const std::unique_ptr<CallEdge> &edge) {
        return std::make_pair(edge->IsTailCall(),
                              edge->GetReturnPCAddress(*this, target)) <
               std::make_pair(false, return_pc);
      });
  if (edge_it == edges.end() ||
      edge_it->get()->GetReturnPCAddress(*this, target) != return_pc)
    return nullptr;
  return edge_it->get();
}

Block &Function::GetBlock(bool can_create) {
  if (!m_block.BlockInfoHasBeenParsed() && can_create) {
    ModuleSP module_sp = CalculateSymbolContextModule();
    if (module_sp) {
      module_sp->GetSymbolFile()->ParseBlocksRecursive(*this);
    } else {
      Debugger::ReportError(llvm::formatv(
          "unable to find module shared pointer for function '{0}' in {1}",
          GetName().GetCString(), m_comp_unit->GetPrimaryFile().GetPath()));
    }
    m_block.SetBlockInfoHasBeenParsed(true, true);
  }
  return m_block;
}

CompileUnit *Function::GetCompileUnit() { return m_comp_unit; }

const CompileUnit *Function::GetCompileUnit() const { return m_comp_unit; }

void Function::GetDescription(Stream *s, lldb::DescriptionLevel level,
                              Target *target) {
  ConstString name = GetName();
  ConstString mangled = m_mangled.GetMangledName();

  *s << "id = " << (const UserID &)*this;
  if (name)
    s->AsRawOstream() << ", name = \"" << name << '"';
  if (mangled)
    s->AsRawOstream() << ", mangled = \"" << mangled << '"';
  if (level == eDescriptionLevelVerbose) {
    *s << ", decl_context = {";
    auto decl_context = GetCompilerContext();
    // Drop the function itself from the context chain.
    if (decl_context.size())
      decl_context.pop_back();
    llvm::interleaveComma(decl_context, *s, [&](auto &ctx) { ctx.Dump(*s); });
    *s << "}";
  }
  *s << ", range" << (m_block.GetNumRanges() > 1 ? "s" : "") << " = ";
  Address::DumpStyle fallback_style =
      level == eDescriptionLevelVerbose
          ? Address::DumpStyleModuleWithFileAddress
          : Address::DumpStyleFileAddress;
  for (unsigned idx = 0; idx < m_block.GetNumRanges(); ++idx) {
    AddressRange range;
    m_block.GetRangeAtIndex(idx, range);
    range.Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
  }
}

void Function::Dump(Stream *s, bool show_context) const {
  s->Printf("%p: ", static_cast<const void *>(this));
  s->Indent();
  *s << "Function" << static_cast<const UserID &>(*this);

  m_mangled.Dump(s);

  if (m_type)
    s->Printf(", type = %p", static_cast<void *>(m_type));
  else if (m_type_uid != LLDB_INVALID_UID)
    s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);

  s->EOL();
  // Dump the root object
  if (m_block.BlockInfoHasBeenParsed())
    m_block.Dump(s, m_address.GetFileAddress(), INT_MAX, show_context);
}

void Function::CalculateSymbolContext(SymbolContext *sc) {
  sc->function = this;
  m_comp_unit->CalculateSymbolContext(sc);
}

ModuleSP Function::CalculateSymbolContextModule() {
  if (SectionSP section_sp = m_address.GetSection())
    return section_sp->GetModule();

  return this->GetCompileUnit()->GetModule();
}

CompileUnit *Function::CalculateSymbolContextCompileUnit() {
  return this->GetCompileUnit();
}

Function *Function::CalculateSymbolContextFunction() { return this; }

lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx,
                                               const char *flavor,
                                               bool prefer_file_cache) {
  ModuleSP module_sp = GetAddress().GetModule();
  if (module_sp && exe_ctx.HasTargetScope()) {
    return Disassembler::DisassembleRange(
        module_sp->GetArchitecture(), nullptr, nullptr, nullptr, flavor,
        exe_ctx.GetTargetRef(), GetAddressRanges(), !prefer_file_cache);
  }
  return lldb::DisassemblerSP();
}

bool Function::GetDisassembly(const ExecutionContext &exe_ctx,
                              const char *flavor, Stream &strm,
                              bool prefer_file_cache) {
  lldb::DisassemblerSP disassembler_sp =
      GetInstructions(exe_ctx, flavor, prefer_file_cache);
  if (disassembler_sp) {
    const bool show_address = true;
    const bool show_bytes = false;
    const bool show_control_flow_kind = false;
    disassembler_sp->GetInstructionList().Dump(
        &strm, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
    return true;
  }
  return false;
}

// Symbol *
// Function::CalculateSymbolContextSymbol ()
//{
//    return // TODO: find the symbol for the function???
//}

void Function::DumpSymbolContext(Stream *s) {
  m_comp_unit->DumpSymbolContext(s);
  s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
}

bool Function::GetIsOptimized() {
  bool result = false;

  // Currently optimization is only indicted by the vendor extension
  // DW_AT_APPLE_optimized which is set on a compile unit level.
  if (m_comp_unit) {
    result = m_comp_unit->GetIsOptimized();
  }
  return result;
}

bool Function::IsTopLevelFunction() {
  bool result = false;

  if (Language *language = Language::FindPlugin(GetLanguage()))
    result = language->IsTopLevelFunction(*this);

  return result;
}

ConstString Function::GetDisplayName() const {
  return m_mangled.GetDisplayDemangledName();
}

CompilerDeclContext Function::GetDeclContext() {
  if (ModuleSP module_sp = CalculateSymbolContextModule())
    if (SymbolFile *sym_file = module_sp->GetSymbolFile())
      return sym_file->GetDeclContextForUID(GetID());
  return {};
}

std::vector<CompilerContext> Function::GetCompilerContext() {
  if (ModuleSP module_sp = CalculateSymbolContextModule())
    if (SymbolFile *sym_file = module_sp->GetSymbolFile())
      return sym_file->GetCompilerContextForUID(GetID());
  return {};
}

Type *Function::GetType() {
  if (m_type == nullptr) {
    SymbolContext sc;

    CalculateSymbolContext(&sc);

    if (!sc.module_sp)
      return nullptr;

    SymbolFile *sym_file = sc.module_sp->GetSymbolFile();

    if (sym_file == nullptr)
      return nullptr;

    m_type = sym_file->ResolveTypeUID(m_type_uid);
  }
  return m_type;
}

const Type *Function::GetType() const { return m_type; }

CompilerType Function::GetCompilerType() {
  Type *function_type = GetType();
  if (function_type)
    return function_type->GetFullCompilerType();
  return CompilerType();
}

uint32_t Function::GetPrologueByteSize() {
  if (m_prologue_byte_size == 0 &&
      m_flags.IsClear(flagsCalculatedPrologueSize)) {
    m_flags.Set(flagsCalculatedPrologueSize);
    LineTable *line_table = m_comp_unit->GetLineTable();
    uint32_t prologue_end_line_idx = 0;

    if (line_table) {
      LineEntry first_line_entry;
      uint32_t first_line_entry_idx = UINT32_MAX;
      bool found_first_line_entry =
          GetStartLineTableEntry(first_line_entry, &first_line_entry_idx);

      if (found_first_line_entry) {
        // Make sure the first line entry isn't already the end of the prologue
        addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
        addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;

        if (first_line_entry.is_prologue_end) {
          prologue_end_file_addr =
              first_line_entry.range.GetBaseAddress().GetFileAddress();
          prologue_end_line_idx = first_line_entry_idx;
        } else {
          // Check the first few instructions and look for one that has
          // is_prologue_end set to true.
          const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
          for (uint32_t idx = first_line_entry_idx + 1;
               idx < last_line_entry_idx; ++idx) {
            LineEntry line_entry;
            if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
              if (line_entry.is_prologue_end) {
                prologue_end_file_addr =
                    line_entry.range.GetBaseAddress().GetFileAddress();
                prologue_end_line_idx = idx;
                break;
              }
            }
          }
        }

        // If we didn't find the end of the prologue in the line tables, then
        // just use the end address of the first line table entry
        if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
          // Check the first few instructions and look for one that has a line
          // number that's different than the first entry.
          uint32_t last_line_entry_idx = first_line_entry_idx + 6;
          for (uint32_t idx = first_line_entry_idx + 1;
               idx < last_line_entry_idx; ++idx) {
            LineEntry line_entry;
            if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
              if (line_entry.line != first_line_entry.line) {
                prologue_end_file_addr =
                    line_entry.range.GetBaseAddress().GetFileAddress();
                prologue_end_line_idx = idx;
                break;
              }
            }
          }

          if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
            prologue_end_file_addr =
                first_line_entry.range.GetBaseAddress().GetFileAddress() +
                first_line_entry.range.GetByteSize();
            prologue_end_line_idx = first_line_entry_idx;
          }
        }

        AddressRange entry_range;
        m_block.GetRangeContainingAddress(m_address, entry_range);

        // Deliberately not starting at entry_range.GetBaseAddress() because the
        // function entry point need not be the first address in the range.
        const addr_t func_start_file_addr = m_address.GetFileAddress();
        const addr_t range_end_file_addr =
            entry_range.GetBaseAddress().GetFileAddress() +
            entry_range.GetByteSize();

        // Now calculate the offset to pass the subsequent line 0 entries.
        uint32_t first_non_zero_line = prologue_end_line_idx;
        while (true) {
          LineEntry line_entry;
          if (line_table->GetLineEntryAtIndex(first_non_zero_line,
                                              line_entry)) {
            if (line_entry.line != 0)
              break;
          }
          if (line_entry.range.GetBaseAddress().GetFileAddress() >=
              range_end_file_addr)
            break;

          first_non_zero_line++;
        }

        if (first_non_zero_line > prologue_end_line_idx) {
          LineEntry first_non_zero_entry;
          if (line_table->GetLineEntryAtIndex(first_non_zero_line,
                                              first_non_zero_entry)) {
            line_zero_end_file_addr =
                first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
          }
        }

        // Verify that this prologue end file address inside the function just
        // to be sure
        if (func_start_file_addr < prologue_end_file_addr &&
            prologue_end_file_addr < range_end_file_addr) {
          m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
        }

        if (prologue_end_file_addr < line_zero_end_file_addr &&
            line_zero_end_file_addr < range_end_file_addr) {
          m_prologue_byte_size +=
              line_zero_end_file_addr - prologue_end_file_addr;
        }
      }
    }
  }

  return m_prologue_byte_size;
}

lldb::LanguageType Function::GetLanguage() const {
  lldb::LanguageType lang = m_mangled.GuessLanguage();
  if (lang != lldb::eLanguageTypeUnknown)
    return lang;

  if (m_comp_unit)
    return m_comp_unit->GetLanguage();

  return lldb::eLanguageTypeUnknown;
}

ConstString Function::GetName() const {
  return m_mangled.GetName();
}

ConstString Function::GetNameNoArguments() const {
  return m_mangled.GetName(Mangled::ePreferDemangledWithoutArguments);
}
