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

#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

using namespace lldb_private;

LineEntry::LineEntry()
    : range(), file(), line(LLDB_INVALID_LINE_NUMBER), column(0),
      is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0),
      is_epilogue_begin(0), is_terminal_entry(0) {}

LineEntry::LineEntry(const lldb::SectionSP &section_sp,
                     lldb::addr_t section_offset, lldb::addr_t byte_size,
                     const FileSpec &_file, uint32_t _line, uint16_t _column,
                     bool _is_start_of_statement, bool _is_start_of_basic_block,
                     bool _is_prologue_end, bool _is_epilogue_begin,
                     bool _is_terminal_entry)
    : range(section_sp, section_offset, byte_size), file(_file),
      original_file(_file), line(_line), column(_column),
      is_start_of_statement(_is_start_of_statement),
      is_start_of_basic_block(_is_start_of_basic_block),
      is_prologue_end(_is_prologue_end), is_epilogue_begin(_is_epilogue_begin),
      is_terminal_entry(_is_terminal_entry) {}

void LineEntry::Clear() {
  range.Clear();
  file.Clear();
  original_file.Clear();
  line = LLDB_INVALID_LINE_NUMBER;
  column = 0;
  is_start_of_statement = 0;
  is_start_of_basic_block = 0;
  is_prologue_end = 0;
  is_epilogue_begin = 0;
  is_terminal_entry = 0;
}

bool LineEntry::IsValid() const {
  return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER;
}

bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const {
  bool result = false;
  if (file) {
    if (show_fullpaths)
      file.Dump(s);
    else
      file.GetFilename().Dump(s);

    if (line)
      s->PutChar(':');
    result = true;
  }
  if (line)
    s->Printf("%u", line);
  else
    result = false;

  return result;
}

bool LineEntry::Dump(Stream *s, Target *target, bool show_file,
                     Address::DumpStyle style,
                     Address::DumpStyle fallback_style, bool show_range) const {
  if (show_range) {
    // Show address range
    if (!range.Dump(s, target, style, fallback_style))
      return false;
  } else {
    // Show address only
    if (!range.GetBaseAddress().Dump(s, target, style, fallback_style))
      return false;
  }
  if (show_file)
    *s << ", file = " << file;
  if (line)
    s->Printf(", line = %u", line);
  if (column)
    s->Printf(", column = %u", column);
  if (is_start_of_statement)
    *s << ", is_start_of_statement = TRUE";

  if (is_start_of_basic_block)
    *s << ", is_start_of_basic_block = TRUE";

  if (is_prologue_end)
    *s << ", is_prologue_end = TRUE";

  if (is_epilogue_begin)
    *s << ", is_epilogue_begin = TRUE";

  if (is_terminal_entry)
    *s << ", is_terminal_entry = TRUE";
  return true;
}

bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level,
                               CompileUnit *cu, Target *target,
                               bool show_address_only) const {

  if (level == lldb::eDescriptionLevelBrief ||
      level == lldb::eDescriptionLevelFull) {
    if (show_address_only) {
      range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress,
                                  Address::DumpStyleFileAddress);
    } else {
      range.Dump(s, target, Address::DumpStyleLoadAddress,
                 Address::DumpStyleFileAddress);
    }

    *s << ": " << file;

    if (line) {
      s->Printf(":%u", line);
      if (column)
        s->Printf(":%u", column);
    }

    if (level == lldb::eDescriptionLevelFull) {
      if (is_start_of_statement)
        *s << ", is_start_of_statement = TRUE";

      if (is_start_of_basic_block)
        *s << ", is_start_of_basic_block = TRUE";

      if (is_prologue_end)
        *s << ", is_prologue_end = TRUE";

      if (is_epilogue_begin)
        *s << ", is_epilogue_begin = TRUE";

      if (is_terminal_entry)
        *s << ", is_terminal_entry = TRUE";
    } else {
      if (is_terminal_entry)
        s->EOL();
    }
  } else {
    return Dump(s, target, true, Address::DumpStyleLoadAddress,
                Address::DumpStyleModuleWithFileAddress, true);
  }
  return true;
}

bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) {
  return LineEntry::Compare(a, b) < 0;
}

int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
  int result = Address::CompareFileAddress(a.range.GetBaseAddress(),
                                           b.range.GetBaseAddress());
  if (result != 0)
    return result;

  const lldb::addr_t a_byte_size = a.range.GetByteSize();
  const lldb::addr_t b_byte_size = b.range.GetByteSize();

  if (a_byte_size < b_byte_size)
    return -1;
  if (a_byte_size > b_byte_size)
    return +1;

  // Check for an end sequence entry mismatch after we have determined that the
  // address values are equal. If one of the items is an end sequence, we don't
  // care about the line, file, or column info.
  if (a.is_terminal_entry > b.is_terminal_entry)
    return -1;
  if (a.is_terminal_entry < b.is_terminal_entry)
    return +1;

  if (a.line < b.line)
    return -1;
  if (a.line > b.line)
    return +1;

  if (a.column < b.column)
    return -1;
  if (a.column > b.column)
    return +1;

  return FileSpec::Compare(a.file, b.file, true);
}

AddressRange LineEntry::GetSameLineContiguousAddressRange() const {
  // Add each LineEntry's range to complete_line_range until we find a
  // different file / line number.
  AddressRange complete_line_range = range;

  while (true) {
    SymbolContext next_line_sc;
    Address range_end(complete_line_range.GetBaseAddress());
    range_end.Slide(complete_line_range.GetByteSize());
    range_end.CalculateSymbolContext(&next_line_sc,
                                     lldb::eSymbolContextLineEntry);

    if (next_line_sc.line_entry.IsValid() &&
        next_line_sc.line_entry.range.GetByteSize() > 0 &&
        original_file == next_line_sc.line_entry.original_file) {
      // Include any line 0 entries - they indicate that this is compiler-
      // generated code that does not correspond to user source code.
      if (next_line_sc.line_entry.line == 0) {
        complete_line_range.SetByteSize(
            complete_line_range.GetByteSize() +
            next_line_sc.line_entry.range.GetByteSize());
        continue;
      }

      if (line == next_line_sc.line_entry.line) {
        // next_line_sc is the same file & line as this LineEntry, so extend
        // our AddressRange by its size and continue to see if there are more
        // LineEntries that we can combine.
        complete_line_range.SetByteSize(
            complete_line_range.GetByteSize() +
            next_line_sc.line_entry.range.GetByteSize());
        continue;
      }
    }
    break;
  }
  return complete_line_range;
}

void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {
  if (target_sp) {
    // Apply any file remappings to our file
    FileSpec new_file_spec;
    if (target_sp->GetSourcePathMap().FindFile(original_file, new_file_spec))
      file = new_file_spec;
  }
}
