// go-linemap.cc -- GCC implementation of Linemap.

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-linemap.h"

#include "go-gcc.h"

// This class implements the Linemap interface defined by the
// frontend.

class Gcc_linemap : public Linemap
{
 public:
  Gcc_linemap()
    : Linemap(),
      in_file_(false)
  { }

  void
  start_file(const char* file_name, unsigned int line_begin);

  void
  start_line(unsigned int line_number, unsigned int line_size);

  Location
  get_location(unsigned int column);

  void
  stop();

  std::string
  to_string(Location);

  std::string
  location_file(Location);

  int
  location_line(Location);

 protected:
  Location
  get_predeclared_location();

  Location
  get_unknown_location();

  bool
  is_predeclared(Location);

  bool
  is_unknown(Location);

 private:
  // Whether we are currently reading a file.
  bool in_file_;
};

Linemap* Linemap::instance_ = NULL;

// Start getting locations from a new file.

void
Gcc_linemap::start_file(const char *file_name, unsigned line_begin)
{
  if (this->in_file_)
    linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
  linemap_add(line_table, LC_ENTER, 0, file_name, line_begin);
  this->in_file_ = true;
}

// Stringify a location

std::string
Gcc_linemap::to_string(Location location)
{
  const line_map_ordinary *lmo;
  location_t resolved_location;

  // Screen out unknown and predeclared locations; produce output
  // only for simple file:line locations.
  resolved_location =
      linemap_resolve_location (line_table, location.gcc_location(),
                                LRK_SPELLING_LOCATION, &lmo);
  if (lmo == NULL || resolved_location < RESERVED_LOCATION_COUNT)
    return "";
  const char *path = LINEMAP_FILE (lmo);
  if (!path)
    return "";

  // Strip the source file down to the base file, to reduce clutter.
  std::stringstream ss;
  ss << lbasename(path) << ":" << SOURCE_LINE (lmo, location.gcc_location());
  return ss.str();
}

// Return the file name for a given location.

std::string
Gcc_linemap::location_file(Location loc)
{
  return LOCATION_FILE(loc.gcc_location());
}

// Return the line number for a given location.

int
Gcc_linemap::location_line(Location loc)
{
  return LOCATION_LINE(loc.gcc_location());
}

// Stop getting locations.

void
Gcc_linemap::stop()
{
  linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
  this->in_file_ = false;
}

// Start a new line.

void
Gcc_linemap::start_line(unsigned lineno, unsigned linesize)
{
  linemap_line_start(line_table, lineno, linesize);
}

// Get a location.

Location
Gcc_linemap::get_location(unsigned column)
{
  return Location(linemap_position_for_column(line_table, column));
}

// Get the unknown location.

Location
Gcc_linemap::get_unknown_location()
{
  return Location(UNKNOWN_LOCATION);
}

// Get the predeclared location.

Location
Gcc_linemap::get_predeclared_location()
{
  return Location(BUILTINS_LOCATION);
}

// Return whether a location is the predeclared location.

bool
Gcc_linemap::is_predeclared(Location loc)
{
  return loc.gcc_location() == BUILTINS_LOCATION;
}

// Return whether a location is the unknown location.

bool
Gcc_linemap::is_unknown(Location loc)
{
  return loc.gcc_location() == UNKNOWN_LOCATION;
}

// Return the Linemap to use for the gcc backend.

Linemap*
go_get_linemap()
{
  return new Gcc_linemap;
}
