/* Language-specific hook definitions for CHILL front end.
   Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000, 2001
   Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC 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 2, or (at your option)
any later version.

GNU CC 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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */


#include "config.h"
#include "system.h"
#include "tree.h"
#include "ch-tree.h"
#include "lex.h"
#include "input.h"
#include "toplev.h"
#include "rtl.h"
#include "expr.h"
#include "diagnostic.h"

/* Type node for boolean types.  */

tree boolean_type_node;

/* True if STRING(INDEX) yields a CHARS(1) (or BOOLS(1)) rather than
   a CHAR (or BOOL).  Also, makes CHARS(1) similar for CHAR,
   and BOOLS(1) similar to BOOL.  This is for compatibility
   for the 1984 version of Z.200.*/
int flag_old_strings = 0;

/* This is set non-zero to force user input tokens to lower case.
   This is non-standard.  See Z.200, page 8. */
int ignore_case = 1;

/* True if reserved and predefined words ('special' words in the Z.200
   terminology) are in uppercase.  Obviously, this had better not be 
   true if we're ignoring input case. */
int special_UC = 0;

/* The actual name of the input file, regardless of any #line directives */
const char* chill_real_input_filename;
extern FILE* finput;

static int deep_const_expr			PARAMS ((tree));
static void chill_print_error_function          PARAMS ((diagnostic_context *,
                                                         const char *));

/* Return 1 if the expression tree given has all
   constant nodes as its leaves,otherwise. */

static int
deep_const_expr (exp)
     tree exp;
{
  enum chill_tree_code code;
  int length;
  int i;

  if (exp == NULL_TREE)
    return 0;

  code = TREE_CODE (exp);
  length = first_rtl_op (TREE_CODE (exp));

  /* constant leaf?  return TRUE */
  if (TREE_CODE_CLASS (code) == 'c')
    return 1;

  /* Recursively check next level down.  */
  for (i = 0; i < length; i++)
    if (! deep_const_expr (TREE_OPERAND (exp, i)))
      return 0;
  return 1;      
}


tree
const_expr (exp)
     tree exp;
{
  if (TREE_CODE (exp) == INTEGER_CST)
    return exp;
  if (TREE_CODE (exp) == CONST_DECL)
    return const_expr (DECL_INITIAL (exp));
  if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
      && DECL_INITIAL (exp) != NULL_TREE
      && TREE_READONLY (exp))
    return DECL_INITIAL (exp);
  if (deep_const_expr (exp))
    return exp;
  if (TREE_CODE (exp) != ERROR_MARK)
    error ("non-constant expression");
  return error_mark_node;
}

/* Each of the functions defined here
   is an alternative to a function in objc-actions.c.  */
   
/* Used by c-lex.c, but only for objc.  */
tree
lookup_interface (arg)
     tree arg ATTRIBUTE_UNUSED;
{
  return 0;
}

int
maybe_objc_comptypes (lhs, rhs)
     tree lhs ATTRIBUTE_UNUSED, rhs ATTRIBUTE_UNUSED;
{
  return -1;
}

tree
maybe_building_objc_message_expr ()
{
  return 0;
}

int
recognize_objc_keyword ()
{
  return 0;
}

void
lang_init_options ()
{
}

/* used by print-tree.c */

void
lang_print_xnode (file, node, indent)
     FILE *file ATTRIBUTE_UNUSED;
     tree node ATTRIBUTE_UNUSED;
     int indent ATTRIBUTE_UNUSED;
{
}

/*
 * process chill-specific compiler command-line options
 * do not complain if the option is not recognised
 */
int
lang_decode_option (argc, argv)
     int argc;
     char **argv;
{
  char *p = argv[0];
  static int explicit_ignore_case = 0;
  if (!strcmp(p, "-lang-chill"))
    ; /* do nothing */
  else if (!strcmp (p, "-fruntime-checking"))
    {
      range_checking = 1;
      empty_checking = 1;
    }
  else if (!strcmp (p, "-fno-runtime-checking"))
    {
      range_checking = 0;
      empty_checking = 0;
      runtime_checking_flag = 0;
    }
  else if (!strcmp (p, "-flocal-loop-counter"))
    flag_local_loop_counter = 1;
  else if (!strcmp (p, "-fno-local-loop-counter"))
    flag_local_loop_counter = 0;
  else if (!strcmp (p, "-fold-strings"))
    flag_old_strings = 1;
  else if (!strcmp (p, "-fno-old-strings"))
    flag_old_strings = 0;
  else if (!strcmp (p, "-fignore-case"))
    {
      explicit_ignore_case = 1;
      if (special_UC)
	{
	  error ("ignoring case upon input and");
	  error ("making special words uppercase wouldn't work");
	}
      else
	ignore_case = 1;
    }
  else if (!strcmp (p, "-fno-ignore-case"))
    ignore_case = 0;
  else if (!strcmp (p, "-fspecial_UC"))
    {
      if (explicit_ignore_case)
	{
	  error ("making special words uppercase and");
	  error (" ignoring case upon input wouldn't work");
	}
      else
	special_UC = 1, ignore_case = 0;
    }
  else if (!strcmp (p, "-fspecial_LC"))
    special_UC = 0;
  else if (!strcmp (p, "-fpack"))
    maximum_field_alignment = BITS_PER_UNIT;
  else if (!strcmp (p, "-fno-pack"))
    maximum_field_alignment = 0;
  else if (!strcmp (p, "-fchill-grant-only"))
    grant_only_flag = 1;
  else if (!strcmp (p, "-fgrant-only"))
    grant_only_flag = 1;
  /* user has specified a seize-file path */
  else if (p[0] == '-' && p[1] == 'I')
    register_seize_path (&p[2]);
  if (!strcmp(p, "-itu"))        /* Force Z.200 semantics */
    {
      pedantic = 1;   /* FIXME: new flag name? */
      flag_local_loop_counter = 1;      
    }
  else
    return c_decode_option (argc, argv);

  return 1;
}

static void
chill_print_error_function (context, file)
     diagnostic_context *buffer __attribute__((__unused__));
     const char *file;
{
  static tree last_error_function = NULL_TREE;
  static struct module *last_error_module = NULL;

  if (last_error_function == current_function_decl
      && last_error_module == current_module)
    return;

  last_error_function = current_function_decl;
  last_error_module = current_module;

  if (file)
    fprintf (stderr, "%s: ", file);

  if (current_function_decl == global_function_decl
      || current_function_decl == NULL_TREE)
    {
      if (current_module == NULL)
	fprintf (stderr, "At top level:\n");
      else
	fprintf (stderr, "In module %s:\n",
		 IDENTIFIER_POINTER (current_module->name));
    }
  else
    {
      const char *kind = "function";
      const char *name = (*decl_printable_name) (current_function_decl, 2);
      fprintf (stderr, "In %s `%s':\n", kind, name);
    }
}

/* Print an error message for invalid use of an incomplete type.
   VALUE is the expression that was used (or 0 if that isn't known)
   and TYPE is the type that was invalid.  */

void
incomplete_type_error (value, type)
     tree value ATTRIBUTE_UNUSED;
     tree type ATTRIBUTE_UNUSED;
{
  error ("internal error - use of undefined type");
}

/* Return the typed-based alias set for T, which may be an expression
   or a type.  Return -1 if we don't do anything special.  */

HOST_WIDE_INT
lang_get_alias_set (t)
     tree t ATTRIBUTE_UNUSED;
{
  /* ??? Need to figure out what the rules are.  Certainly we'd need
     to handle union-like things, and probably variant records. 
     Until then, turn off type-based aliasing completely.  */
  return 0;
}

void
lang_init ()
{
  chill_real_input_filename = input_filename;

  /* the beginning of the file is a new line; check for # */
  /* With luck, we discover the real source file's name from that
     and put it in input_filename.  */

  ungetc (check_newline (), finput);

  /* set default grant file */
  set_default_grant_file ();

  print_error_function = chill_print_error_function;
}
