/* Perform the semantic phase of parsing, i.e., the process of
   building tree structure, checking semantic consistency, and
   building RTL.  These routines are used both during actual parsing
   and during the instantiation of template functions. 

   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
   Written by Mark Mitchell (mmitchell@usa.net) based on code found
   formerly in parse.y and pt.c.  

   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 "cp-tree.h"
#include "except.h"
#include "lex.h"
#include "toplev.h"
#include "flags.h"
#include "ggc.h"
#include "rtl.h"
#include "output.h"
#include "timevar.h"

/* There routines provide a modular interface to perform many parsing
   operations.  They may therefore be used during actual parsing, or
   during template instantiation, which may be regarded as a
   degenerate form of parsing.  Since the current g++ parser is
   lacking in several respects, and will be reimplemented, we are
   attempting to move most code that is not directly related to
   parsing into this file; that will make implementing the new parser
   much easier since it will be able to make use of these routines.  */

static tree maybe_convert_cond PARAMS ((tree));
static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
static void deferred_type_access_control PARAMS ((void));
static void emit_associated_thunks PARAMS ((tree));
static void genrtl_try_block PARAMS ((tree));
static void genrtl_eh_spec_block PARAMS ((tree));
static void genrtl_handler PARAMS ((tree));
static void genrtl_catch_block PARAMS ((tree));
static void genrtl_ctor_stmt PARAMS ((tree));
static void genrtl_subobject PARAMS ((tree));
static void genrtl_named_return_value PARAMS ((void));
static void cp_expand_stmt PARAMS ((tree));
static void genrtl_start_function PARAMS ((tree));
static void genrtl_finish_function PARAMS ((tree));
static tree clear_decl_rtl PARAMS ((tree *, int *, void *));

/* Finish processing the COND, the SUBSTMT condition for STMT.  */

#define FINISH_COND(cond, stmt, substmt) 		\
  do {							\
    if (last_tree != stmt)				\
      {							\
        RECHAIN_STMTS (stmt, substmt);	                \
        if (!processing_template_decl)                  \
          {                                             \
	    cond = build_tree_list (substmt, cond);     \
	    substmt = cond;                             \
          }                                             \
      }							\
    else						\
      substmt = cond;					\
  } while (0)

/* Returns non-zero if the current statement is a full expression,
   i.e. temporaries created during that statement should be destroyed
   at the end of the statement.  */

int
stmts_are_full_exprs_p ()
{
  return current_stmt_tree ()->stmts_are_full_exprs_p;
}

/* Returns the stmt_tree (if any) to which statements are currently
   being added.  If there is no active statement-tree, NULL is
   returned.  */

stmt_tree
current_stmt_tree ()
{
  return (cfun 
	  ? &cfun->language->x_stmt_tree 
	  : &scope_chain->x_stmt_tree);
}

/* Nonzero if TYPE is an anonymous union or struct type.  We have to use a
   flag for this because "A union for which objects or pointers are
   declared is not an anonymous union" [class.union].  */

int
anon_aggr_type_p (node)
     tree node;
{
  return (CLASS_TYPE_P (node) && TYPE_LANG_SPECIFIC(node)->anon_aggr);
}

/* Finish a scope.  */

tree
do_poplevel ()
{
  tree block = NULL_TREE;

  if (stmts_are_full_exprs_p ())
    {
      tree scope_stmts = NULL_TREE;

      if (!processing_template_decl)
	scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);

      block = poplevel (kept_level_p (), 1, 0);
      if (block && !processing_template_decl)
	{
	  SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
	  SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
	}
    }

  return block;
}

/* Begin a new scope.  */ 

void
do_pushlevel ()
{
  if (stmts_are_full_exprs_p ())
    {
      pushlevel (0);
      if (!processing_template_decl)
	add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
    }
}

/* Finish a goto-statement.  */

tree
finish_goto_stmt (destination)
     tree destination;
{
  if (TREE_CODE (destination) == IDENTIFIER_NODE)
    destination = lookup_label (destination);

  /* We warn about unused labels with -Wunused.  That means we have to
     mark the used labels as used.  */
  if (TREE_CODE (destination) == LABEL_DECL)
    TREE_USED (destination) = 1;
    
  if (TREE_CODE (destination) != LABEL_DECL)
    /* We don't inline calls to functions with computed gotos.
       Those functions are typically up to some funny business,
       and may be depending on the labels being at particular
       addresses, or some such.  */
    DECL_UNINLINABLE (current_function_decl) = 1;
  
  check_goto (destination);

  return add_stmt (build_stmt (GOTO_STMT, destination));
}

/* COND is the condition-expression for an if, while, etc.,
   statement.  Convert it to a boolean value, if appropriate.  */

tree
maybe_convert_cond (cond)
     tree cond;
{
  /* Empty conditions remain empty.  */
  if (!cond)
    return NULL_TREE;

  /* Wait until we instantiate templates before doing conversion.  */
  if (processing_template_decl)
    return cond;

  /* Do the conversion.  */
  cond = convert_from_reference (cond);
  return condition_conversion (cond);
}

/* Finish an expression-statement, whose EXPRESSION is as indicated.  */

tree
finish_expr_stmt (expr)
     tree expr;
{
  tree r = NULL_TREE;

  if (expr != NULL_TREE)
    {
      if (!processing_template_decl
	  && !(stmts_are_full_exprs_p ())
	  && ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
	       && lvalue_p (expr))
	      || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE))
	expr = default_conversion (expr);
      
      if (stmts_are_full_exprs_p ())
	expr = convert_to_void (expr, "statement");
      
      r = add_stmt (build_stmt (EXPR_STMT, expr));
    }

  finish_stmt ();

  /* This was an expression-statement, so we save the type of the
     expression.  */
  last_expr_type = expr ? TREE_TYPE (expr) : NULL_TREE;

  return r;
}


/* Begin an if-statement.  Returns a newly created IF_STMT if
   appropriate.  */

tree
begin_if_stmt ()
{
  tree r;
  do_pushlevel ();
  r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
  add_stmt (r);
  return r;
}

/* Process the COND of an if-statement, which may be given by
   IF_STMT.  */

void 
finish_if_stmt_cond (cond, if_stmt)
     tree cond;
     tree if_stmt;
{
  cond = maybe_convert_cond (cond);
  FINISH_COND (cond, if_stmt, IF_COND (if_stmt));
}

/* Finish the then-clause of an if-statement, which may be given by
   IF_STMT.  */

tree
finish_then_clause (if_stmt)
     tree if_stmt;
{
  RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
  last_tree = if_stmt;
  return if_stmt;
}

/* Begin the else-clause of an if-statement.  */

void 
begin_else_clause ()
{
}

/* Finish the else-clause of an if-statement, which may be given by
   IF_STMT.  */

void
finish_else_clause (if_stmt)
     tree if_stmt;
{
  RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
}

/* Finsh an if-statement.  */

void 
finish_if_stmt ()
{
  do_poplevel ();
  finish_stmt ();
}

void
clear_out_block ()
{
  /* If COND wasn't a declaration, clear out the
     block we made for it and start a new one here so the
     optimization in expand_end_loop will work.  */
  if (getdecls () == NULL_TREE)
    {
      do_poplevel ();
      do_pushlevel ();
    }
}

/* Begin a while-statement.  Returns a newly created WHILE_STMT if
   appropriate.  */

tree
begin_while_stmt ()
{
  tree r;
  r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
  add_stmt (r);
  do_pushlevel ();
  return r;
}

/* Process the COND of a while-statement, which may be given by
   WHILE_STMT.  */

void 
finish_while_stmt_cond (cond, while_stmt)
     tree cond;
     tree while_stmt;
{
  cond = maybe_convert_cond (cond);
  FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt));
  clear_out_block ();
}

/* Finish a while-statement, which may be given by WHILE_STMT.  */

void 
finish_while_stmt (while_stmt)
     tree while_stmt;
{
  do_poplevel ();
  RECHAIN_STMTS (while_stmt, WHILE_BODY (while_stmt));
  finish_stmt ();
}

/* Begin a do-statement.  Returns a newly created DO_STMT if
   appropriate.  */

tree
begin_do_stmt ()
{
  tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE);
  add_stmt (r);
  return r;
}

/* Finish the body of a do-statement, which may be given by DO_STMT.  */

void
finish_do_body (do_stmt)
     tree do_stmt;
{
  RECHAIN_STMTS (do_stmt, DO_BODY (do_stmt));
}

/* Finish a do-statement, which may be given by DO_STMT, and whose
   COND is as indicated.  */

void
finish_do_stmt (cond, do_stmt)
     tree cond;
     tree do_stmt;
{
  cond = maybe_convert_cond (cond);
  DO_COND (do_stmt) = cond;
  finish_stmt ();
}

/* Finish a return-statement.  The EXPRESSION returned, if any, is as
   indicated.  */

tree
finish_return_stmt (expr)
     tree expr;
{
  tree r;

  if (!processing_template_decl)
    expr = check_return_expr (expr);
  if (!processing_template_decl)
    {
      if (DECL_CONSTRUCTOR_P (current_function_decl) && ctor_label)
	{
	  /* Even returns without a value in a constructor must return
	     `this'.  We accomplish this by sending all returns in a
	     constructor to the CTOR_LABEL; finish_function emits code to
	     return a value there.  When we finally generate the real
	     return statement, CTOR_LABEL is no longer set, and we fall
	     through into the normal return-processing code below.  */
	  return finish_goto_stmt (ctor_label);
	}
      else if (DECL_DESTRUCTOR_P (current_function_decl))
	{
	  /* Similarly, all destructors must run destructors for
	     base-classes before returning.  So, all returns in a
	     destructor get sent to the DTOR_LABEL; finsh_function emits
	     code to return a value there.  */
	  return finish_goto_stmt (dtor_label);
	}
    }
  r = add_stmt (build_stmt (RETURN_STMT, expr));
  finish_stmt ();

  return r;
}

/* Begin a for-statement.  Returns a new FOR_STMT if appropriate.  */

tree
begin_for_stmt ()
{
  tree r;

  r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE, 
		  NULL_TREE, NULL_TREE);
  NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0;
  add_stmt (r);
  if (NEW_FOR_SCOPE_P (r))
    {
      do_pushlevel ();
      note_level_for_for ();
    }

  return r;
}

/* Finish the for-init-statement of a for-statement, which may be
   given by FOR_STMT.  */

void
finish_for_init_stmt (for_stmt)
     tree for_stmt;
{
  if (last_tree != for_stmt)
    RECHAIN_STMTS (for_stmt, FOR_INIT_STMT (for_stmt));
  do_pushlevel ();
}

/* Finish the COND of a for-statement, which may be given by
   FOR_STMT.  */

void
finish_for_cond (cond, for_stmt)
     tree cond;
     tree for_stmt;
{
  cond = maybe_convert_cond (cond);
  FINISH_COND (cond, for_stmt, FOR_COND (for_stmt));
  clear_out_block ();
}

/* Finish the increment-EXPRESSION in a for-statement, which may be
   given by FOR_STMT.  */

void
finish_for_expr (expr, for_stmt)
     tree expr;
     tree for_stmt;
{
  FOR_EXPR (for_stmt) = expr;
}

/* Finish the body of a for-statement, which may be given by
   FOR_STMT.  The increment-EXPR for the loop must be
   provided.  */

void
finish_for_stmt (for_stmt)
     tree for_stmt;
{
  /* Pop the scope for the body of the loop.  */
  do_poplevel ();
  RECHAIN_STMTS (for_stmt, FOR_BODY (for_stmt));
  if (NEW_FOR_SCOPE_P (for_stmt))
    do_poplevel ();
  finish_stmt (); 
}

/* Finish a break-statement.  */

tree
finish_break_stmt ()
{
  return add_stmt (build_break_stmt ());
}

/* Finish a continue-statement.  */

tree
finish_continue_stmt ()
{
  return add_stmt (build_continue_stmt ());
}

/* Begin a switch-statement.  Returns a new SWITCH_STMT if
   appropriate.  */

tree
begin_switch_stmt ()
{
  tree r;
  r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE);
  add_stmt (r);
  do_pushlevel ();
  return r;
}

/* Finish the cond of a switch-statement.  */

void
finish_switch_cond (cond, switch_stmt)
     tree cond;
     tree switch_stmt;
{
  if (!processing_template_decl)
    {
      tree type;
      tree index;

      /* Convert the condition to an integer or enumeration type.  */
      cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, 1);
      if (cond == NULL_TREE)
	{
	  error ("switch quantity not an integer");
	  cond = error_mark_node;
	}
      if (cond != error_mark_node)
	{
	  cond = default_conversion (cond);
	  cond = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (cond), cond));
	}

      type = TREE_TYPE (cond);
      index = get_unwidened (cond, NULL_TREE);
      /* We can't strip a conversion from a signed type to an unsigned,
	 because if we did, int_fits_type_p would do the wrong thing
	 when checking case values for being in range,
	 and it's too hard to do the right thing.  */
      if (TREE_UNSIGNED (TREE_TYPE (cond))
	  == TREE_UNSIGNED (TREE_TYPE (index)))
	cond = index;
    }
  FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt));
  push_switch (switch_stmt);
}

/* Finish the body of a switch-statement, which may be given by
   SWITCH_STMT.  The COND to switch on is indicated.  */

void
finish_switch_stmt (switch_stmt)
     tree switch_stmt;
{
  RECHAIN_STMTS (switch_stmt, SWITCH_BODY (switch_stmt));
  pop_switch (); 
  do_poplevel ();
  finish_stmt ();
}

/* Generate the RTL for T, which is a TRY_BLOCK. */

static void 
genrtl_try_block (t)
     tree t;
{
  if (CLEANUP_P (t))
    {
      expand_eh_region_start ();
      expand_stmt (TRY_STMTS (t));
      expand_eh_region_end_cleanup (TRY_HANDLERS (t));
    }
  else
    {
      if (!FN_TRY_BLOCK_P (t)) 
	emit_line_note (input_filename, lineno);

      expand_eh_region_start ();
      expand_stmt (TRY_STMTS (t));

      if (FN_TRY_BLOCK_P (t))
	{
	  end_protect_partials ();
	  expand_start_all_catch ();
	  in_function_try_handler = 1;
	  expand_stmt (TRY_HANDLERS (t));
	  in_function_try_handler = 0;
	  expand_end_all_catch ();
	}
      else 
	{
	  expand_start_all_catch ();  
	  expand_stmt (TRY_HANDLERS (t));
	  expand_end_all_catch ();
	}
    }
}

/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */

static void 
genrtl_eh_spec_block (t)
     tree t;
{
  expand_eh_region_start ();
  expand_stmt (EH_SPEC_STMTS (t));
  expand_eh_region_end_allowed (EH_SPEC_RAISES (t),
				build_call (call_unexpected_node,
					    tree_cons (NULL_TREE,
						       build_exc_ptr (),
						       NULL_TREE)));
}

/* Begin a try-block.  Returns a newly-created TRY_BLOCK if
   appropriate.  */

tree
begin_try_block ()
{
  tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
  add_stmt (r);
  return r;
}

/* Likewise, for a function-try-block.  */

tree
begin_function_try_block ()
{
  tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
  FN_TRY_BLOCK_P (r) = 1;
  add_stmt (r);
  return r;
}

/* Finish a try-block, which may be given by TRY_BLOCK.  */

void
finish_try_block (try_block)
     tree try_block;
{
  RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
}

/* Finish the body of a cleanup try-block, which may be given by
   TRY_BLOCK.  */

void
finish_cleanup_try_block (try_block)
     tree try_block;
{
  RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
}

/* Finish an implicitly generated try-block, with a cleanup is given
   by CLEANUP.  */

void
finish_cleanup (cleanup, try_block)
     tree cleanup;
     tree try_block;
{
  TRY_HANDLERS (try_block) = cleanup;
  CLEANUP_P (try_block) = 1;
}

/* Likewise, for a function-try-block.  */

void
finish_function_try_block (try_block)
     tree try_block; 
{
  if (TREE_CHAIN (try_block) 
      && TREE_CODE (TREE_CHAIN (try_block)) == CTOR_INITIALIZER)
    {
      /* Chain the compound statement after the CTOR_INITIALIZER.  */
      TREE_CHAIN (TREE_CHAIN (try_block)) = last_tree;
      /* And make the CTOR_INITIALIZER the body of the try-block.  */
      RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
    }
  else
    RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
  in_function_try_handler = 1;
}

/* Finish a handler-sequence for a try-block, which may be given by
   TRY_BLOCK.  */

void
finish_handler_sequence (try_block)
     tree try_block;
{
  RECHAIN_STMTS (try_block, TRY_HANDLERS (try_block));
  check_handlers (TRY_HANDLERS (try_block));
}

/* Likewise, for a function-try-block.  */

void
finish_function_handler_sequence (try_block)
     tree try_block;
{
  in_function_try_handler = 0;
  RECHAIN_STMTS (try_block, TRY_HANDLERS (try_block));
  check_handlers (TRY_HANDLERS (try_block));
}

/* Generate the RTL for T, which is a HANDLER. */

static void
genrtl_handler (t)
     tree t;
{
  genrtl_do_pushlevel ();
  expand_stmt (HANDLER_BODY (t));
  if (!processing_template_decl)
    expand_end_catch ();
}

/* Begin a handler.  Returns a HANDLER if appropriate.  */

tree
begin_handler ()
{
  tree r;
  r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
  add_stmt (r);
  do_pushlevel ();
  return r;
}

/* Finish the handler-parameters for a handler, which may be given by
   HANDLER.  DECL is the declaration for the catch parameter, or NULL
   if this is a `catch (...)' clause.  */

tree
finish_handler_parms (decl, handler)
     tree decl;
     tree handler;
{
  tree blocks = NULL_TREE;

  if (processing_template_decl)
    {
      if (decl)
	{
	  decl = pushdecl (decl);
	  decl = push_template_decl (decl);
	  add_decl_stmt (decl);
	  RECHAIN_STMTS (handler, HANDLER_PARMS (handler));
	}
    }
  else
    blocks = expand_start_catch_block (decl);

  if (decl)
    TREE_TYPE (handler) = TREE_TYPE (decl);

  return blocks;
}

/* Generate the RTL for a START_CATCH_STMT. */

static void
genrtl_catch_block (type)
     tree type;
{
  expand_start_catch (type);
}

/* Note the beginning of a handler for TYPE.  This function is called
   at the point to which control should be transferred when an
   appropriately-typed exception is thrown.  */

void
begin_catch_block (type)
     tree type;
{
  add_stmt (build (START_CATCH_STMT, type));
}

/* Finish a handler, which may be given by HANDLER.  The BLOCKs are
   the return value from the matching call to finish_handler_parms.  */

void
finish_handler (blocks, handler)
     tree blocks;
     tree handler;
{
  if (!processing_template_decl)
      expand_end_catch_block (blocks);
  do_poplevel ();
  RECHAIN_STMTS (handler, HANDLER_BODY (handler));
}

/* Generate the RTL for T, which is a CTOR_STMT. */

static void
genrtl_ctor_stmt (t)
     tree t;
{
  if (CTOR_BEGIN_P (t))
    begin_protect_partials ();
  else
    /* After this point, any exceptions will cause the
       destructor to be executed, so we no longer need to worry
       about destroying the various subobjects ourselves.  */
    end_protect_partials ();
}

/* Begin a compound-statement.  If HAS_NO_SCOPE is non-zero, the
   compound-statement does not define a scope.  Returns a new
   COMPOUND_STMT if appropriate.  */

tree
begin_compound_stmt (has_no_scope)
     int has_no_scope;
{
  tree r; 
  int is_try = 0;

  r = build_stmt (COMPOUND_STMT, NULL_TREE);

  if (last_tree && TREE_CODE (last_tree) == TRY_BLOCK)
    is_try = 1;

  add_stmt (r);
  if (has_no_scope)
    COMPOUND_STMT_NO_SCOPE (r) = 1;

  last_expr_type = NULL_TREE;

  if (!has_no_scope)
    {
      do_pushlevel ();
      if (is_try)
      	note_level_for_try ();
    }
  else
    /* Normally, we try hard to keep the BLOCK for a
       statement-expression.  But, if it's a statement-expression with
       a scopeless block, there's nothing to keep, and we don't want
       to accidentally keep a block *inside* the scopeless block.  */ 
    keep_next_level (0);

  /* If this is the outermost block of the function, declare the
     variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth.  */
  if (cfun
      && !function_name_declared_p
      && !has_no_scope)
    {
      function_name_declared_p = 1;
      declare_function_name ();
    }

  return r;
}

/* Finish a compound-statement, which may be given by COMPOUND_STMT.
   If HAS_NO_SCOPE is non-zero, the compound statement does not define
   a scope.  */

tree
finish_compound_stmt (has_no_scope, compound_stmt)
     int has_no_scope;
     tree compound_stmt;
{
  tree r;
  tree t;

  if (!has_no_scope)
    r = do_poplevel ();
  else
    r = NULL_TREE;

  RECHAIN_STMTS (compound_stmt, COMPOUND_BODY (compound_stmt));

  /* When we call finish_stmt we will lose LAST_EXPR_TYPE.  But, since
     the precise purpose of that variable is store the type of the
     last expression statement within the last compound statement, we
     preserve the value.  */
  t = last_expr_type;
  finish_stmt ();
  last_expr_type = t;

  return r;
}

/* Finish an asm-statement, whose components are a CV_QUALIFIER, a
   STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, and some
   CLOBBERS.  */

tree
finish_asm_stmt (cv_qualifier, string, output_operands,
		 input_operands, clobbers)
     tree cv_qualifier;
     tree string;
     tree output_operands;
     tree input_operands;
     tree clobbers;
{
  tree r;
  tree t;

  if (TREE_CHAIN (string))
    string = combine_strings (string);

  if (cv_qualifier != NULL_TREE
      && cv_qualifier != ridpointers[(int) RID_VOLATILE])
    {
      cp_warning ("%s qualifier ignored on asm",
		  IDENTIFIER_POINTER (cv_qualifier));
      cv_qualifier = NULL_TREE;
    }

  if (!processing_template_decl)
    for (t = input_operands; t; t = TREE_CHAIN (t))
      {
	tree converted_operand 
	  = decay_conversion (TREE_VALUE (t)); 

	/* If the type of the operand hasn't been determined (e.g.,
	   because it involves an overloaded function), then issue an
	   error message.  There's no context available to resolve the
	   overloading.  */
	if (TREE_TYPE (converted_operand) == unknown_type_node)
	  {
	    cp_error ("type of asm operand `%E' could not be determined", 
		      TREE_VALUE (t));
	    converted_operand = error_mark_node;
	  }
	TREE_VALUE (t) = converted_operand;
      }

  r = build_stmt (ASM_STMT, cv_qualifier, string,
		  output_operands, input_operands,
		  clobbers);
  return add_stmt (r);
}

/* Finish a label with the indicated NAME.  */

void
finish_label_stmt (name)
     tree name;
{
  tree decl = define_label (input_filename, lineno, name);
  add_stmt (build_stmt (LABEL_STMT, decl));
}

/* Finish a series of declarations for local labels.  G++ allows users
   to declare "local" labels, i.e., labels with scope.  This extension
   is useful when writing code involving statement-expressions.  */

void
finish_label_decl (name)
     tree name;
{
  tree decl = declare_local_label (name);
  add_decl_stmt (decl);
}

/* Generate the RTL for a SUBOBJECT. */

static void 
genrtl_subobject (cleanup)
     tree cleanup;
{
  add_partial_entry (cleanup);
}

/* We're in a constructor, and have just constructed a a subobject of
   *THIS.  CLEANUP is code to run if an exception is thrown before the
   end of the current function is reached.   */

void 
finish_subobject (cleanup)
     tree cleanup;
{
  tree r = build_stmt (SUBOBJECT, cleanup);
  add_stmt (r);
}

/* When DECL goes out of scope, make sure that CLEANUP is executed.  */

void 
finish_decl_cleanup (decl, cleanup)
     tree decl;
     tree cleanup;
{
  add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
}

/* Generate the RTL for a RETURN_INIT. */

static void
genrtl_named_return_value ()
{
  tree decl = DECL_RESULT (current_function_decl);

  /* If this named return value comes in a register, put it in a
     pseudo-register.  */
  if (DECL_REGISTER (decl))
    {
      /* Note that the mode of the old DECL_RTL may be wider than the
	 mode of DECL_RESULT, depending on the calling conventions for
	 the processor.  For example, on the Alpha, a 32-bit integer
	 is returned in a DImode register -- the DECL_RESULT has
	 SImode but the DECL_RTL for the DECL_RESULT has DImode.  So,
	 here, we use the mode the back-end has already assigned for
	 the return value.  */
      SET_DECL_RTL (decl, gen_reg_rtx (GET_MODE (DECL_RTL (decl))));
      if (TREE_ADDRESSABLE (decl))
	put_var_into_stack (decl);
    }

  emit_local_var (decl);
}

/* Bind a name and initialization to the return value of
   the current function.  */

void
finish_named_return_value (return_id, init)
     tree return_id, init;
{
  tree decl = DECL_RESULT (current_function_decl);

  /* Give this error as many times as there are occurrences, so that
     users can use Emacs compilation buffers to find and fix all such
     places.  */
  if (pedantic)
    pedwarn ("ISO C++ does not permit named return values");
  cp_deprecated ("the named return value extension");

  if (return_id != NULL_TREE)
    {
      if (DECL_NAME (decl) == NULL_TREE)
	DECL_NAME (decl) = return_id;
      else
	{
	  cp_error ("return identifier `%D' already in place", return_id);
	  return;
	}
    }

  /* Can't let this happen for constructors.  */
  if (DECL_CONSTRUCTOR_P (current_function_decl))
    {
      error ("can't redefine default return value for constructors");
      return;
    }

  /* If we have a named return value, put that in our scope as well.  */
  if (DECL_NAME (decl) != NULL_TREE)
    {
      /* Let `cp_finish_decl' know that this initializer is ok.  */
      DECL_INITIAL (decl) = init;
      if (doing_semantic_analysis_p ())
	pushdecl (decl);
      if (!processing_template_decl) 
	{
	  cp_finish_decl (decl, init, NULL_TREE, 0);
	  add_stmt (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE));
	}
      else
	add_stmt (build_stmt (RETURN_INIT, return_id, init));
    }

  /* Don't use tree-inlining for functions with named return values.
     That doesn't work properly because we don't do any translation of
     the RETURN_INITs when they are copied.  */
  DECL_UNINLINABLE (current_function_decl) = 1;
}

/* The INIT_LIST is a list of mem-initializers, in the order they were
   written by the user.  The TREE_VALUE of each node is a list of
   initializers for a particular subobject.  The TREE_PURPOSE is a
   FIELD_DECL is the initializer is for a non-static data member, and
   a class type if the initializer is for a base class.  */

void
finish_mem_initializers (init_list)
     tree init_list;
{
  tree member_init_list;
  tree base_init_list;
  tree last_base_warned_about;
  tree next; 
  tree init;

  member_init_list = NULL_TREE;
  base_init_list = NULL_TREE;
  last_base_warned_about = NULL_TREE;

  for (init = init_list; init; init = next)
    {
      next = TREE_CHAIN (init);
      if (TREE_CODE (TREE_PURPOSE (init)) == FIELD_DECL)
	{
	  TREE_CHAIN (init) = member_init_list;
	  member_init_list = init;

	  /* We're running through the initializers from right to left
	     as we process them here.  So, if we see a data member
	     initializer after we see a base initializer, that
	     actually means that the base initializer preceeded the
	     data member initializer.  */
	  if (warn_reorder && last_base_warned_about != base_init_list)
	    {
	      tree base;

	      for (base = base_init_list; 
		   base != last_base_warned_about; 
		   base = TREE_CHAIN (base))
		{
		  cp_warning ("base initializer for `%T'",
			      TREE_PURPOSE (base));
		  warning ("   will be re-ordered to precede member initializations");
		}

	      last_base_warned_about = base_init_list;
	    }
	}
      else
	{
	  TREE_CHAIN (init) = base_init_list;
	  base_init_list = init;
	}
    }

  setup_vtbl_ptr (member_init_list, base_init_list);
}

/* Cache the value of this class's main virtual function table pointer
   in a register variable.  This will save one indirection if a
   more than one virtual function call is made this function.  */

void
setup_vtbl_ptr (member_init_list, base_init_list)
     tree member_init_list;
     tree base_init_list;
{
  my_friendly_assert (doing_semantic_analysis_p (), 19990919);

  /* If we've already done this, there's no need to do it again.  */
  if (vtbls_set_up_p)
    return;

  if (DECL_CONSTRUCTOR_P (current_function_decl))
    {
      if (processing_template_decl)
	add_stmt (build_min_nt
		  (CTOR_INITIALIZER,
		   member_init_list, base_init_list));
      else
	{
	  tree ctor_stmt;

	  /* Mark the beginning of the constructor.  */
	  ctor_stmt = build_stmt (CTOR_STMT);
	  CTOR_BEGIN_P (ctor_stmt) = 1;
	  add_stmt (ctor_stmt);
	  
	  /* And actually initialize the base-classes and members.  */
	  emit_base_init (member_init_list, base_init_list);
	}
    }
  else if (DECL_DESTRUCTOR_P (current_function_decl)
	   && !processing_template_decl)
    {
      tree if_stmt;
      tree compound_stmt;
      int saved_cfnd;

      /* If the dtor is empty, and we know there is not any possible
	 way we could use any vtable entries, before they are possibly
	 set by a base class dtor, we don't have to setup the vtables,
	 as we know that any base class dtor will set up any vtables
	 it needs.  We avoid MI, because one base class dtor can do a
	 virtual dispatch to an overridden function that would need to
	 have a non-related vtable set up, we cannot avoid setting up
	 vtables in that case.  We could change this to see if there
	 is just one vtable.  */
      if_stmt = begin_if_stmt ();

      /* If it is not safe to avoid setting up the vtables, then
	 someone will change the condition to be boolean_true_node.  
         (Actually, for now, we do not have code to set the condition
	 appropriately, so we just assume that we always need to
	 initialize the vtables.)  */
      finish_if_stmt_cond (boolean_true_node, if_stmt);
      current_vcalls_possible_p = &IF_COND (if_stmt);

      /* Don't declare __PRETTY_FUNCTION__ and friends here when we
	 open the block for the if-body.  */
      saved_cfnd = function_name_declared_p;
      function_name_declared_p = 1;
      compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
      function_name_declared_p = saved_cfnd;

      /* Make all virtual function table pointers in non-virtual base
	 classes point to CURRENT_CLASS_TYPE's virtual function
	 tables.  */
      initialize_vtbl_ptrs (current_class_ptr);

      finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
      finish_then_clause (if_stmt);
      finish_if_stmt ();
    }

  /* Always keep the BLOCK node associated with the outermost pair of
     curly braces of a function.  These are needed for correct
     operation of dwarfout.c.  */
  keep_next_level (1);

  /* The virtual function tables are set up now.  */
  vtbls_set_up_p = 1;
}

/* Returns the stack of SCOPE_STMTs for the current function.  */

tree *
current_scope_stmt_stack ()
{
  return &cfun->language->x_scope_stmt_stack;
}

/* Finish a parenthesized expression EXPR.  */

tree
finish_parenthesized_expr (expr)
     tree expr;
{
  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr))))
    /* This inhibits warnings in truthvalue_conversion.  */
    C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK); 

  if (TREE_CODE (expr) == OFFSET_REF)
    /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
       enclosed in parentheses.  */
    PTRMEM_OK_P (expr) = 0;
  return expr;
}

/* Begin a statement-expression.  The value returned must be passed to
   finish_stmt_expr.  */

tree 
begin_stmt_expr ()
{
  /* If we're outside a function, we won't have a statement-tree to
     work with.  But, if we see a statement-expression we need to
     create one.  */
  if (! cfun && !last_tree)
    begin_stmt_tree (&scope_chain->x_saved_tree);

  keep_next_level (1);
  /* If we're building a statement tree, then the upcoming compound
     statement will be chained onto the tree structure, starting at
     last_tree.  We return last_tree so that we can later unhook the
     compound statement.  */
  return last_tree; 
}

/* Used when beginning a statement-expression outside function scope.
   For example, when handling a file-scope initializer, we use this
   function.  */

tree
begin_global_stmt_expr ()
{
  if (! cfun && !last_tree)
    begin_stmt_tree (&scope_chain->x_saved_tree);

  keep_next_level (1);
  
  return (last_tree != NULL_TREE) ? last_tree : expand_start_stmt_expr(); 
}

/* Finish the STMT_EXPR last begun with begin_global_stmt_expr.  */

tree 
finish_global_stmt_expr (stmt_expr)
     tree stmt_expr;
{
  stmt_expr = expand_end_stmt_expr (stmt_expr);
  
  if (! cfun
      && TREE_CHAIN (scope_chain->x_saved_tree) == NULL_TREE)
    finish_stmt_tree (&scope_chain->x_saved_tree);

  return stmt_expr;
}

/* Finish a statement-expression.  RTL_EXPR should be the value
   returned by the previous begin_stmt_expr; EXPR is the
   statement-expression.  Returns an expression representing the
   statement-expression.  */

tree 
finish_stmt_expr (rtl_expr)
     tree rtl_expr;
{
  tree result;

  /* If the last thing in the statement-expression was not an
     expression-statement, then it has type `void'.  */
  if (!last_expr_type)
    last_expr_type = void_type_node;
  result = build_min (STMT_EXPR, last_expr_type, last_tree);
  TREE_SIDE_EFFECTS (result) = 1;
  
  /* Remove the compound statement from the tree structure; it is
     now saved in the STMT_EXPR.  */
  last_tree = rtl_expr;
  TREE_CHAIN (last_tree) = NULL_TREE;

  /* If we created a statement-tree for this statement-expression,
     remove it now.  */ 
  if (! cfun
      && TREE_CHAIN (scope_chain->x_saved_tree) == NULL_TREE)
    finish_stmt_tree (&scope_chain->x_saved_tree);

  return result;
}

/* Finish a call to FN with ARGS.  Returns a representation of the
   call.  */

tree 
finish_call_expr (fn, args, koenig)
     tree fn;
     tree args;
     int koenig;
{
  tree result;

  if (koenig)
    {
      if (TREE_CODE (fn) == BIT_NOT_EXPR)
	fn = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND (fn, 0));
      else if (TREE_CODE (fn) != TEMPLATE_ID_EXPR)
	fn = do_identifier (fn, 2, args);
    }
  result = build_x_function_call (fn, args, current_class_ref);

  if (TREE_CODE (result) == CALL_EXPR
      && (! TREE_TYPE (result)
          || TREE_CODE (TREE_TYPE (result)) != VOID_TYPE))
    result = require_complete_type (result);

  return result;
}

/* Finish a call to a postfix increment or decrement or EXPR.  (Which
   is indicated by CODE, which should be POSTINCREMENT_EXPR or
   POSTDECREMENT_EXPR.)  */

tree 
finish_increment_expr (expr, code)
     tree expr;
     enum tree_code code;
{
  /* If we get an OFFSET_REF, turn it into what it really means (e.g.,
     a COMPONENT_REF).  This way if we've got, say, a reference to a
     static member that's being operated on, we don't end up trying to
     find a member operator for the class it's in.  */

  if (TREE_CODE (expr) == OFFSET_REF)
    expr = resolve_offset_ref (expr);
  return build_x_unary_op (code, expr);  
}

/* Finish a use of `this'.  Returns an expression for `this'.  */

tree 
finish_this_expr ()
{
  tree result;

  if (current_class_ptr)
    {
#ifdef WARNING_ABOUT_CCD
      TREE_USED (current_class_ptr) = 1;
#endif
      result = current_class_ptr;
    }
  else if (current_function_decl
	   && DECL_STATIC_FUNCTION_P (current_function_decl))
    {
      error ("`this' is unavailable for static member functions");
      result = error_mark_node;
    }
  else
    {
      if (current_function_decl)
	error ("invalid use of `this' in non-member function");
      else
	error ("invalid use of `this' at top level");
      result = error_mark_node;
    }

  return result;
}

/* Finish a member function call using OBJECT and ARGS as arguments to
   FN.  Returns an expression for the call.  */

tree 
finish_object_call_expr (fn, object, args)
     tree fn;
     tree object;
     tree args;
{
#if 0
  /* This is a future direction of this code, but because
     build_x_function_call cannot always undo what is done in
     build_component_ref entirely yet, we cannot do this.  */

  tree real_fn = build_component_ref (object, fn, NULL_TREE, 1);
  return finish_call_expr (real_fn, args);
#else
  if (DECL_DECLARES_TYPE_P (fn))
    {
      if (processing_template_decl)
	/* This can happen on code like:

	   class X;
	   template <class T> void f(T t) {
	     t.X();
	   }  

	   We just grab the underlying IDENTIFIER.  */
	fn = DECL_NAME (fn);
      else
	{
	  cp_error ("calling type `%T' like a method", fn);
	  return error_mark_node;
	}
    }

  return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
#endif
}

/* Finish a qualified member function call using OBJECT and ARGS as
   arguments to FN.  Returns an expression for the call.  */

tree 
finish_qualified_object_call_expr (fn, object, args)
     tree fn;
     tree object;
     tree args;
{
  return build_scoped_method_call (object, TREE_OPERAND (fn, 0),
				   TREE_OPERAND (fn, 1), args);
}

/* Finish a pseudo-destructor call expression of OBJECT, with SCOPE
   being the scope, if any, of DESTRUCTOR.  Returns an expression for
   the call.  */

tree 
finish_pseudo_destructor_call_expr (object, scope, destructor)
     tree object;
     tree scope;
     tree destructor;
{
  if (processing_template_decl)
    return build_min_nt (PSEUDO_DTOR_EXPR, object, scope, destructor);

  if (scope && scope != destructor)
    cp_error ("destructor specifier `%T::~%T()' must have matching names", 
	      scope, destructor);

  if ((scope == NULL_TREE || IDENTIFIER_GLOBAL_VALUE (destructor))
      && (TREE_CODE (TREE_TYPE (object)) !=
	  TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (destructor)))))
    cp_error ("`%E' is not of type `%T'", object, destructor);

  return cp_convert (void_type_node, object);
}

/* Finish a call to a globally qualified member function FN using
   ARGS.  Returns an expression for the call.  */

tree 
finish_qualified_call_expr (fn, args)
     tree fn;
     tree args;
{
  if (processing_template_decl)
    return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
  else
    return build_member_call (TREE_OPERAND (fn, 0),
			      TREE_OPERAND (fn, 1),
			      args);
}

/* Finish an expression taking the address of LABEL.  Returns an
   expression for the address.  */

tree 
finish_label_address_expr (label)
     tree label;
{
  tree result;

  label = lookup_label (label);
  if (label == NULL_TREE)
    result = null_pointer_node;
  else
    {
      TREE_USED (label) = 1;
      result = build1 (ADDR_EXPR, ptr_type_node, label);
      TREE_CONSTANT (result) = 1;
      /* This function cannot be inlined.  All jumps to the addressed
	 label should wind up at the same point.  */
      DECL_UNINLINABLE (current_function_decl) = 1;
    }

  return result;
}

/* Finish an expression of the form CODE EXPR.  */

tree
finish_unary_op_expr (code, expr)
     enum tree_code code;
     tree expr;
{
  tree result = build_x_unary_op (code, expr);
  /* Inside a template, build_x_unary_op does not fold the
     expression. So check whether the result is folded before
     setting TREE_NEGATED_INT.  */
  if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST
      && TREE_CODE (result) == INTEGER_CST
      && !TREE_UNSIGNED (TREE_TYPE (result))
      && INT_CST_LT (result, integer_zero_node))
    TREE_NEGATED_INT (result) = 1;
  overflow_warning (result);
  return result;
}

/* Finish an id-expression.  */

tree
finish_id_expr (expr)
     tree expr;
{
  if (TREE_CODE (expr) == IDENTIFIER_NODE)
    expr = do_identifier (expr, 1, NULL_TREE);

  if (TREE_TYPE (expr) == error_mark_node)
    expr = error_mark_node;
  return expr;
}

static tree current_type_lookups;

/* Perform deferred access control for types used in the type of a
   declaration.  */

static void
deferred_type_access_control ()
{
  tree lookup = type_lookups;

  if (lookup == error_mark_node)
    return;

  for (; lookup; lookup = TREE_CHAIN (lookup))
    enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup));
}

void
decl_type_access_control (decl)
     tree decl;
{
  tree save_fn;

  if (type_lookups == error_mark_node)
    return;

  save_fn = current_function_decl;

  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
    current_function_decl = decl;

  deferred_type_access_control ();

  current_function_decl = save_fn;
  
  /* Now strip away the checks for the current declarator; they were
     added to type_lookups after typed_declspecs saved the copy that
     ended up in current_type_lookups.  */
  type_lookups = current_type_lookups;
  
  current_type_lookups = NULL_TREE;
}

/* Record the lookups, if we're doing deferred access control.  */

void
save_type_access_control (lookups)
     tree lookups;
{
  if (type_lookups != error_mark_node)
    {
      my_friendly_assert (!current_type_lookups, 20010301);
      current_type_lookups = lookups;
    }
  else
    my_friendly_assert (!lookups || lookups == error_mark_node, 20010301);
}

/* Set things up so that the next deferred access control will succeed.
   This is needed for friend declarations see grokdeclarator for details.  */

void
skip_type_access_control ()
{
  type_lookups = NULL_TREE;
}

/* Reset the deferred access control.  */

void
reset_type_access_control ()
{
  type_lookups = NULL_TREE;
  current_type_lookups = NULL_TREE;
}

/* Begin a function definition declared with DECL_SPECS and
   DECLARATOR.  Returns non-zero if the function-declaration is
   legal.  */

int
begin_function_definition (decl_specs, declarator)
     tree decl_specs;
     tree declarator;
{
  tree specs;
  tree attrs;

  split_specs_attrs (decl_specs, &specs, &attrs);
  if (!start_function (specs, declarator, attrs, SF_DEFAULT))
    return 0;

  deferred_type_access_control ();
  type_lookups = error_mark_node;

  /* The things we're about to see are not directly qualified by any
     template headers we've seen thus far.  */
  reset_specialization ();

  return 1;
}

/* Begin a constructor declarator of the form `SCOPE::NAME'.  Returns
   a SCOPE_REF.  */

tree 
begin_constructor_declarator (scope, name)
     tree scope;
     tree name;
{
  tree result = build_nt (SCOPE_REF, scope, name);
  enter_scope_of (result);
  return result;
}

/* Finish an init-declarator.  Returns a DECL.  */

tree
finish_declarator (declarator, declspecs, attributes,
		   prefix_attributes, initialized)
     tree declarator;
     tree declspecs;
     tree attributes;
     tree prefix_attributes;
     int initialized;
{
  return start_decl (declarator, declspecs, initialized, attributes,
		     prefix_attributes); 
}

/* Finish a translation unit.  */

void 
finish_translation_unit ()
{
  /* In case there were missing closebraces,
     get us back to the global binding level.  */
  pop_everything ();
  while (current_namespace != global_namespace)
    pop_namespace ();
  finish_file ();
}

/* Finish a template type parameter, specified as AGGR IDENTIFIER.
   Returns the parameter.  */

tree 
finish_template_type_parm (aggr, identifier)
     tree aggr;
     tree identifier;
{
  if (aggr != class_type_node)
    {
      pedwarn ("template type parameters must use the keyword `class' or `typename'");
      aggr = class_type_node;
    }

  return build_tree_list (aggr, identifier);
}

/* Finish a template template parameter, specified as AGGR IDENTIFIER.
   Returns the parameter.  */

tree 
finish_template_template_parm (aggr, identifier)
     tree aggr;
     tree identifier;
{
  tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE);
  tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
  DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
  DECL_TEMPLATE_RESULT (tmpl) = decl;
  DECL_ARTIFICIAL (decl) = 1;
  end_template_decl ();

  my_friendly_assert (DECL_TEMPLATE_PARMS (tmpl), 20010110);

  return finish_template_type_parm (aggr, tmpl);
}

/* Finish a parameter list, indicated by PARMS.  If ELLIPSIS is
   non-zero, the parameter list was terminated by a `...'.  */

tree
finish_parmlist (parms, ellipsis)
     tree parms;
     int ellipsis;
{
  if (parms)
    {
      /* We mark the PARMS as a parmlist so that declarator processing can
         disambiguate certain constructs.  */
      TREE_PARMLIST (parms) = 1;
      /* We do not append void_list_node here, but leave it to grokparms
         to do that.  */
      PARMLIST_ELLIPSIS_P (parms) = ellipsis;
    }
  return parms;
}

/* Begin a class definition, as indicated by T.  */

tree
begin_class_definition (t)
     tree t;
{
  /* Check the bases are accessible. */
  decl_type_access_control (TYPE_NAME (t));
  reset_type_access_control ();
  
  if (processing_template_parmlist)
    {
      cp_error ("definition of `%#T' inside template parameter list", t);
      return error_mark_node;
    }
  if (t == error_mark_node
      || ! IS_AGGR_TYPE (t))
    {
      t = make_aggr_type (RECORD_TYPE);
      pushtag (make_anon_name (), t, 0);
    }

  /* In a definition of a member class template, we will get here with an
     implicit typename, a TYPENAME_TYPE with a type.  */
  if (TREE_CODE (t) == TYPENAME_TYPE)
    t = TREE_TYPE (t);
  
  /* If we generated a partial instantiation of this type, but now
     we're seeing a real definition, we're actually looking at a
     partial specialization.  Consider:

       template <class T, class U>
       struct Y {};

       template <class T>
       struct X {};

       template <class T, class U>
       void f()
       {
	 typename X<Y<T, U> >::A a;
       }

       template <class T, class U>
       struct X<Y<T, U> >
       {
       };

     We have to undo the effects of the previous partial
     instantiation.  */
  if (PARTIAL_INSTANTIATION_P (t))
    {
      if (!pedantic) 
	{
	  /* Unfortunately, when we're not in pedantic mode, we
	     attempt to actually fill in some of the fields of the
	     partial instantiation, in order to support the implicit
	     typename extension.  Clear those fields now, in
	     preparation for the definition here.  The fields cleared
	     here must match those set in instantiate_class_template.
	     Look for a comment mentioning begin_class_definition
	     there.  */
	  TYPE_BINFO_BASETYPES (t) = NULL_TREE;
	  TYPE_FIELDS (t) = NULL_TREE;
	  TYPE_METHODS (t) = NULL_TREE;
	  CLASSTYPE_TAGS (t) = NULL_TREE;
	  CLASSTYPE_VBASECLASSES (t) = NULL_TREE;
	  TYPE_SIZE (t) = NULL_TREE;
	}

      /* This isn't a partial instantiation any more.  */
      PARTIAL_INSTANTIATION_P (t) = 0;
    }
  /* If this type was already complete, and we see another definition,
     that's an error.  */
  else if (COMPLETE_TYPE_P (t))
    duplicate_tag_error (t);

  /* Update the location of the decl.  */
  DECL_SOURCE_FILE (TYPE_NAME (t)) = input_filename;
  DECL_SOURCE_LINE (TYPE_NAME (t)) = lineno;
  
  if (TYPE_BEING_DEFINED (t))
    {
      t = make_aggr_type (TREE_CODE (t));
      pushtag (TYPE_IDENTIFIER (t), t, 0);
    }
  maybe_process_partial_specialization (t);
  pushclass (t, 1);
  TYPE_BEING_DEFINED (t) = 1;
  TYPE_PACKED (t) = flag_pack_struct;
  /* Reset the interface data, at the earliest possible
     moment, as it might have been set via a class foo;
     before.  */
  {
    tree name = TYPE_IDENTIFIER (t);
    
    if (! ANON_AGGRNAME_P (name))
      {
	CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
	SET_CLASSTYPE_INTERFACE_UNKNOWN_X
	  (t, interface_unknown);
      }
  }
  reset_specialization();
  
  /* Make a declaration for this class in its own scope.  */
  build_self_reference ();

  return t;
}

/* Finish the member declaration given by DECL.  */

void
finish_member_declaration (decl)
     tree decl;
{
  if (decl == error_mark_node || decl == NULL_TREE)
    return;

  if (decl == void_type_node)
    /* The COMPONENT was a friend, not a member, and so there's
       nothing for us to do.  */
    return;

  /* We should see only one DECL at a time.  */
  my_friendly_assert (TREE_CHAIN (decl) == NULL_TREE, 0);

  /* Set up access control for DECL.  */
  TREE_PRIVATE (decl) 
    = (current_access_specifier == access_private_node);
  TREE_PROTECTED (decl) 
    = (current_access_specifier == access_protected_node);
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
      TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
    }

  /* Mark the DECL as a member of the current class.  */
  DECL_CONTEXT (decl) = current_class_type;

  /* [dcl.link]

     A C language linkage is ignored for the names of class members
     and the member function type of class member functions.  */
  if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
    DECL_LANGUAGE (decl) = lang_cplusplus;

  /* Put functions on the TYPE_METHODS list and everything else on the
     TYPE_FIELDS list.  Note that these are built up in reverse order.
     We reverse them (to obtain declaration order) in finish_struct.  */
  if (TREE_CODE (decl) == FUNCTION_DECL 
      || DECL_FUNCTION_TEMPLATE_P (decl))
    {
      /* We also need to add this function to the
	 CLASSTYPE_METHOD_VEC.  */
      add_method (current_class_type, decl, /*error_p=*/0);

      TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
      TYPE_METHODS (current_class_type) = decl;
    }
  else
    {
      /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
	 go at the beginning.  The reason is that lookup_field_1
	 searches the list in order, and we want a field name to
	 override a type name so that the "struct stat hack" will
	 work.  In particular:

	   struct S { enum E { }; int E } s;
	   s.E = 3;

	 is legal.  In addition, the FIELD_DECLs must be maintained in
	 declaration order so that class layout works as expected.
	 However, we don't need that order until class layout, so we
	 save a little time by putting FIELD_DECLs on in reverse order
	 here, and then reversing them in finish_struct_1.  (We could
	 also keep a pointer to the correct insertion points in the
	 list.)  */

      if (TREE_CODE (decl) == TYPE_DECL)
	TYPE_FIELDS (current_class_type) 
	  = chainon (TYPE_FIELDS (current_class_type), decl);
      else
	{
	  TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type);
	  TYPE_FIELDS (current_class_type) = decl;
	}

      /* Enter the DECL into the scope of the class.  */
      if (TREE_CODE (decl) != USING_DECL)
	pushdecl_class_level (decl);
    }
}

/* Finish a class definition T with the indicate ATTRIBUTES.  If SEMI,
   the definition is immediately followed by a semicolon.  Returns the
   type.  */

tree
finish_class_definition (t, attributes, semi, pop_scope_p)
     tree t;
     tree attributes;
     int semi;
     int pop_scope_p;
{
  /* finish_struct nukes this anyway; if finish_exception does too,
     then it can go.  */
  if (semi)
    note_got_semicolon (t);

  /* If we got any attributes in class_head, xref_tag will stick them in
     TREE_TYPE of the type.  Grab them now.  */
  attributes = chainon (TREE_TYPE (t), attributes);
  TREE_TYPE (t) = NULL_TREE;

  if (TREE_CODE (t) == ENUMERAL_TYPE)
    ;
  else
    {
      t = finish_struct (t, attributes);
      if (semi) 
	note_got_semicolon (t);
    }

  if (! semi)
    check_for_missing_semicolon (t); 
  if (pop_scope_p)
    pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t)));
  if (current_function_decl)
    type_lookups = error_mark_node;
  if (current_scope () == current_function_decl)
    do_pending_defargs ();

  return t;
}

/* Finish processing the default argument expressions cached during
   the processing of a class definition.  */

void
begin_inline_definitions ()
{
  if (current_scope () == current_function_decl)
    do_pending_inlines ();
}

/* Finish processing the inline function definitions cached during the
   processing of a class definition.  */

void
finish_inline_definitions ()
{
  if (current_class_type == NULL_TREE)
    clear_inline_text_obstack (); 
}

/* Finish processing the declaration of a member class template
   TYPES whose template parameters are given by PARMS.  */

tree
finish_member_class_template (types)
     tree types;
{
  tree t;

  /* If there are declared, but undefined, partial specializations
     mixed in with the typespecs they will not yet have passed through
     maybe_process_partial_specialization, so we do that here.  */
  for (t = types; t != NULL_TREE; t = TREE_CHAIN (t))
    if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_VALUE (t))))
      maybe_process_partial_specialization (TREE_VALUE (t));

  note_list_got_semicolon (types);
  grok_x_components (types);
  if (TYPE_CONTEXT (TREE_VALUE (types)) != current_class_type)
    /* The component was in fact a friend declaration.  We avoid
       finish_member_template_decl performing certain checks by
       unsetting TYPES.  */
    types = NULL_TREE;
  
  finish_member_template_decl (types);

  /* As with other component type declarations, we do
     not store the new DECL on the list of
     component_decls.  */
  return NULL_TREE;
}

/* Finish processsing a complete template declaration.  The PARMS are
   the template parameters.  */

void
finish_template_decl (parms)
     tree parms;
{
  if (parms)
    end_template_decl ();
  else
    end_specialization ();
}

/* Finish processing a template-id (which names a type) of the form
   NAME < ARGS >.  Return the TYPE_DECL for the type named by the
   template-id.  If ENTERING_SCOPE is non-zero we are about to enter
   the scope of template-id indicated.  */

tree
finish_template_type (name, args, entering_scope)
     tree name;
     tree args;
     int entering_scope;
{
  tree decl;

  decl = lookup_template_class (name, args,
				NULL_TREE, NULL_TREE,
	                        entering_scope, /*complain=*/1);
  if (decl != error_mark_node)
    decl = TYPE_STUB_DECL (decl);

  return decl;
}

/* SR is a SCOPE_REF node.  Enter the scope of SR, whether it is a
   namespace scope or a class scope.  */

void
enter_scope_of (sr)
     tree sr;
{
  tree scope = TREE_OPERAND (sr, 0);

  if (TREE_CODE (scope) == NAMESPACE_DECL)
    {
      push_decl_namespace (scope);
      TREE_COMPLEXITY (sr) = -1;
    }
  else if (scope != current_class_type)
    {
      if (TREE_CODE (scope) == TYPENAME_TYPE)
	{
	  /* In a declarator for a template class member, the scope will
	     get here as an implicit typename, a TYPENAME_TYPE with a type.  */
	  scope = TREE_TYPE (scope);
	  TREE_OPERAND (sr, 0) = scope;
	}
      push_nested_class (scope, 3);
      TREE_COMPLEXITY (sr) = current_class_depth;
    }
}

/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
   Return a TREE_LIST containing the ACCESS_SPECIFIER and the
   BASE_CLASS, or NULL_TREE if an error occurred.  The
   ACCESSS_SPECIFIER is one of
   access_{default,public,protected_private}[_virtual]_node.*/

tree 
finish_base_specifier (access_specifier, base_class)
     tree access_specifier;
     tree base_class;
{
  tree result;

  if (! is_aggr_type (base_class, 1))
    result = NULL_TREE;
  else
    {
      if (CP_TYPE_QUALS (base_class) != 0)
        {
          cp_error ("base class `%T' has cv qualifiers", base_class);
          base_class = TYPE_MAIN_VARIANT (base_class);
        }
      result = build_tree_list (access_specifier, base_class);
    }

  return result;
}

/* Called when multiple declarators are processed.  If that is not
   premitted in this context, an error is issued.  */

void
check_multiple_declarators ()
{
  /* [temp]
     
     In a template-declaration, explicit specialization, or explicit
     instantiation the init-declarator-list in the declaration shall
     contain at most one declarator.  

     We don't just use PROCESSING_TEMPLATE_DECL for the first
     condition since that would disallow the perfectly legal code, 
     like `template <class T> struct S { int i, j; };'.  */
  tree scope = current_scope ();

  if (scope && TREE_CODE (scope) == FUNCTION_DECL)
    /* It's OK to write `template <class T> void f() { int i, j;}'.  */
    return;
     
  if (PROCESSING_REAL_TEMPLATE_DECL_P () 
      || processing_explicit_instantiation
      || processing_specialization)
    cp_error ("multiple declarators in template declaration");
}

tree
finish_typeof (expr)
     tree expr;
{
  if (processing_template_decl)
    {
      tree t;

      t = make_aggr_type (TYPEOF_TYPE);
      TYPE_FIELDS (t) = expr;

      return t;
    }

  if (TREE_CODE (expr) == OFFSET_REF)
    expr = resolve_offset_ref (expr);

  return TREE_TYPE (expr);
}

/* Generate RTL for the statement T, and its substatements, and any
   other statements at its nesting level.  */

static void
cp_expand_stmt (t)
     tree t;
{
  switch (TREE_CODE (t))
    {
    case CLEANUP_STMT:
      genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
      break;

    case START_CATCH_STMT:
      genrtl_catch_block (TREE_TYPE (t));
      break;

    case CTOR_STMT:
      genrtl_ctor_stmt (t);
      break;

    case TRY_BLOCK:
      genrtl_try_block (t);
      break;

    case EH_SPEC_BLOCK:
      genrtl_eh_spec_block (t);
      break;

    case HANDLER:
      genrtl_handler (t);
      break;

    case SUBOBJECT:
      genrtl_subobject (SUBOBJECT_CLEANUP (t));
      break;

    case RETURN_INIT:
      genrtl_named_return_value ();
      break;

    default:
      my_friendly_abort (19990810);
      break;
    }
}

/* Called from expand_body via walk_tree.  Replace all AGGR_INIT_EXPRs
   will equivalent CALL_EXPRs.  */

static tree
simplify_aggr_init_exprs_r (tp, walk_subtrees, data)
     tree *tp;
     int *walk_subtrees ATTRIBUTE_UNUSED;
     void *data ATTRIBUTE_UNUSED;
{
  tree aggr_init_expr;
  tree call_expr;
  tree fn;
  tree args;
  tree slot;
  tree type;
  int copy_from_buffer_p;

  aggr_init_expr = *tp;
  /* We don't need to walk into types; there's nothing in a type that
     needs simplification.  (And, furthermore, there are places we
     actively don't want to go.  For example, we don't want to wander
     into the default arguments for a FUNCTION_DECL that appears in a
     CALL_EXPR.)  */
  if (TYPE_P (aggr_init_expr))
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }
  /* Only AGGR_INIT_EXPRs are interesting.  */
  else if (TREE_CODE (aggr_init_expr) != AGGR_INIT_EXPR)
    return NULL_TREE;

  /* Form an appropriate CALL_EXPR.  */
  fn = TREE_OPERAND (aggr_init_expr, 0);
  args = TREE_OPERAND (aggr_init_expr, 1);
  slot = TREE_OPERAND (aggr_init_expr, 2);
  type = TREE_TYPE (aggr_init_expr);
  if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
    {
      /* Replace the first argument with the address of the third
	 argument to the AGGR_INIT_EXPR.  */
      mark_addressable (slot);
      args = tree_cons (NULL_TREE, 
			build1 (ADDR_EXPR, 
				build_pointer_type (TREE_TYPE (slot)),
				slot),
			TREE_CHAIN (args));
    }
  call_expr = build (CALL_EXPR, 
		     TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
		     fn, args, NULL_TREE);
  TREE_SIDE_EFFECTS (call_expr) = 1;

  /* If we're using the non-reentrant PCC calling convention, then we
     need to copy the returned value out of the static buffer into the
     SLOT.  */
  copy_from_buffer_p = 0;
#ifdef PCC_STATIC_STRUCT_RETURN  
  if (!AGGR_INIT_VIA_CTOR_P (aggr_init_expr) && aggregate_value_p (type))
    {
      int old_ac;

      flag_access_control = 0;
      call_expr = build_aggr_init (slot, call_expr, LOOKUP_ONLYCONVERTING);
      flag_access_control = old_ac;
      copy_from_buffer_p = 1;
    }
#endif

  /* If this AGGR_INIT_EXPR indicates the value returned by a
     function, then we want to use the value of the initialized
     location as the result.  */
  if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr) || copy_from_buffer_p)
    {
      call_expr = build (COMPOUND_EXPR, type,
			 call_expr, slot);
      TREE_SIDE_EFFECTS (call_expr) = 1;
    }

  /* Replace the AGGR_INIT_EXPR with the CALL_EXPR.  */
  TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr);
  *tp = call_expr;

  /* Keep iterating.  */
  return NULL_TREE;
}

/* Emit all thunks to FN that should be emitted when FN is emitted.  */

static void
emit_associated_thunks (fn)
     tree fn;
{
  /* When we use vcall offsets, we emit thunks with the virtual
     functions to which they thunk. The whole point of vcall offsets
     is so that you can know statically the entire set of thunks that
     will ever be needed for a given virtual function, thereby
     enabling you to output all the thunks with the function itself.  */
  if (vcall_offsets_in_vtable_p () && DECL_VIRTUAL_P (fn))
    {
      tree binfo;
      tree v;

      for (binfo = TYPE_BINFO (DECL_CONTEXT (fn));
	   binfo;
	   binfo = TREE_CHAIN (binfo))
	for (v = BINFO_VIRTUALS (binfo); v; v = TREE_CHAIN (v))
	  if (BV_FN (v) == fn
	      && (!integer_zerop (BV_DELTA (v))
		  || BV_VCALL_INDEX (v)))
	    {
	      tree thunk;
	      tree vcall_index;

	      if (BV_USE_VCALL_INDEX_P (v))
		{
		  vcall_index = BV_VCALL_INDEX (v);
		  my_friendly_assert (vcall_index != NULL_TREE, 20000621);
		}
	      else
		vcall_index = NULL_TREE;

	      thunk = make_thunk (build1 (ADDR_EXPR,
					  vfunc_ptr_type_node,
					  fn),
				  BV_DELTA (v),
				  vcall_index,
				  /*generate_with_vtable_p=*/0);
	      use_thunk (thunk, /*emit_p=*/1);
	    }
    }
}

/* Generate RTL for FN.  */

void
expand_body (fn)
     tree fn;
{
  int saved_lineno;
  const char *saved_input_filename;

  /* When the parser calls us after finishing the body of a template
     function, we don't really want to expand the body.  When we're
     processing an in-class definition of an inline function,
     PROCESSING_TEMPLATE_DECL will no longer be set here, so we have
     to look at the function itself.  */
  if (processing_template_decl
      || (DECL_LANG_SPECIFIC (fn) 
	  && DECL_TEMPLATE_INFO (fn)
	  && uses_template_parms (DECL_TI_ARGS (fn))))
    {
      /* Normally, collection only occurs in rest_of_compilation.  So,
	 if we don't collect here, we never collect junk generated
	 during the processing of templates until we hit a
	 non-template function.  */
      ggc_collect ();
      return;
    }

  /* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs.  */
  walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
				simplify_aggr_init_exprs_r,
				NULL);

  /* If this is a constructor or destructor body, we have to clone it
     under the new ABI.  */
  if (maybe_clone_body (fn))
    {
      /* We don't want to process FN again, so pretend we've written
	 it out, even though we haven't.  */
      TREE_ASM_WRITTEN (fn) = 1;
      return;
    }

  /* There's no reason to do any of the work here if we're only doing
     semantic analysis; this code just generates RTL.  */
  if (flag_syntax_only)
    return;

  /* If possible, avoid generating RTL for this function.  Instead,
     just record it as an inline function, and wait until end-of-file
     to decide whether to write it out or not.  */
  if (/* We have to generate RTL if it's not an inline function.  */
      (DECL_INLINE (fn) || DECL_COMDAT (fn))
      /* Or if we have to keep all inline functions anyhow.  */
      && !flag_keep_inline_functions
      /* Or if we actually have a reference to the function.  */
      && !DECL_NEEDED_P (fn)
      /* Or if this is a nested function.  */
      && !decl_function_context (fn))
    {
      /* Set DECL_EXTERNAL so that assemble_external will be called as
	 necessary.  We'll clear it again in finish_file.  */
      if (!DECL_EXTERNAL (fn))
	{
	  DECL_NOT_REALLY_EXTERN (fn) = 1;
	  DECL_EXTERNAL (fn) = 1;
	}
      /* Remember this function.  In finish_file we'll decide if
	 we actually need to write this function out.  */
      defer_fn (fn);
      /* Let the back-end know that this funtion exists.  */
      note_deferral_of_defined_inline_function (fn);
      return;
    }

  /* Compute the appropriate object-file linkage for inline
     functions.  */
  if (DECL_DECLARED_INLINE_P (fn))
    import_export_decl (fn);

  /* Emit any thunks that should be emitted at the same time as FN.  */
  emit_associated_thunks (fn);

  timevar_push (TV_INTEGRATION);

  /* Optimize the body of the function before expanding it.  */
  optimize_function (fn);

  timevar_pop (TV_INTEGRATION);
  timevar_push (TV_EXPAND);

  /* Save the current file name and line number.  When we expand the
     body of the function, we'll set LINENO and INPUT_FILENAME so that
     error-mesages come out in the right places.  */
  saved_lineno = lineno;
  saved_input_filename = input_filename;
  lineno = DECL_SOURCE_LINE (fn);
  input_filename = DECL_SOURCE_FILE (fn);

  genrtl_start_function (fn);
  current_function_is_thunk = DECL_THUNK_P (fn);

  /* We don't need to redeclare __FUNCTION__, __PRETTY_FUNCTION__, or
     any of the other magic variables we set up when starting a
     function body.  */
  function_name_declared_p = 1;

  /* Expand the body.  */
  expand_stmt (DECL_SAVED_TREE (fn));

  /* Statements should always be full-expressions at the outermost set
     of curly braces for a function.  */
  my_friendly_assert (stmts_are_full_exprs_p (), 19990831);

  /* The outermost statement for a function contains the line number
     recorded when we finished processing the function.  */
  lineno = STMT_LINENO (DECL_SAVED_TREE (fn));

  /* Generate code for the function.  */
  genrtl_finish_function (fn);

  /* If possible, obliterate the body of the function so that it can
     be garbage collected.  */
  if (flag_dump_translation_unit)
    /* Keep the body; we're going to dump it.  */
    ;
  else if (DECL_INLINE (fn) && flag_inline_trees)
    /* We might need the body of this function so that we can expand
       it inline somewhere else.  */
    ;
  else
    /* We don't need the body; blow it away.  */
    DECL_SAVED_TREE (fn) = NULL_TREE;

  /* And restore the current source position.  */
  lineno = saved_lineno;
  input_filename = saved_input_filename;
  extract_interface_info ();

  timevar_pop (TV_EXPAND);
}

/* Start generating the RTL for FN.  */

static void
genrtl_start_function (fn)
     tree fn;
{
  tree parm;

  /* Tell everybody what function we're processing.  */
  current_function_decl = fn;
  /* Get the RTL machinery going for this function.  */
  init_function_start (fn, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn));
  /* Let everybody know that we're expanding this function, not doing
     semantic analysis.  */
  expanding_p = 1;

  /* Even though we're inside a function body, we still don't want to
     call expand_expr to calculate the size of a variable-sized array.
     We haven't necessarily assigned RTL to all variables yet, so it's
     not safe to try to expand expressions involving them.  */
  immediate_size_expand = 0;
  cfun->x_dont_save_pending_sizes_p = 1;

  /* Let the user know we're compiling this function.  */
  announce_function (fn);

  /* Initialize the per-function data.  */
  my_friendly_assert (!DECL_PENDING_INLINE_P (fn), 20000911);
  if (DECL_SAVED_FUNCTION_DATA (fn))
    {
      /* If we already parsed this function, and we're just expanding it
	 now, restore saved state.  */
      *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);

      /* This function is being processed in whole-function mode; we
	 already did semantic analysis.  */
      cfun->x_whole_function_mode_p = 1;

      /* If we decided that we didn't want to inline this function,
	 make sure the back-end knows that.  */
      if (!current_function_cannot_inline)
	current_function_cannot_inline = cp_function_chain->cannot_inline;

      /* We don't need the saved data anymore.  */
      free (DECL_SAVED_FUNCTION_DATA (fn));
      DECL_SAVED_FUNCTION_DATA (fn) = NULL;
    }

  /* Tell the cross-reference machinery that we're defining this
     function.  */
  GNU_xref_function (fn, DECL_ARGUMENTS (fn));

  /* Keep track of how many functions we're presently expanding.  */
  ++function_depth;

  /* Create a binding level for the parameters.  */
  expand_start_bindings (2);
  /* Clear out any previously saved instructions for this function, in
     case it was defined more than once.  */
  DECL_SAVED_INSNS (fn) = NULL;
  /* Go through the PARM_DECLs for this function to see if any need
     cleanups.  */
  for (parm = DECL_ARGUMENTS (fn); parm; parm = TREE_CHAIN (parm))
    if (TREE_TYPE (parm) != error_mark_node
	&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (parm)))
      {
	expand_function_start (fn, /*parms_have_cleanups=*/1);
	break;
      }
  if (!parm)
    expand_function_start (fn, /*parms_have_cleanups=*/0);
  /* If this function is `main'.  */
  if (DECL_MAIN_P (fn))
    expand_main_function ();
  /* Create a binding contour which can be used to catch
     cleanup-generated temporaries.  */
  expand_start_bindings (2);
}

/* Finish generating the RTL for FN.  */

static void
genrtl_finish_function (fn)
     tree fn;
{
  tree no_return_label = NULL_TREE;

#if 0
  if (write_symbols != NO_DEBUG)
    {
      /* Keep this code around in case we later want to control debug info
	 based on whether a type is "used".  (jason 1999-11-11) */

      tree ttype = target_type (fntype);
      tree parmdecl;

      if (IS_AGGR_TYPE (ttype))
	/* Let debugger know it should output info for this type.  */
	note_debug_info_needed (ttype);

      for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl))
	{
	  ttype = target_type (TREE_TYPE (parmdecl));
	  if (IS_AGGR_TYPE (ttype))
	    /* Let debugger know it should output info for this type.  */
	    note_debug_info_needed (ttype);
	}
    }
#endif

  /* Clean house because we will need to reorder insns here.  */
  do_pending_stack_adjust ();

  if (!dtor_label && !DECL_CONSTRUCTOR_P (fn)
      && return_label != NULL_RTX
      && current_function_return_value == NULL_TREE
      && ! DECL_NAME (DECL_RESULT (current_function_decl)))
    no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);

  /* If this function is supposed to return a value, ensure that
     we do not fall into the cleanups by mistake.  The end of our
     function will look like this:

     user code (may have return stmt somewhere)
     goto no_return_label
     cleanup_label:
     cleanups
     goto return_label
     no_return_label:
     NOTE_INSN_FUNCTION_END
     return_label:
     things for return

     If the user omits a return stmt in the USER CODE section, we
     will have a control path which reaches NOTE_INSN_FUNCTION_END.
     Otherwise, we won't.  */
  if (no_return_label)
    {
      DECL_CONTEXT (no_return_label) = fn;
      DECL_INITIAL (no_return_label) = error_mark_node;
      DECL_SOURCE_FILE (no_return_label) = input_filename;
      DECL_SOURCE_LINE (no_return_label) = lineno;
      expand_goto (no_return_label);
    }

  if (cleanup_label)
    {
      /* Remove the binding contour which is used to catch
	 cleanup-generated temporaries.  */
      expand_end_bindings (0, 0, 0);
      poplevel (0, 0, 0);

      /* Emit label at beginning of cleanup code for parameters.  */
      emit_label (cleanup_label);
    }

  /* Finish building code that will trigger warnings if users forget
     to make their functions return values.  */
  if (return_label)
    emit_jump (return_label);
  if (no_return_label)
    {
      /* We don't need to call `expand_*_return' here because we don't
	 need any cleanups here--this path of code is only for error
	 checking purposes.  */
      expand_label (no_return_label);
    }

  /* We hard-wired immediate_size_expand to zero in start_function.
     Expand_function_end will decrement this variable.  So, we set the
     variable to one here, so that after the decrement it will remain
     zero.  */
  immediate_size_expand = 1;

  /* Generate rtl for function exit.  */
  expand_function_end (input_filename, lineno, 1);

  /* If this is a nested function (like a template instantiation that
     we're compiling in the midst of compiling something else), push a
     new GC context.  That will keep local variables on the stack from
     being collected while we're doing the compilation of this
     function.  */
  if (function_depth > 1)
    ggc_push_context ();

  /* There's no need to defer outputting this function any more; we
     know we want to output it.  */
  DECL_DEFER_OUTPUT (fn) = 0;

  /* Run the optimizers and output the assembler code for this
     function.  */
  rest_of_compilation (fn);

  /* Undo the call to ggc_push_context above.  */
  if (function_depth > 1)
    ggc_pop_context ();

  if (DECL_SAVED_INSNS (fn) && ! TREE_ASM_WRITTEN (fn))
    {
      /* Set DECL_EXTERNAL so that assemble_external will be called as
	 necessary.  We'll clear it again in finish_file.  */
      if (! DECL_EXTERNAL (fn))
	DECL_NOT_REALLY_EXTERN (fn) = 1;
      DECL_EXTERNAL (fn) = 1;
      defer_fn (fn);
    }

#if 0
  /* Keep this code around in case we later want to control debug info
     based on whether a type is "used".  (jason 1999-11-11) */

  if (ctype && TREE_ASM_WRITTEN (fn))
    note_debug_info_needed (ctype);
#endif

  /* If this function is marked with the constructor attribute, add it
     to the list of functions to be called along with constructors
     from static duration objects.  */
  if (DECL_STATIC_CONSTRUCTOR (fn))
    static_ctors = tree_cons (NULL_TREE, fn, static_ctors);

  /* If this function is marked with the destructor attribute, add it
     to the list of functions to be called along with destructors from
     static duration objects.  */
  if (DECL_STATIC_DESTRUCTOR (fn))
    static_dtors = tree_cons (NULL_TREE, fn, static_dtors);

  --function_depth;

  /* If we don't need the RTL for this function anymore, stop pointing
     to it.  That's especially important for LABEL_DECLs, since you
     can reach all the instructions in the function from the
     CODE_LABEL stored in the DECL_RTL for the LABEL_DECL.  */
  if (!DECL_SAVED_INSNS (fn))
    {
      tree t;

      /* Walk the BLOCK-tree, clearing DECL_RTL for LABEL_DECLs and
	 non-static local variables.  */
      walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
				    clear_decl_rtl,
				    NULL);

      /* Clear out the RTL for the arguments.  */
      for (t = DECL_ARGUMENTS (fn); t; t = TREE_CHAIN (t))
	{
	  SET_DECL_RTL (t, NULL_RTX);
	  DECL_INCOMING_RTL (t) = NULL_RTX;
	}

      if (!(flag_inline_trees && DECL_INLINE (fn)))
	/* DECL_INITIAL must remain nonzero so we know this was an
	   actual function definition.  */
	DECL_INITIAL (fn) = error_mark_node;
    }
  
  /* Let the error reporting routines know that we're outside a
     function.  For a nested function, this value is used in
     pop_cp_function_context and then reset via pop_function_context.  */
  current_function_decl = NULL_TREE;
}

/* Clear out the DECL_RTL for the non-static variables in BLOCK and
   its sub-blocks.  */

static tree
clear_decl_rtl (tp, walk_subtrees, data)
     tree *tp;
     int *walk_subtrees ATTRIBUTE_UNUSED;
     void *data ATTRIBUTE_UNUSED;
{
  if (nonstatic_local_decl_p (*tp)) 
    SET_DECL_RTL (*tp, NULL_RTX);
    
  return NULL_TREE;
}

/* Perform initialization related to this module.  */

void
init_cp_semantics ()
{
  lang_expand_stmt = cp_expand_stmt;
}
