//===-- BreakpointResolverFileLine.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/Breakpoint/BreakpointResolverFileLine.h"

#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb;
using namespace lldb_private;

// BreakpointResolverFileLine:
BreakpointResolverFileLine::BreakpointResolverFileLine(
    const BreakpointSP &bkpt, lldb::addr_t offset, bool skip_prologue,
    const SourceLocationSpec &location_spec)
    : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset),
      m_location_spec(location_spec), m_skip_prologue(skip_prologue) {}

BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData(
    const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict,
    Status &error) {
  llvm::StringRef filename;
  uint32_t line;
  uint16_t column;
  bool check_inlines;
  bool skip_prologue;
  bool exact_match;
  bool success;

  lldb::addr_t offset = 0;

  success = options_dict.GetValueForKeyAsString(GetKey(OptionNames::FileName),
                                                filename);
  if (!success) {
    error.SetErrorString("BRFL::CFSD: Couldn't find filename entry.");
    return nullptr;
  }

  success = options_dict.GetValueForKeyAsInteger(
      GetKey(OptionNames::LineNumber), line);
  if (!success) {
    error.SetErrorString("BRFL::CFSD: Couldn't find line number entry.");
    return nullptr;
  }

  success =
      options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Column), column);
  if (!success) {
    // Backwards compatibility.
    column = 0;
  }

  success = options_dict.GetValueForKeyAsBoolean(GetKey(OptionNames::Inlines),
                                                 check_inlines);
  if (!success) {
    error.SetErrorString("BRFL::CFSD: Couldn't find check inlines entry.");
    return nullptr;
  }

  success = options_dict.GetValueForKeyAsBoolean(
      GetKey(OptionNames::SkipPrologue), skip_prologue);
  if (!success) {
    error.SetErrorString("BRFL::CFSD: Couldn't find skip prologue entry.");
    return nullptr;
  }

  success = options_dict.GetValueForKeyAsBoolean(
      GetKey(OptionNames::ExactMatch), exact_match);
  if (!success) {
    error.SetErrorString("BRFL::CFSD: Couldn't find exact match entry.");
    return nullptr;
  }

  SourceLocationSpec location_spec(FileSpec(filename), line, column,
                                   check_inlines, exact_match);
  if (!location_spec)
    return nullptr;

  return new BreakpointResolverFileLine(bkpt, offset, skip_prologue,
                                        location_spec);
}

StructuredData::ObjectSP
BreakpointResolverFileLine::SerializeToStructuredData() {
  StructuredData::DictionarySP options_dict_sp(
      new StructuredData::Dictionary());

  options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),
                                  m_skip_prologue);
  options_dict_sp->AddStringItem(GetKey(OptionNames::FileName),
                                 m_location_spec.GetFileSpec().GetPath());
  options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber),
                                  m_location_spec.GetLine().getValueOr(0));
  options_dict_sp->AddIntegerItem(
      GetKey(OptionNames::Column),
      m_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER));
  options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines),
                                  m_location_spec.GetCheckInlines());
  options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch),
                                  m_location_spec.GetExactMatch());

  return WrapOptionsDict(options_dict_sp);
}

// Filter the symbol context list to remove contexts where the line number was
// moved into a new function. We do this conservatively, so if e.g. we cannot
// resolve the function in the context (which can happen in case of line-table-
// only debug info), we leave the context as is. The trickiest part here is
// handling inlined functions -- in this case we need to make sure we look at
// the declaration line of the inlined function, NOT the function it was
// inlined into.
void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
                                                bool is_relative) {
  if (m_location_spec.GetExactMatch())
    return; // Nothing to do. Contexts are precise.

  llvm::StringRef relative_path;
  if (is_relative)
    relative_path = m_location_spec.GetFileSpec().GetDirectory().GetStringRef();

  Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
  for(uint32_t i = 0; i < sc_list.GetSize(); ++i) {
    SymbolContext sc;
    sc_list.GetContextAtIndex(i, sc);
    if (is_relative) {
      // If the path was relative, make sure any matches match as long as the
      // relative parts of the path match the path from support files
      auto sc_dir = sc.line_entry.file.GetDirectory().GetStringRef();
      if (!sc_dir.endswith(relative_path)) {
        // We had a relative path specified and the relative directory doesn't
        // match so remove this one
        LLDB_LOG(log, "removing not matching relative path {0} since it "
                "doesn't end with {1}", sc_dir, relative_path);
        sc_list.RemoveContextAtIndex(i);
        --i;
        continue;
      }
    }

    if (!sc.block)
      continue;

    FileSpec file;
    uint32_t line;
    const Block *inline_block = sc.block->GetContainingInlinedBlock();
    if (inline_block) {
      const Declaration &inline_declaration = inline_block->GetInlinedFunctionInfo()->GetDeclaration();
      if (!inline_declaration.IsValid())
        continue;
      file = inline_declaration.GetFile();
      line = inline_declaration.GetLine();
    } else if (sc.function)
      sc.function->GetStartLineSourceInfo(file, line);
    else
      continue;

    if (file != sc.line_entry.file) {
      LLDB_LOG(log, "unexpected symbol context file {0}", sc.line_entry.file);
      continue;
    }

    // Compare the requested line number with the line of the function
    // declaration. In case of a function declared as:
    //
    // int
    // foo()
    // {
    //   ...
    //
    // the compiler will set the declaration line to the "foo" line, which is
    // the reason why we have -1 here. This can fail in case of two inline
    // functions defined back-to-back:
    //
    // inline int foo1() { ... }
    // inline int foo2() { ... }
    //
    // but that's the best we can do for now.
    // One complication, if the line number returned from GetStartLineSourceInfo
    // is 0, then we can't do this calculation.  That can happen if
    // GetStartLineSourceInfo gets an error, or if the first line number in
    // the function really is 0 - which happens for some languages.

    // But only do this calculation if the line number we found in the SC
    // was different from the one requested in the source file.  If we actually
    // found an exact match it must be valid.

    if (m_location_spec.GetLine() == sc.line_entry.line)
      continue;

    const int decl_line_is_too_late_fudge = 1;
    if (line &&
        m_location_spec.GetLine() < line - decl_line_is_too_late_fudge) {
      LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line);
      sc_list.RemoveContextAtIndex(i);
      --i;
    }
  }
}

Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback(
    SearchFilter &filter, SymbolContext &context, Address *addr) {
  SymbolContextList sc_list;

  // There is a tricky bit here.  You can have two compilation units that
  // #include the same file, and in one of them the function at m_line_number
  // is used (and so code and a line entry for it is generated) but in the
  // other it isn't.  If we considered the CU's independently, then in the
  // second inclusion, we'd move the breakpoint to the next function that
  // actually generated code in the header file.  That would end up being
  // confusing.  So instead, we do the CU iterations by hand here, then scan
  // through the complete list of matches, and figure out the closest line
  // number match, and only set breakpoints on that match.

  // Note also that if file_spec only had a file name and not a directory,
  // there may be many different file spec's in the resultant list.  The
  // closest line match for one will not be right for some totally different
  // file.  So we go through the match list and pull out the sets that have the
  // same file spec in their line_entry and treat each set separately.

  const uint32_t line = m_location_spec.GetLine().getValueOr(0);
  const llvm::Optional<uint16_t> column = m_location_spec.GetColumn();

  // We'll create a new SourceLocationSpec that can take into account the
  // relative path case, and we'll use it to resolve the symbol context
  // of the CUs.
  FileSpec search_file_spec = m_location_spec.GetFileSpec();
  const bool is_relative = search_file_spec.IsRelative();
  if (is_relative)
    search_file_spec.GetDirectory().Clear();
  SourceLocationSpec search_location_spec(
      search_file_spec, m_location_spec.GetLine().getValueOr(0),
      m_location_spec.GetColumn(), m_location_spec.GetCheckInlines(),
      m_location_spec.GetExactMatch());

  const size_t num_comp_units = context.module_sp->GetNumCompileUnits();
  for (size_t i = 0; i < num_comp_units; i++) {
    CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i));
    if (cu_sp) {
      if (filter.CompUnitPasses(*cu_sp))
        cu_sp->ResolveSymbolContext(search_location_spec,
                                    eSymbolContextEverything, sc_list);
    }
  }

  FilterContexts(sc_list, is_relative);

  StreamString s;
  s.Printf("for %s:%d ",
           m_location_spec.GetFileSpec().GetFilename().AsCString("<Unknown>"),
           line);

  SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(), line,
                     column);

  return Searcher::eCallbackReturnContinue;
}

lldb::SearchDepth BreakpointResolverFileLine::GetDepth() {
  return lldb::eSearchDepthModule;
}

void BreakpointResolverFileLine::GetDescription(Stream *s) {
  s->Printf("file = '%s', line = %u, ",
            m_location_spec.GetFileSpec().GetPath().c_str(),
            m_location_spec.GetLine().getValueOr(0));
  auto column = m_location_spec.GetColumn();
  if (column)
    s->Printf("column = %u, ", *column);
  s->Printf("exact_match = %d", m_location_spec.GetExactMatch());
}

void BreakpointResolverFileLine::Dump(Stream *s) const {}

lldb::BreakpointResolverSP
BreakpointResolverFileLine::CopyForBreakpoint(BreakpointSP &breakpoint) {
  lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(
      breakpoint, GetOffset(), m_skip_prologue, m_location_spec));

  return ret_sp;
}
