/* Implementation of gcc_rich_location class
   Copyright (C) 2014-2019 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "hash-set.h"
#include "vec.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "inchash.h"
#include "tree-core.h"
#include "tree.h"
#include "diagnostic-core.h"
#include "gcc-rich-location.h"
#include "print-tree.h"
#include "pretty-print.h"
#include "intl.h"
#include "cpplib.h"
#include "diagnostic.h"

/* Add a range to the rich_location, covering expression EXPR,
   using LABEL if non-NULL. */

void
gcc_rich_location::add_expr (tree expr, range_label *label)
{
  gcc_assert (expr);

  if (CAN_HAVE_RANGE_P (expr))
    add_range (EXPR_LOCATION (expr), SHOW_RANGE_WITHOUT_CARET, label);
}

/* If T is an expression, add a range for it to the rich_location,
   using LABEL if non-NULL. */

void
gcc_rich_location::maybe_add_expr (tree t, range_label *label)
{
  if (EXPR_P (t))
    add_expr (t, label);
}

/* Add a fixit hint suggesting replacing the range at MISSPELLED_TOKEN_LOC
   with the identifier HINT_ID.  */

void
gcc_rich_location::add_fixit_misspelled_id (location_t misspelled_token_loc,
					    tree hint_id)
{
  gcc_assert (TREE_CODE (hint_id) == IDENTIFIER_NODE);

  add_fixit_replace (misspelled_token_loc, IDENTIFIER_POINTER (hint_id));
}

/* Return true if there is nothing on LOC's line before LOC.  */

static bool
blank_line_before_p (location_t loc)
{
  expanded_location exploc = expand_location (loc);
  char_span line = location_get_source_line (exploc.file, exploc.line);
  if (!line)
    return false;
  if (line.length () < (size_t)exploc.column)
    return false;
  /* Columns are 1-based.  */
  for (int column = 1; column < exploc.column; ++column)
    if (!ISSPACE (line[column - 1]))
      return false;
  return true;
}

/* Subroutine of gcc_rich_location::add_fixit_insert_formatted.
   Return true if we should add the content on its own line,
   false otherwise.
   If true is returned then *OUT_START_OF_LINE is written to.  */

static bool
use_new_line (location_t insertion_point, location_t indent,
	      location_t *out_start_of_line)
{
  if (indent == UNKNOWN_LOCATION)
    return false;
  const line_map *indent_map = linemap_lookup (line_table, indent);
  if (linemap_macro_expansion_map_p (indent_map))
    return false;

  if (!blank_line_before_p (insertion_point))
    return false;

  /* Locate the start of the line containing INSERTION_POINT.  */
  const line_map *insertion_point_map
    = linemap_lookup (line_table, insertion_point);
  if (linemap_macro_expansion_map_p (insertion_point_map))
    return false;
  const line_map_ordinary *ordmap
    = linemap_check_ordinary (insertion_point_map);
  expanded_location exploc_insertion_point = expand_location (insertion_point);
  location_t start_of_line
    = linemap_position_for_line_and_column (line_table, ordmap,
					    exploc_insertion_point.line, 1);
  *out_start_of_line = start_of_line;
  return true;
}

/* Add a fix-it hint suggesting the insertion of CONTENT before
   INSERTION_POINT.

   Attempt to handle formatting: if INSERTION_POINT is the first thing on
   its line, and INDENT is sufficiently sane, then add CONTENT on its own
   line, using the indentation of INDENT.
   Otherwise, add CONTENT directly before INSERTION_POINT.

   For example, adding "CONTENT;" with the closing brace as the insertion
   point and "INDENT;" as the indentation point:

   if ()
     {
       INDENT;
     }

  would lead to:

   if ()
     {
       INDENT;
       CONTENT;
     }

  but adding it to:

    if () {INDENT;}

  would lead to:

    if () {INDENT;CONTENT;}
*/

void
gcc_rich_location::add_fixit_insert_formatted (const char *content,
					       location_t insertion_point,
					       location_t indent)
{
  location_t start_of_line;
  if (use_new_line (insertion_point, indent, &start_of_line))
    {
      /* Add CONTENT on its own line, using the indentation of INDENT.  */

      /* Generate an insertion string, indenting by the amount INDENT
	 was indented.  */
      int indent_column = LOCATION_COLUMN (get_start (indent));
      pretty_printer tmp_pp;
      pretty_printer *pp = &tmp_pp;
      /* Columns are 1-based.  */
      for (int column = 1; column < indent_column; ++column)
	pp_space (pp);
      pp_string (pp, content);
      pp_newline (pp);

      add_fixit_insert_before (start_of_line, pp_formatted_text (pp));
    }
  else
    add_fixit_insert_before (insertion_point, content);
}

/* Implementation of range_label::get_text for
   maybe_range_label_for_tree_type_mismatch.

   If both expressions are non-NULL, then generate text describing
   the first expression's type (using the other expression's type
   for comparison, analogous to %H and %I in the C++ frontend, but
   on expressions rather than types).  */

label_text
maybe_range_label_for_tree_type_mismatch::get_text (unsigned range_idx) const
{
  if (m_expr == NULL_TREE
      || !EXPR_P (m_expr))
    return label_text (NULL, false);
  tree expr_type = TREE_TYPE (m_expr);

  tree other_type = NULL_TREE;
  if (m_other_expr && EXPR_P (m_other_expr))
    other_type = TREE_TYPE (m_other_expr);

  range_label_for_type_mismatch inner (expr_type, other_type);
  return inner.get_text (range_idx);
}

/* binary_op_rich_location's ctor.

   If use_operator_loc_p (LOC, ARG0, ARG1), then attempt to make a 3-location
   rich_location of the form:

     arg_0 op arg_1
     ~~~~~ ^~ ~~~~~
       |        |
       |        arg1 type
       arg0 type

   labelling the types of the arguments if SHOW_TYPES is true.

   Otherwise, make a 1-location rich_location using the compound
   location within LOC:

     arg_0 op arg_1
     ~~~~~~^~~~~~~~

   for which we can't label the types.  */

binary_op_rich_location::binary_op_rich_location (const op_location_t &loc,
						  tree arg0, tree arg1,
						  bool show_types)
: gcc_rich_location (loc.m_combined_loc),
  m_label_for_arg0 (arg0, arg1),
  m_label_for_arg1 (arg1, arg0)
{
  /* Default (above) to using the combined loc.
     Potentially override it here: if we have location information for the
     operator and for both arguments, then split them all out.
     Alternatively, override it if we don't have the combined location.  */
  if (use_operator_loc_p (loc, arg0, arg1))
    {
      set_range (0, loc.m_operator_loc, SHOW_RANGE_WITH_CARET);
      maybe_add_expr (arg0, show_types ? &m_label_for_arg0 : NULL);
      maybe_add_expr (arg1, show_types ? &m_label_for_arg1 : NULL);
    }
}

/* Determine if binary_op_rich_location's ctor should attempt to make
   a 3-location rich_location (the location of the operator and of
   the 2 arguments), or fall back to a 1-location rich_location showing
   just the combined location of the operation as a whole.  */

bool
binary_op_rich_location::use_operator_loc_p (const op_location_t &loc,
					     tree arg0, tree arg1)
{
  /* If we don't have a combined location, then use the operator location,
     and try to add ranges for the operators.  */
  if (loc.m_combined_loc == UNKNOWN_LOCATION)
    return true;

  /* If we don't have the operator location, then use the
     combined location.  */
  if (loc.m_operator_loc == UNKNOWN_LOCATION)
    return false;

  /* We have both operator location and combined location: only use the
     operator location if we have locations for both arguments.  */
  return (EXPR_HAS_LOCATION (arg0)
	  && EXPR_HAS_LOCATION (arg1));
}
