/* Default language-specific hooks.
   Copyright (C) 2001-2015 Free Software Foundation, Inc.
   Contributed by Alexandre Oliva  <aoliva@redhat.com>

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 "intl.h"
#include "tm.h"
#include "toplev.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-inline.h"
#include "gimplify.h"
#include "rtl.h"
#include "insn-config.h"
#include "flags.h"
#include "langhooks.h"
#include "target.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "tree-diagnostic.h"
#include "hash-map.h"
#include "is-a.h"
#include "plugin-api.h"
#include "hard-reg-set.h"
#include "input.h"
#include "function.h"
#include "ipa-ref.h"
#include "cgraph.h"
#include "timevar.h"
#include "output.h"

/* Do nothing; in many cases the default hook.  */

void
lhd_do_nothing (void)
{
}

/* Do nothing (tree).  */

void
lhd_do_nothing_t (tree ARG_UNUSED (t))
{
}

/* Pass through (tree).  */
tree
lhd_pass_through_t (tree t)
{
  return t;
}

/* Do nothing (int, int, int).  Return NULL_TREE.  */

tree
lhd_do_nothing_iii_return_null_tree (int ARG_UNUSED (i),
				     int ARG_UNUSED (j),
				     int ARG_UNUSED (k))
{
  return NULL_TREE;
}

/* Do nothing (function).  */

void
lhd_do_nothing_f (struct function * ARG_UNUSED (f))
{
}

/* Do nothing (return NULL_TREE).  */

tree
lhd_return_null_tree_v (void)
{
  return NULL_TREE;
}

/* Do nothing (return NULL_TREE).  */

tree
lhd_return_null_tree (tree ARG_UNUSED (t))
{
  return NULL_TREE;
}

/* Do nothing (return NULL_TREE).  */

tree
lhd_return_null_const_tree (const_tree ARG_UNUSED (t))
{
  return NULL_TREE;
}

/* The default post options hook.  */

bool
lhd_post_options (const char ** ARG_UNUSED (pfilename))
{
  /* Excess precision other than "fast" requires front-end
     support.  */
  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
  return false;
}

/* Called from by print-tree.c.  */

void
lhd_print_tree_nothing (FILE * ARG_UNUSED (file),
			tree ARG_UNUSED (node),
			int ARG_UNUSED (indent))
{
}

/* Called from check_global_declarations.  */

bool
lhd_warn_unused_global_decl (const_tree decl)
{
  /* This is what used to exist in check_global_declarations.  Probably
     not many of these actually apply to non-C languages.  */

  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
    return false;
  if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl))
    return false;
  if (DECL_IN_SYSTEM_HEADER (decl))
    return false;

  return true;
}

/* Set the DECL_ASSEMBLER_NAME for DECL.  */
void
lhd_set_decl_assembler_name (tree decl)
{
  tree id;

  /* set_decl_assembler_name may be called on TYPE_DECL to record ODR
     name for C++ types.  By default types have no ODR names.  */
  if (TREE_CODE (decl) == TYPE_DECL)
    return;

  /* The language-independent code should never use the
     DECL_ASSEMBLER_NAME for lots of DECLs.  Only FUNCTION_DECLs and
     VAR_DECLs for variables with static storage duration need a real
     DECL_ASSEMBLER_NAME.  */
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
	      || (TREE_CODE (decl) == VAR_DECL
		  && (TREE_STATIC (decl)
		      || DECL_EXTERNAL (decl)
		      || TREE_PUBLIC (decl))));

  /* By default, assume the name to use in assembly code is the same
     as that used in the source language.  (That's correct for C, and
     GCC used to set DECL_ASSEMBLER_NAME to the same value as
     DECL_NAME in build_decl, so this choice provides backwards
     compatibility with existing front-ends.  This assumption is wrapped
     in a target hook, to allow for target-specific modification of the
     identifier.

     Can't use just the variable's own name for a variable whose scope
     is less than the whole compilation.  Concatenate a distinguishing
     number - we use the DECL_UID.  */

  if (TREE_PUBLIC (decl) || DECL_FILE_SCOPE_P (decl))
    id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));
  else
    {
      const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
      char *label;

      ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
      id = get_identifier (label);
    }
  SET_DECL_ASSEMBLER_NAME (decl, id);

}

/* Type promotion for variable arguments.  */
tree
lhd_type_promotes_to (tree ARG_UNUSED (type))
{
  gcc_unreachable ();
}

/* Registration of machine- or os-specific builtin types.  */
void
lhd_register_builtin_type (tree ARG_UNUSED (type),
			   const char * ARG_UNUSED (name))
{
}

/* Invalid use of an incomplete type.  */
void
lhd_incomplete_type_error (const_tree ARG_UNUSED (value), const_tree type)
{
  gcc_assert (TREE_CODE (type) == ERROR_MARK);
  return;
}

/* Provide a default routine for alias sets that always returns -1.  This
   is used by languages that don't need to do anything special.  */

alias_set_type
lhd_get_alias_set (tree ARG_UNUSED (t))
{
  return -1;
}

/* This is the default decl_printable_name function.  */

const char *
lhd_decl_printable_name (tree decl, int ARG_UNUSED (verbosity))
{
  gcc_assert (decl && DECL_NAME (decl));
  return IDENTIFIER_POINTER (DECL_NAME (decl));
}

/* This is the default dwarf_name function.  */

const char *
lhd_dwarf_name (tree t, int verbosity)
{
  gcc_assert (DECL_P (t));

  return lang_hooks.decl_printable_name (t, verbosity);
}

/* This compares two types for equivalence ("compatible" in C-based languages).
   This routine should only return 1 if it is sure.  It should not be used
   in contexts where erroneously returning 0 causes problems.  */

int
lhd_types_compatible_p (tree x, tree y)
{
  return TYPE_MAIN_VARIANT (x) == TYPE_MAIN_VARIANT (y);
}

/* lang_hooks.tree_dump.dump_tree:  Dump language-specific parts of tree
   nodes.  Returns nonzero if it does not want the usual dumping of the
   second argument.  */

bool
lhd_tree_dump_dump_tree (void *di ATTRIBUTE_UNUSED, tree t ATTRIBUTE_UNUSED)
{
  return false;
}

/* lang_hooks.tree_dump.type_qual:  Determine type qualifiers in a
   language-specific way.  */

int
lhd_tree_dump_type_quals (const_tree t)
{
  return TYPE_QUALS (t);
}

/* lang_hooks.gimplify_expr re-writes *EXPR_P into GIMPLE form.  */

int
lhd_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED,
		   gimple_seq *pre_p ATTRIBUTE_UNUSED,
		   gimple_seq *post_p ATTRIBUTE_UNUSED)
{
  return GS_UNHANDLED;
}

/* lang_hooks.tree_size: Determine the size of a tree with code C,
   which is a language-specific tree code in category tcc_constant or
   tcc_exceptional.  The default expects never to be called.  */
size_t
lhd_tree_size (enum tree_code c ATTRIBUTE_UNUSED)
{
  gcc_unreachable ();
}

/* Return true if decl, which is a function decl, may be called by a
   sibcall.  */

bool
lhd_decl_ok_for_sibcall (const_tree decl ATTRIBUTE_UNUSED)
{
  return true;
}

/* lang_hooks.decls.final_write_globals: perform final processing on
   global variables.  */
void
write_global_declarations (void)
{
  tree globals, decl, *vec;
  int len, i;

  timevar_start (TV_PHASE_DEFERRED);
  /* Really define vars that have had only a tentative definition.
     Really output inline functions that must actually be callable
     and have not been output so far.  */

  globals = lang_hooks.decls.getdecls ();
  len = list_length (globals);
  vec = XNEWVEC (tree, len);

  /* Process the decls in reverse order--earliest first.
     Put them into VEC from back to front, then take out from front.  */

  for (i = 0, decl = globals; i < len; i++, decl = DECL_CHAIN (decl))
    vec[len - i - 1] = decl;

  wrapup_global_declarations (vec, len);
  check_global_declarations (vec, len);
  timevar_stop (TV_PHASE_DEFERRED);

  timevar_start (TV_PHASE_OPT_GEN);
  /* This lang hook is dual-purposed, and also finalizes the
     compilation unit.  */
  symtab->finalize_compilation_unit ();
  timevar_stop (TV_PHASE_OPT_GEN);

  timevar_start (TV_PHASE_DBGINFO);
  emit_debug_global_declarations (vec, len);
  timevar_stop (TV_PHASE_DBGINFO);

  /* Clean up.  */
  free (vec);
}

/* Called to perform language-specific initialization of CTX.  */
void
lhd_initialize_diagnostics (diagnostic_context *ctx ATTRIBUTE_UNUSED)
{
}

/* Called to perform language-specific options initialization.  */
void
lhd_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
		  struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
{
}

/* By default, always complain about options for the wrong language.  */
bool
lhd_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
{
  return true;
}

/* By default, no language-specific options are valid.  */
bool
lhd_handle_option (size_t code ATTRIBUTE_UNUSED,
		   const char *arg ATTRIBUTE_UNUSED,
		   int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
		   location_t loc ATTRIBUTE_UNUSED,
		   const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{
  return false;
}

/* The default function to print out name of current function that caused
   an error.  */
void
lhd_print_error_function (diagnostic_context *context, const char *file,
			  diagnostic_info *diagnostic)
{
  if (diagnostic_last_function_changed (context, diagnostic))
    {
      const char *old_prefix = context->printer->prefix;
      tree abstract_origin = diagnostic_abstract_origin (diagnostic);
      char *new_prefix = (file && abstract_origin == NULL)
			 ? file_name_as_prefix (context, file) : NULL;

      pp_set_prefix (context->printer, new_prefix);

      if (current_function_decl == NULL)
	pp_printf (context->printer, _("At top level:"));
      else
	{
	  tree fndecl, ao;

	  if (abstract_origin)
	    {
	      ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
	      while (TREE_CODE (ao) == BLOCK
		     && BLOCK_ABSTRACT_ORIGIN (ao)
		     && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
		ao = BLOCK_ABSTRACT_ORIGIN (ao);
	      gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
	      fndecl = ao;
	    }
	  else
	    fndecl = current_function_decl;

	  if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
	    pp_printf
	      (context->printer, _("In member function %qs"),
	       identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)));
	  else
	    pp_printf
	      (context->printer, _("In function %qs"),
	       identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)));

	  while (abstract_origin)
	    {
	      location_t *locus;
	      tree block = abstract_origin;

	      locus = &BLOCK_SOURCE_LOCATION (block);
	      fndecl = NULL;
	      block = BLOCK_SUPERCONTEXT (block);
	      while (block && TREE_CODE (block) == BLOCK
		     && BLOCK_ABSTRACT_ORIGIN (block))
		{
		  ao = BLOCK_ABSTRACT_ORIGIN (block);

		  while (TREE_CODE (ao) == BLOCK
			 && BLOCK_ABSTRACT_ORIGIN (ao)
			 && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
		    ao = BLOCK_ABSTRACT_ORIGIN (ao);

		  if (TREE_CODE (ao) == FUNCTION_DECL)
		    {
		      fndecl = ao;
		      break;
		    }
		  else if (TREE_CODE (ao) != BLOCK)
		    break;

		  block = BLOCK_SUPERCONTEXT (block);
		}
	      if (fndecl)
		abstract_origin = block;
	      else
		{
		  while (block && TREE_CODE (block) == BLOCK)
		    block = BLOCK_SUPERCONTEXT (block);

		  if (block && TREE_CODE (block) == FUNCTION_DECL)
		    fndecl = block;
		  abstract_origin = NULL;
		}
	      if (fndecl)
		{
		  expanded_location s = expand_location (*locus);
		  pp_comma (context->printer);
		  pp_newline (context->printer);
		  if (s.file != NULL)
		    {
		      if (context->show_column)
			pp_printf (context->printer,
				   _("    inlined from %qs at %r%s:%d:%d%R"),
				   identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)),
				   "locus", s.file, s.line, s.column);
		      else
			pp_printf (context->printer,
				   _("    inlined from %qs at %r%s:%d%R"),
				   identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)),
				   "locus", s.file, s.line);

		    }
		  else
		    pp_printf (context->printer, _("    inlined from %qs"),
			       identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)));
		}
	    }
	  pp_colon (context->printer);
	}

      diagnostic_set_last_function (context, diagnostic);
      pp_newline_and_flush (context->printer);
      context->printer->prefix = old_prefix;
      free ((char*) new_prefix);
    }
}

tree
lhd_make_node (enum tree_code code)
{
  return make_node (code);
}

HOST_WIDE_INT
lhd_to_target_charset (HOST_WIDE_INT c)
{
  return c;
}

tree
lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED, bool *se ATTRIBUTE_UNUSED)
{
  return expr;
}

/* Return sharing kind if OpenMP sharing attribute of DECL is
   predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise.  */

enum omp_clause_default_kind
lhd_omp_predetermined_sharing (tree decl ATTRIBUTE_UNUSED)
{
  if (DECL_ARTIFICIAL (decl))
    return OMP_CLAUSE_DEFAULT_SHARED;
  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
}

/* Generate code to copy SRC to DST.  */

tree
lhd_omp_assignment (tree clause ATTRIBUTE_UNUSED, tree dst, tree src)
{
  return build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
}

/* Finalize clause C.  */

void
lhd_omp_finish_clause (tree, gimple_seq *)
{
}

/* Register language specific type size variables as potentially OpenMP
   firstprivate variables.  */

void
lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *c ATTRIBUTE_UNUSED,
				   tree t ATTRIBUTE_UNUSED)
{
}

/* Return true if TYPE is an OpenMP mappable type.  */

bool
lhd_omp_mappable_type (tree type)
{
  /* Mappable type has to be complete.  */
  if (type == error_mark_node || !COMPLETE_TYPE_P (type))
    return false;
  return true;
}

/* Common function for add_builtin_function and
   add_builtin_function_ext_scope.  */
static tree
add_builtin_function_common (const char *name,
			     tree type,
			     int function_code,
			     enum built_in_class cl,
			     const char *library_name,
			     tree attrs,
			     tree (*hook) (tree))
{
  tree   id = get_identifier (name);
  tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, id, type);

  TREE_PUBLIC (decl)         = 1;
  DECL_EXTERNAL (decl)       = 1;
  DECL_BUILT_IN_CLASS (decl) = cl;

  DECL_FUNCTION_CODE (decl)  = (enum built_in_function) function_code;

  /* DECL_FUNCTION_CODE is a bitfield; verify that the value fits.  */
  gcc_assert (DECL_FUNCTION_CODE (decl) == function_code);

  if (library_name)
    {
      tree libname = get_identifier (library_name);
      SET_DECL_ASSEMBLER_NAME (decl, libname);
    }

  /* Possibly apply some default attributes to this built-in function.  */
  if (attrs)
    decl_attributes (&decl, attrs, ATTR_FLAG_BUILT_IN);
  else
    decl_attributes (&decl, NULL_TREE, 0);

  return hook (decl);

}

/* Create a builtin function.  */

tree
add_builtin_function (const char *name,
		      tree type,
		      int function_code,
		      enum built_in_class cl,
		      const char *library_name,
		      tree attrs)
{
  return add_builtin_function_common (name, type, function_code, cl,
				      library_name, attrs,
				      lang_hooks.builtin_function);
}

/* Like add_builtin_function, but make sure the scope is the external scope.
   This is used to delay putting in back end builtin functions until the ISA
   that defines the builtin is declared via function specific target options,
   which can save memory for machines like the x86_64 that have multiple ISAs.
   If this points to the same function as builtin_function, the backend must
   add all of the builtins at program initialization time.  */

tree
add_builtin_function_ext_scope (const char *name,
				tree type,
				int function_code,
				enum built_in_class cl,
				const char *library_name,
				tree attrs)
{
  return add_builtin_function_common (name, type, function_code, cl,
				      library_name, attrs,
				      lang_hooks.builtin_function_ext_scope);
}

tree
lhd_builtin_function (tree decl)
{
  lang_hooks.decls.pushdecl (decl);
  return decl;
}

/* Create a builtin type.  */

tree
add_builtin_type (const char *name, tree type)
{
  tree   id = get_identifier (name);
  tree decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, id, type);
  return lang_hooks.decls.pushdecl (decl);
}

/* LTO hooks.  */

/* Used to save and restore any previously active section.  */
static section *saved_section;


/* Begin a new LTO output section named NAME.  This default implementation
   saves the old section and emits assembly code to switch to the new
   section.  */

void
lhd_begin_section (const char *name)
{
  section *section;

  /* Save the old section so we can restore it in lto_end_asm_section.  */
  gcc_assert (!saved_section);
  saved_section = in_section;
  if (!saved_section)
    saved_section = text_section;

  /* Create a new section and switch to it.  */
  section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL);
  switch_to_section (section);
}


/* Write DATA of length LEN to the current LTO output section.  This default
   implementation just calls assemble_string.  */

void
lhd_append_data (const void *data, size_t len, void *)
{
  if (data)
    assemble_string ((const char *)data, len);
}


/* Finish the current LTO output section.  This default implementation emits
   assembly code to switch to any section previously saved by
   lhd_begin_section.  */

void
lhd_end_section (void)
{
  if (saved_section)
    {
      switch_to_section (saved_section);
      saved_section = NULL;
    }
}

/* Default implementation of enum_underlying_base_type using type_for_size.  */

tree
lhd_enum_underlying_base_type (const_tree enum_type)
{
  return lang_hooks.types.type_for_size (TYPE_PRECISION (enum_type),
					 TYPE_UNSIGNED (enum_type));
}

/* Returns true if the current lang_hooks represents the GNU C frontend.  */

bool
lang_GNU_C (void)
{
  return (strncmp (lang_hooks.name, "GNU C", 5) == 0
	  && (lang_hooks.name[5] == '\0' || ISDIGIT (lang_hooks.name[5])));
}

/* Returns true if the current lang_hooks represents the GNU C++ frontend.  */

bool
lang_GNU_CXX (void)
{
  return strncmp (lang_hooks.name, "GNU C++", 7) == 0;
}

/* Returns true if the current lang_hooks represents the GNU Fortran frontend.  */

bool
lang_GNU_Fortran (void)
{
  return strncmp (lang_hooks.name, "GNU Fortran", 11) == 0;
}
