(root)/
gcc-13.2.0/
gcc/
rust/
rust-linemap.cc
// Copyright (C) 2020-2023 Free Software Foundation, Inc.

// This file is part of GCC.

// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.

// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.

// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

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

#include "rust-linemap.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);

  int location_column (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 ())
     << ":" << SOURCE_COLUMN (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 ());
}

// Return the column number for a given location.
int
Gcc_linemap::location_column (Location loc)
{
  return LOCATION_COLUMN (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 *
rust_get_linemap ()
{
  return new Gcc_linemap;
}

RichLocation::RichLocation (Location root)
  : gcc_rich_loc (line_table, root.gcc_location ())
{
  /*rich_location (line_maps *set, location_t loc,
		 const range_label *label = NULL);*/
}

RichLocation::~RichLocation () {}

void
RichLocation::add_range (Location loc)
{
  gcc_rich_loc.add_range (loc.gcc_location ());
}

void
RichLocation::add_fixit_insert_before (const std::string &new_parent)
{
  gcc_rich_loc.add_fixit_insert_before (new_parent.c_str ());
}

void
RichLocation::add_fixit_insert_before (Location where,
				       const std::string &new_parent)
{
  gcc_rich_loc.add_fixit_insert_before (where.gcc_location (),
					new_parent.c_str ());
}

void
RichLocation::add_fixit_insert_after (const std::string &new_parent)
{
  gcc_rich_loc.add_fixit_insert_after (new_parent.c_str ());
}

void
RichLocation::add_fixit_insert_after (Location where,
				      const std::string &new_parent)
{
  gcc_rich_loc.add_fixit_insert_after (where.gcc_location (),
				       new_parent.c_str ());
}