/* toir.cc -- Lower D frontend statements to GCC trees.
   Copyright (C) 2006-2021 Free Software Foundation, Inc.

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 "dmd/aggregate.h"
#include "dmd/declaration.h"
#include "dmd/expression.h"
#include "dmd/identifier.h"
#include "dmd/init.h"
#include "dmd/statement.h"

#include "tree.h"
#include "tree-iterator.h"
#include "options.h"
#include "stmt.h"
#include "fold-const.h"
#include "diagnostic.h"
#include "stringpool.h"
#include "function.h"
#include "toplev.h"

#include "d-tree.h"


/* Update data for defined and undefined labels when leaving a scope.  */

bool
pop_binding_label (Statement * const &, d_label_entry *ent, binding_level *bl)
{
  binding_level *obl = bl->level_chain;

  if (ent->level == bl)
    {
      if (bl->kind == level_try)
	ent->in_try_scope = true;
      else if (bl->kind == level_catch)
	ent->in_catch_scope = true;

      ent->level = obl;
    }
  else if (ent->fwdrefs)
    {
      for (d_label_use_entry *ref = ent->fwdrefs; ref; ref = ref->next)
	ref->level = obl;
    }

  return true;
}

/* At the end of a function, all labels declared within the function
   go out of scope.  Queue them in LABELS.  */

bool
pop_label (Statement * const &, d_label_entry *ent, vec <tree> &labels)
{
  if (!ent->bc_label)
    {
      /* Put the labels into the "variables" of the top-level block,
	 so debugger can see them.  */
      if (DECL_NAME (ent->label))
	{
	  gcc_assert (DECL_INITIAL (ent->label) != NULL_TREE);
	  labels.safe_push (ent->label);
	}
    }

  return true;
}

/* The D front-end does not use the 'binding level' system for a symbol table,
   however it has been the goto structure for tracking code flow.
   Primarily it is only needed to get debugging information for local variables
   and otherwise support the back-end.  */

void
push_binding_level (level_kind kind)
{
  /* Add it to the front of currently active scopes stack.  */
  binding_level *new_level = ggc_cleared_alloc <binding_level> ();
  new_level->level_chain = current_binding_level;
  new_level->kind = kind;

  current_binding_level = new_level;
}

static int
cmp_labels (const void *p1, const void *p2)
{
  const tree *l1 = (const tree *) p1;
  const tree *l2 = (const tree *) p2;
  return DECL_UID (*l1) - DECL_UID (*l2);
}

tree
pop_binding_level (void)
{
  binding_level *level = current_binding_level;
  current_binding_level = level->level_chain;

  tree block = make_node (BLOCK);
  BLOCK_VARS (block) = level->names;
  BLOCK_SUBBLOCKS (block) = level->blocks;

  /* In each subblock, record that this is its superior.  */
  for (tree t = level->blocks; t; t = BLOCK_CHAIN (t))
    BLOCK_SUPERCONTEXT (t) = block;

  if (level->kind == level_function)
    {
      /* Dispose of the block that we just made inside some higher level.  */
      DECL_INITIAL (current_function_decl) = block;
      BLOCK_SUPERCONTEXT (block) = current_function_decl;

      /* Pop all the labels declared in the function.  */
      if (d_function_chain->labels)
	{
	  auto_vec <tree> labels;
	  d_function_chain->labels->traverse <vec <tree> &,
					      &pop_label> (labels);
	  d_function_chain->labels->empty ();
	  labels.qsort (cmp_labels);
	  for (unsigned i = 0; i < labels.length (); ++i)
	    {
	      DECL_CHAIN (labels[i]) = BLOCK_VARS (block);
	      BLOCK_VARS (block) = labels[i];
	    }
	}
    }
  else
    {
      /* Any uses of undefined labels, and any defined labels, now operate
	 under constraints of next binding contour.  */
      if (d_function_chain && d_function_chain->labels)
	{
	  language_function *f = d_function_chain;
	  f->labels->traverse <binding_level *, &pop_binding_label> (level);
	}

      current_binding_level->blocks
	= block_chainon (current_binding_level->blocks, block);
    }

  TREE_USED (block) = 1;
  return block;
}

/* Create an empty statement tree rooted at T.  */

void
push_stmt_list (void)
{
  tree t = alloc_stmt_list ();
  vec_safe_push (d_function_chain->stmt_list, t);
  d_keep (t);
}

/* Finish the statement tree rooted at T.  */

tree
pop_stmt_list (void)
{
  tree t = d_function_chain->stmt_list->pop ();

  /* If the statement list is completely empty, just return it.  This is just
     as good as build_empty_stmt, with the advantage that statement lists
     are merged when they are appended to one another.  So using the
     STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P statements.  */
  if (TREE_SIDE_EFFECTS (t))
    {
      /* If the statement list contained exactly one statement, then extract
	 it immediately.  */
      tree_stmt_iterator i = tsi_start (t);

      if (tsi_one_before_end_p (i))
	{
	  tree u = tsi_stmt (i);
	  tsi_delink (&i);
	  free_stmt_list (t);
	  t = u;
	}
    }

  return t;
}

/* T is an expression statement.  Add it to the statement-tree.  */

void
add_stmt (tree t)
{
  /* Ignore (void) 0; expression statements received from the frontend.
     Likewise void_node is used when contracts become nops in release code.  */
  if (t == void_node || IS_EMPTY_STMT (t))
    return;

  /* At this point, we no longer care about the value of expressions,
     so if there's no side-effects, then don't add it.  */
  if (!TREE_SIDE_EFFECTS (t))
    return;

  if (TREE_CODE (t) == COMPOUND_EXPR)
    {
      /* Push out each comma expressions as separate statements.  */
      add_stmt (TREE_OPERAND (t, 0));
      add_stmt (TREE_OPERAND (t, 1));
    }
  else
    {
      /* Force the type to be void so we don't need to create a temporary
	 variable to hold the inner expression.  */
      if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
	TREE_TYPE (t) = void_type_node;

      /* Append the expression to the statement list.
	 Make sure it has a proper location.  */
      if (EXPR_P (t) && !EXPR_HAS_LOCATION (t))
	SET_EXPR_LOCATION (t, input_location);

      tree stmt_list = d_function_chain->stmt_list->last ();
      append_to_statement_list_force (t, &stmt_list);
    }
}

/* Implements the visitor interface to build the GCC trees of all Statement
   AST classes emitted from the D Front-end.
   All visit methods accept one parameter S, which holds the frontend AST
   of the statement to compile.  They also don't return any value, instead
   generated code are pushed to add_stmt(), which appends them to the
   statement list in the current_binding_level.  */

class IRVisitor : public Visitor
{
  using Visitor::visit;

  FuncDeclaration *func_;

  /* Stack of labels which are targets for "break" and "continue",
     linked through TREE_CHAIN.  */
  tree break_label_;
  tree continue_label_;

public:
  IRVisitor (FuncDeclaration *fd)
  {
    this->func_ = fd;
    this->break_label_ = NULL_TREE;
    this->continue_label_ = NULL_TREE;
  }

  /* Helper for generating code for the statement AST class S.
     Sets up the location of the statement before lowering.  */

  void build_stmt (Statement *s)
  {
    location_t saved_location = input_location;
    input_location = make_location_t (s->loc);
    s->accept (this);
    input_location = saved_location;
  }

  /* Start a new scope for a KIND statement.
     Each user-declared variable will have a binding contour that begins
     where the variable is declared and ends at its containing scope.  */

  void start_scope (level_kind kind)
  {
    push_binding_level (kind);
    push_stmt_list ();
  }

  /* Leave scope pushed by start_scope, returning a new bind_expr if
     any variables where declared in the scope.  */

  tree end_scope (void)
  {
    tree block = pop_binding_level ();
    tree body = pop_stmt_list ();

    if (!BLOCK_VARS (block))
      return body;

    tree bind = build3 (BIND_EXPR, void_type_node,
			BLOCK_VARS (block), body, block);
    TREE_SIDE_EFFECTS (bind) = 1;
    return bind;
  }

  /* Like end_scope, but also push it into the outer statement-tree.  */

  void finish_scope (void)
  {
    tree scope = this->end_scope ();
    add_stmt (scope);
  }

  /* Return TRUE if IDENT is the current function return label.  */

  bool is_return_label (Identifier *ident)
  {
    if (this->func_->returnLabel)
      return this->func_->returnLabel->ident == ident;

    return false;
  }

  /* Define a label, specifying the location in the source file.
     Return the LABEL_DECL node for the label.  */

  tree define_label (Statement *s, Identifier *ident = NULL)
  {
    tree label = this->lookup_label (s, ident);
    gcc_assert (DECL_INITIAL (label) == NULL_TREE);

    d_label_entry *ent = d_function_chain->labels->get (s);
    gcc_assert (ent != NULL);

    /* Mark label as having been defined.  */
    DECL_INITIAL (label) = error_mark_node;

    ent->level = current_binding_level;

    for (d_label_use_entry *ref = ent->fwdrefs; ref ; ref = ref->next)
      this->check_previous_goto (ent->statement, ref);
    ent->fwdrefs = NULL;

    return label;
  }

  /* Emit a LABEL expression.  */

  void do_label (tree label)
  {
    /* Don't write out label unless it is marked as used by the frontend.
       This makes auto-vectorization possible in conditional loops.
       The only excemption to this is in the LabelStatement visitor,
       in which all computed labels are marked regardless.  */
    if (TREE_USED (label))
      add_stmt (build1 (LABEL_EXPR, void_type_node, label));
  }

  /* Emit a goto expression to LABEL.  */

  void do_jump (tree label)
  {
    add_stmt (fold_build1 (GOTO_EXPR, void_type_node, label));
    TREE_USED (label) = 1;
  }

  /* Check that a new jump at statement scope FROM to a label declared in
     statement scope TO is valid.  */

  void check_goto (Statement *from, Statement *to)
  {
    d_label_entry *ent = d_function_chain->labels->get (to);
    gcc_assert (ent != NULL);

    /* If the label hasn't been defined yet, defer checking.  */
    if (!DECL_INITIAL (ent->label))
      {
	d_label_use_entry *fwdref = ggc_alloc <d_label_use_entry> ();
	fwdref->level = current_binding_level;
	fwdref->statement = from;
	fwdref->next = ent->fwdrefs;
	ent->fwdrefs = fwdref;
	return;
      }

    if (ent->in_try_scope)
      error_at (make_location_t (from->loc),
		"cannot %<goto%> into %<try%> block");
    else if (ent->in_catch_scope)
      error_at (make_location_t (from->loc),
		"cannot %<goto%> into %<catch%> block");
  }

  /* Check that a previously seen jump to a newly defined label is valid.
     S is the label statement; FWDREF is the jump context.  This is called
     for both user-defined and case labels.  */

  void check_previous_goto (Statement *s, d_label_use_entry *fwdref)
  {
    for (binding_level *b = current_binding_level; b ; b = b->level_chain)
      {
	if (b == fwdref->level)
	  break;

	if (b->kind == level_try || b->kind == level_catch)
	  {
	    location_t location;

	    if (s->isLabelStatement ())
	      {
		location = make_location_t (fwdref->statement->loc);
		if (b->kind == level_try)
		  error_at (location, "cannot %<goto%> into %<try%> block");
		else
		  error_at (location, "cannot %<goto%> into %<catch%> block");
	      }
	    else if (s->isCaseStatement ())
	      {
		location = make_location_t (s->loc);
		error_at (location, "case cannot be in different "
			  "%<try%> block level from %<switch%>");
	      }
	    else if (s->isDefaultStatement ())
	      {
		location = make_location_t (s->loc);
		error_at (location, "default cannot be in different "
			  "%<try%> block level from %<switch%>");
	      }
	    else
	      gcc_unreachable ();
	  }
      }
  }

  /* Get or build LABEL_DECL using the IDENT and statement block S given.  */

  tree lookup_label (Statement *s, Identifier *ident = NULL)
  {
    /* You can't use labels at global scope.  */
    if (d_function_chain == NULL)
      {
	error ("label %s referenced outside of any function",
	       ident ? ident->toChars () : "(unnamed)");
	return NULL_TREE;
      }

    /* Create the label htab for the function on demand.  */
    if (!d_function_chain->labels)
      {
	d_function_chain->labels
	  = hash_map <Statement *, d_label_entry>::create_ggc (13);
      }

    d_label_entry *ent = d_function_chain->labels->get (s);
    if (ent != NULL)
      return ent->label;
    else
      {
	tree name = ident ? get_identifier (ident->toChars ()) : NULL_TREE;
	tree decl = build_decl (make_location_t (s->loc), LABEL_DECL,
				name, void_type_node);
	DECL_CONTEXT (decl) = current_function_decl;
	DECL_MODE (decl) = VOIDmode;

	/* Create new empty slot.  */
	ent = ggc_cleared_alloc <d_label_entry> ();
	ent->statement = s;
	ent->label = decl;

	bool existed = d_function_chain->labels->put (s, *ent);
	gcc_assert (!existed);

	return decl;
      }
  }

  /* Get the LABEL_DECL to represent a break or continue for the
     statement S given.  BC indicates which.  */

  tree lookup_bc_label (Statement *s, bc_kind bc)
  {
    tree vec = this->lookup_label (s);

    /* The break and continue labels are put into a TREE_VEC.  */
    if (TREE_CODE (vec) == LABEL_DECL)
      {
	d_label_entry *ent = d_function_chain->labels->get (s);
	gcc_assert (ent != NULL);

	vec = make_tree_vec (2);
	TREE_VEC_ELT (vec, bc_break) = ent->label;

	/* Build the continue label.  */
	tree label = build_decl (make_location_t (s->loc), LABEL_DECL,
				 NULL_TREE, void_type_node);
	DECL_CONTEXT (label) = current_function_decl;
	DECL_MODE (label) = VOIDmode;
	TREE_VEC_ELT (vec, bc_continue) = label;

	ent->label = vec;
	ent->bc_label = true;
      }

    return TREE_VEC_ELT (vec, bc);
  }

  /* Set and return the current break label for the current block.  */

  tree push_break_label (Statement *s)
  {
    tree label = this->lookup_bc_label (s->getRelatedLabeled (), bc_break);
    DECL_CHAIN (label) = this->break_label_;
    this->break_label_ = label;
    return label;
  }

  /* Finish with the current break label.  */

  void pop_break_label (tree label)
  {
    gcc_assert (this->break_label_ == label);
    this->break_label_ = DECL_CHAIN (this->break_label_);
    this->do_label (label);
  }

  /* Set and return the continue label for the current block.  */

  tree push_continue_label (Statement *s)
  {
    tree label = this->lookup_bc_label (s->getRelatedLabeled (), bc_continue);
    DECL_CHAIN (label) = this->continue_label_;
    this->continue_label_ = label;
    return label;
  }

  /* Finish with the current continue label.  */

  void pop_continue_label (tree label)
  {
    gcc_assert (this->continue_label_ == label);
    this->continue_label_ = DECL_CHAIN (this->continue_label_);
    this->do_label (label);
  }

  /* Visitor interfaces.  */


  /* This should be overridden by each statement class.  */

  void visit (Statement *)
  {
    gcc_unreachable ();
  }

  /* The frontend lowers `scope (exit/failure/success)' statements as
     try/catch/finally.  At this point, this statement is just an empty
     placeholder.  Maybe the frontend shouldn't leak these.  */

  void visit (ScopeGuardStatement *)
  {
  }

  /* If statements provide simple conditional execution of statements.  */

  void visit (IfStatement *s)
  {
    this->start_scope (level_cond);

    /* Build the outer `if' condition, which may produce temporaries
       requiring scope destruction.  */
    tree ifcond = convert_for_condition (build_expr_dtor (s->condition),
					 s->condition->type);
    tree ifbody = void_node;
    tree elsebody = void_node;

    /* Build the `then' branch.  */
    if (s->ifbody)
      {
	push_stmt_list ();
	this->build_stmt (s->ifbody);
	ifbody = pop_stmt_list ();
      }

    /* Now build the `else' branch, which may have nested `else if' parts.  */
    if (s->elsebody)
      {
	push_stmt_list ();
	this->build_stmt (s->elsebody);
	elsebody = pop_stmt_list ();
      }

    /* Wrap up our constructed if condition into a COND_EXPR.  */
    tree cond = build_vcondition (ifcond, ifbody, elsebody);
    add_stmt (cond);

    /* Finish the if-then scope.  */
    this->finish_scope ();
  }

  /* Should there be any `pragma (...)' statements requiring code generation,
     here would be the place to do it.  For now, all pragmas are handled
     by the frontend.  */

  void visit (PragmaStatement *)
  {
  }

  /* The frontend lowers `while (...)' statements as `for (...)' loops.
     This visitor is not strictly required other than to enforce that
     these kinds of statements never reach here.  */

  void visit (WhileStatement *)
  {
    gcc_unreachable ();
  }

  /* Do while statments implement simple loops.  The body is executed, then
     the condition is evaluated.  */

  void visit (DoStatement *s)
  {
    tree lbreak = this->push_break_label (s);

    this->start_scope (level_loop);
    if (s->_body)
      {
	tree lcontinue = this->push_continue_label (s);
	this->build_stmt (s->_body);
	this->pop_continue_label (lcontinue);
      }

    /* Build the outer `while' condition, which may produce temporaries
       requiring scope destruction.  */
    tree exitcond = convert_for_condition (build_expr_dtor (s->condition),
					   s->condition->type);
    add_stmt (build_vcondition (exitcond, void_node,
				build1 (GOTO_EXPR, void_type_node, lbreak)));
    TREE_USED (lbreak) = 1;

    tree body = this->end_scope ();
    add_stmt (build1 (LOOP_EXPR, void_type_node, body));

    this->pop_break_label (lbreak);
  }

  /* For statements implement loops with initialization, test, and
     increment clauses.  */

  void visit (ForStatement *s)
  {
    tree lbreak = this->push_break_label (s);
    this->start_scope (level_loop);

    if (s->_init)
      this->build_stmt (s->_init);

    if (s->condition)
      {
	tree exitcond = convert_for_condition (build_expr_dtor (s->condition),
					       s->condition->type);
	add_stmt (build_vcondition (exitcond, void_node,
				    build1 (GOTO_EXPR, void_type_node,
					    lbreak)));
	TREE_USED (lbreak) = 1;
      }

    if (s->_body)
      {
	tree lcontinue = this->push_continue_label (s);
	this->build_stmt (s->_body);
	this->pop_continue_label (lcontinue);
      }

    if (s->increment)
      {
	/* Force side effects?  */
	add_stmt (build_expr_dtor (s->increment));
      }

    tree body = this->end_scope ();
    add_stmt (build1 (LOOP_EXPR, void_type_node, body));

    this->pop_break_label (lbreak);
  }

  /* The frontend lowers `foreach (...)' statements as `for (...)' loops.
     This visitor is not strictly required other than to enforce that
     these kinds of statements never reach here.  */

  void visit (ForeachStatement *)
  {
    gcc_unreachable ();
  }

  /* The frontend lowers `foreach (...; [x..y])' statements as `for (...)'
     loops.  This visitor is not strictly required other than to enforce that
     these kinds of statements never reach here.  */

  void visit (ForeachRangeStatement *)
  {
    gcc_unreachable ();
  }

  /* Jump to the associated exit label for the current loop.  If IDENT
     for the Statement is not null, then the label is user defined.  */

  void visit (BreakStatement *s)
  {
    if (s->ident)
      {
	/* The break label may actually be some levels up.
	   eg: on a try/finally wrapping a loop.  */
	LabelStatement *label = this->func_->searchLabel (s->ident)->statement;
	gcc_assert (label != NULL);
	Statement *stmt = label->statement->getRelatedLabeled ();
	this->do_jump (this->lookup_bc_label (stmt, bc_break));
      }
    else
      this->do_jump (this->break_label_);
  }

  /* Jump to the associated continue label for the current loop.  If IDENT
     for the Statement is not null, then the label is user defined.  */

  void visit (ContinueStatement *s)
  {
    if (s->ident)
      {
	LabelStatement *label = this->func_->searchLabel (s->ident)->statement;
	gcc_assert (label != NULL);
	this->do_jump (this->lookup_bc_label (label->statement,
					      bc_continue));
      }
    else
      this->do_jump (this->continue_label_);
  }

  /* A goto statement jumps to the statement identified by the given label.  */

  void visit (GotoStatement *s)
  {
    gcc_assert (s->label->statement != NULL);
    gcc_assert (s->tf == s->label->statement->tf);

    /* If no label found, there was an error.  */
    tree label = this->lookup_label (s->label->statement, s->label->ident);
    this->do_jump (label);

    /* Need to error if the goto is jumping into a try or catch block.  */
    this->check_goto (s, s->label->statement);
  }

  /* Statements can be labeled.  A label is an identifier that precedes
     a statement.  */

  void visit (LabelStatement *s)
  {
    LabelDsymbol *sym;

    if (this->is_return_label (s->ident))
      sym = this->func_->returnLabel;
    else
      sym = this->func_->searchLabel (s->ident);

    /* If no label found, there was an error.  */
    tree label = this->define_label (sym->statement, sym->ident);
    TREE_USED (label) = 1;

    this->do_label (label);

    if (this->is_return_label (s->ident) && this->func_->fensure != NULL)
      this->build_stmt (this->func_->fensure);
    else if (s->statement)
      this->build_stmt (s->statement);
  }

  /* A switch statement goes to one of a collection of case statements
     depending on the value of the switch expression.  */

  void visit (SwitchStatement *s)
  {
    this->start_scope (level_switch);
    tree lbreak = this->push_break_label (s);

    tree condition = build_expr_dtor (s->condition);
    Type *condtype = s->condition->type->toBasetype ();

    /* A switch statement on a string gets turned into a library call,
       which does a binary lookup on list of string cases.  */
    if (s->condition->type->isString ())
      {
	Type *etype = condtype->nextOf ()->toBasetype ();
	libcall_fn libcall;

	switch (etype->ty)
	  {
	  case Tchar:
	    libcall = LIBCALL_SWITCH_STRING;
	    break;

	  case Twchar:
	    libcall = LIBCALL_SWITCH_USTRING;
	    break;

	  case Tdchar:
	    libcall = LIBCALL_SWITCH_DSTRING;
	    break;

	  default:
	    ::error ("switch statement value must be an array of "
		     "some character type, not %s", etype->toChars ());
	    gcc_unreachable ();
	  }

	/* Apparently the backend is supposed to sort and set the indexes
	   on the case array, have to change them to be usable.  */
	Type *satype = condtype->sarrayOf (s->cases->length);
	vec <constructor_elt, va_gc> *elms = NULL;

	s->cases->sort ();

	for (size_t i = 0; i < s->cases->length; i++)
	  {
	    CaseStatement *cs = (*s->cases)[i];
	    cs->index = i;

	    if (cs->exp->op != TOKstring)
	      s->error ("case '%s' is not a string", cs->exp->toChars ());
	    else
	      {
		tree exp = build_expr (cs->exp, true);
		CONSTRUCTOR_APPEND_ELT (elms, size_int (i), exp);
	      }
	  }

	/* Build static declaration to reference constructor.  */
	tree ctor = build_constructor (build_ctype (satype), elms);
	tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor);
	TREE_READONLY (decl) = 1;
	d_pushdecl (decl);
	rest_of_decl_compilation (decl, 1, 0);

	/* Pass it as a dynamic array.  */
	decl = d_array_value (build_ctype (condtype->arrayOf ()),
			      size_int (s->cases->length),
			      build_address (decl));

	condition = build_libcall (libcall, Type::tint32, 2, decl, condition);
      }
    else if (!condtype->isscalar ())
      {
	error ("cannot handle switch condition of type %s",
	       condtype->toChars ());
	gcc_unreachable ();
      }

    condition = fold (condition);

    /* Build LABEL_DECLs now so they can be refered to by goto case.
       Also checking the jump from the switch to the label is allowed.  */
    if (s->cases)
      {
	for (size_t i = 0; i < s->cases->length; i++)
	  {
	    CaseStatement *cs = (*s->cases)[i];
	    tree caselabel = this->lookup_label (cs);

	    /* Write cases as a series of if-then-else blocks.
	       if (condition == case)
		 goto caselabel;  */
	    if (s->hasVars)
	      {
		tree ifcase = build2 (EQ_EXPR, build_ctype (condtype),
				      condition, build_expr_dtor (cs->exp));
		tree ifbody = fold_build1 (GOTO_EXPR, void_type_node,
					   caselabel);
		tree cond = build_vcondition (ifcase, ifbody, void_node);
		TREE_USED (caselabel) = 1;
		LABEL_VARIABLE_CASE (caselabel) = 1;
		add_stmt (cond);
	      }

	    this->check_goto (s, cs);
	  }

	if (s->sdefault)
	  {
	    tree defaultlabel = this->lookup_label (s->sdefault);

	    /* The default label is the last `else' block.  */
	    if (s->hasVars)
	      {
		this->do_jump (defaultlabel);
		LABEL_VARIABLE_CASE (defaultlabel) = 1;
	      }

	    this->check_goto (s, s->sdefault);
	  }
      }

    /* Switch body goes in its own statement list.  */
    push_stmt_list ();
    if (s->_body)
      this->build_stmt (s->_body);

    tree casebody = pop_stmt_list ();

    /* Wrap up constructed body into a switch_expr, unless it was
       converted to an if-then-else expression.  */
    if (s->hasVars)
      add_stmt (casebody);
    else
      {
	tree switchexpr = build2 (SWITCH_EXPR, TREE_TYPE (condition),
				  condition, casebody);
	add_stmt (switchexpr);
	SWITCH_ALL_CASES_P (switchexpr) = 1;
      }

    SWITCH_BREAK_LABEL_P (lbreak) = 1;

    /* If the switch had any `break' statements, emit the label now.  */
    this->pop_break_label (lbreak);
    this->finish_scope ();
  }

  /* Declare the case label associated with the current SwitchStatement.  */

  void visit (CaseStatement *s)
  {
    /* Emit the case label.  */
    tree label = this->define_label (s);

    if (LABEL_VARIABLE_CASE (label))
      this->do_label (label);
    else
      {
	tree casevalue;
	if (s->exp->type->isscalar ())
	  casevalue = build_expr (s->exp);
	else
	  casevalue = build_integer_cst (s->index, build_ctype (Type::tint32));

	tree caselabel = build_case_label (casevalue, NULL_TREE, label);
	add_stmt (caselabel);
      }

    /* Now do the body.  */
    if (s->statement)
      this->build_stmt (s->statement);
  }

  /* Declare the default label associated with the current SwitchStatement.  */

  void visit (DefaultStatement *s)
  {
    /* Emit the default case label.  */
    tree label = this->define_label (s);

    if (LABEL_VARIABLE_CASE (label))
      this->do_label (label);
    else
      {
	tree caselabel = build_case_label (NULL_TREE, NULL_TREE, label);
	add_stmt (caselabel);
      }

    /* Now do the body.  */
    if (s->statement)
      this->build_stmt (s->statement);
  }

  /* Implements `goto default' by jumping to the label associated with
     the DefaultStatement in a switch block.  */

  void visit (GotoDefaultStatement *s)
  {
    tree label = this->lookup_label (s->sw->sdefault);
    this->do_jump (label);
  }

  /* Implements `goto case' by jumping to the label associated with the
     CaseStatement in a switch block.  */

  void visit (GotoCaseStatement *s)
  {
    tree label = this->lookup_label (s->cs);
    this->do_jump (label);
  }

  /* Throw a SwitchError exception, called when a switch statement has
     no DefaultStatement, yet none of the cases match.  */

  void visit (SwitchErrorStatement *s)
  {
    add_stmt (build_assert_call (s->loc, LIBCALL_SWITCH_ERROR));
  }

  /* A return statement exits the current function and supplies its return
     value, if the return type is not void.  */

  void visit (ReturnStatement *s)
  {
    if (s->exp == NULL || s->exp->type->toBasetype ()->ty == Tvoid)
      {
	/* Return has no value.  */
	add_stmt (return_expr (NULL_TREE));
	return;
      }

    TypeFunction *tf = this->func_->type->toTypeFunction ();
    Type *type = this->func_->tintro != NULL
      ? this->func_->tintro->nextOf () : tf->nextOf ();

    if ((this->func_->isMain () || this->func_->isCMain ())
	&& type->toBasetype ()->ty == Tvoid)
      type = Type::tint32;

    if (this->func_->shidden)
      {
	/* Returning by hidden reference, store the result into the retval decl.
	   The result returned then becomes the retval reference itself.  */
	tree decl = DECL_RESULT (get_symbol_decl (this->func_));
	gcc_assert (!tf->isref);

	/* If returning via NRVO, just refer to the DECL_RESULT; this differs
	   from using NULL_TREE in that it indicates that we care about the
	   value of the DECL_RESULT.  */
	if (this->func_->nrvo_can && this->func_->nrvo_var)
	  {
	    add_stmt (return_expr (decl));
	    return;
	  }

	/* Detect a call to a constructor function, or if returning a struct
	   literal, write result directly into the return value.  */
	StructLiteralExp *sle = NULL;
	bool using_rvo_p = false;

	if (DotVarExp *dve = (s->exp->op == TOKcall
			      && s->exp->isCallExp ()->e1->op == TOKdotvar
			      ? s->exp->isCallExp ()->e1->isDotVarExp ()
			      : NULL))
	  {
	    if (dve->var->isCtorDeclaration ())
	      {
		if (CommaExp *ce = dve->e1->isCommaExp ())
		  {
		    /* Temporary initialized inside a return expression, and
		       used as the return value.  Replace it with the hidden
			reference to allow RVO return.  */
		    DeclarationExp *de = ce->e1->isDeclarationExp ();
		    VarExp *ve = ce->e2->isVarExp ();
		    if (de != NULL && ve != NULL
			&& ve->var == de->declaration
			&& ve->var->storage_class & STCtemp)
		      {
			tree var = get_symbol_decl (ve->var);
			TREE_ADDRESSABLE (var) = 1;
			SET_DECL_VALUE_EXPR (var, decl);
			DECL_HAS_VALUE_EXPR_P (var) = 1;
			SET_DECL_LANG_NRVO (var, this->func_->shidden);
			using_rvo_p = true;
		      }
		  }
		else
		  sle = dve->e1->isStructLiteralExp ();
	      }
	  }
	else
	  sle = s->exp->isStructLiteralExp ();

	if (sle != NULL)
	  {
	    StructDeclaration *sd = type->baseElemOf ()->isTypeStruct ()->sym;
	    sle->sym = build_address (this->func_->shidden);
	    using_rvo_p = true;

	    /* Fill any alignment holes in the return slot using memset.  */
	    if (!identity_compare_p (sd) || sd->isUnionDeclaration ())
	      add_stmt (build_memset_call (this->func_->shidden));
	  }

	if (using_rvo_p == true)
	  {
	    /* Generate: (expr, return <retval>);  */
	    add_stmt (build_expr_dtor (s->exp));
	  }
	else
	  {
	    /* Generate: (<retval> = expr, return <retval>);  */
	    tree expr = build_expr_dtor (s->exp);
	    tree init = stabilize_expr (&expr);
	    expr = build_assign (INIT_EXPR, this->func_->shidden, expr);
	    add_stmt (compound_expr (init, expr));
	  }

	add_stmt (return_expr (decl));
      }
    else if (tf->next->ty == Tnoreturn)
      {
	/* Returning an expression that has no value, but has a side effect
	   that should never return.  */
	add_stmt (build_expr_dtor (s->exp));
	add_stmt (return_expr (NULL_TREE));
      }
    else
      {
	/* Convert for initializing the DECL_RESULT.  */
	add_stmt (build_return_dtor (s->exp, type, tf));
      }
  }

  /* Evaluate the enclosed expression, and add it to the statement list.  */

  void visit (ExpStatement *s)
  {
    if (s->exp)
      {
	/* Expression may produce temporaries requiring scope destruction.  */
	tree exp = build_expr_dtor (s->exp);
	add_stmt (exp);
      }
  }

  /* Evaluate all enclosed statements.  */

  void visit (CompoundStatement *s)
  {
    if (s->statements == NULL)
      return;

    for (size_t i = 0; i < s->statements->length; i++)
      {
	Statement *statement = (*s->statements)[i];

	if (statement != NULL)
	  this->build_stmt (statement);
      }
  }

  /* The frontend lowers `foreach (Tuple!(...))' statements as an unrolled loop.
     These are compiled down as a `do ... while (0)', where each unrolled loop
     is nested inside and given their own continue label to jump to.  */

  void visit (UnrolledLoopStatement *s)
  {
    if (s->statements == NULL)
      return;

    tree lbreak = this->push_break_label (s);
    this->start_scope (level_loop);

    for (size_t i = 0; i < s->statements->length; i++)
      {
	Statement *statement = (*s->statements)[i];

	if (statement != NULL)
	  {
	    tree lcontinue = this->push_continue_label (statement);
	    this->build_stmt (statement);
	    this->pop_continue_label (lcontinue);
	  }
      }

    this->do_jump (this->break_label_);

    tree body = this->end_scope ();
    add_stmt (build1 (LOOP_EXPR, void_type_node, body));

    this->pop_break_label (lbreak);
  }

  /* Start a new scope and visit all nested statements, wrapping
     them up into a BIND_EXPR at the end of the scope.  */

  void visit (ScopeStatement *s)
  {
    if (s->statement == NULL)
      return;

    this->start_scope (level_block);
    this->build_stmt (s->statement);
    this->finish_scope ();
  }

  /* A with statement is a way to simplify repeated references to the same
     object, where the handle is either a class or struct instance.  */

  void visit (WithStatement *s)
  {
    this->start_scope (level_with);

    if (s->wthis)
      {
	/* Perform initialisation of the `with' handle.  */
	ExpInitializer *ie = s->wthis->_init->isExpInitializer ();
	gcc_assert (ie != NULL);

	declare_local_var (s->wthis);
	tree init = build_expr_dtor (ie->exp);
	add_stmt (init);
      }

    if (s->_body)
      this->build_stmt (s->_body);

    this->finish_scope ();
  }

  /* Implements `throw Object'.  Frontend already checks that the object
     thrown is a class type, but does not check if it is derived from
     Object.  Foreign objects are not currently supported at run-time.  */

  void visit (ThrowStatement *s)
  {
    ClassDeclaration *cd = s->exp->type->toBasetype ()->isClassHandle ();
    InterfaceDeclaration *id = cd->isInterfaceDeclaration ();
    tree arg = build_expr_dtor (s->exp);

    if (!global.params.useExceptions)
      {
	static int warned = 0;
	if (!warned)
	  {
	    error_at (make_location_t (s->loc), "exception handling disabled; "
		      "use %<-fexceptions%> to enable");
	    warned = 1;
	  }
      }

    if (cd->isCPPclass () || (id != NULL && id->isCPPclass ()))
      error_at (make_location_t (s->loc), "cannot throw C++ classes");
    else if (cd->com || (id != NULL && id->com))
      error_at (make_location_t (s->loc), "cannot throw COM objects");
    else
      arg = build_nop (build_ctype (get_object_type ()), arg);

    add_stmt (build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg));
  }

  /* Build a try-catch statement, one of the building blocks for exception
     handling generated by the frontend.  This is also used to implement
     `scope (failure)' statements.  */

  void visit (TryCatchStatement *s)
  {
    this->start_scope (level_try);
    if (s->_body)
      this->build_stmt (s->_body);

    tree trybody = this->end_scope ();

    /* Try handlers go in their own statement list.  */
    push_stmt_list ();

    if (s->catches)
      {
	for (size_t i = 0; i < s->catches->length; i++)
	  {
	    Catch *vcatch = (*s->catches)[i];

	    this->start_scope (level_catch);

	    tree ehptr = builtin_decl_explicit (BUILT_IN_EH_POINTER);
	    tree catchtype = build_ctype (vcatch->type);
	    tree object = NULL_TREE;

	    ehptr = build_call_expr (ehptr, 1, integer_zero_node);

	    /* Retrieve the internal exception object, which could be for a
	       D or C++ catch handler.  This is different from the generic
	       exception pointer returned from gcc runtime.  */
	    Type *tcatch = vcatch->type->toBasetype ();
	    ClassDeclaration *cd = tcatch->isClassHandle ();

	    libcall_fn libcall = (cd->isCPPclass ()) ? LIBCALL_CXA_BEGIN_CATCH
	      : LIBCALL_BEGIN_CATCH;
	    object = build_libcall (libcall, vcatch->type, 1, ehptr);

	    if (vcatch->var)
	      {
		tree var = get_symbol_decl (vcatch->var);
		tree init = build_assign (INIT_EXPR, var, object);

		declare_local_var (vcatch->var);
		add_stmt (init);
	      }
	    else
	      {
		/* Still need to emit a call to __gdc_begin_catch() to
		   remove the object from the uncaught exceptions list.  */
		add_stmt (object);
	      }

	    if (vcatch->handler)
	      this->build_stmt (vcatch->handler);

	    tree catchbody = this->end_scope ();

	    /* Need to wrap C++ handlers in a try/finally block to signal
	       the end catch callback.  */
	    if (cd->isCPPclass ())
	      {
		tree endcatch = build_libcall (LIBCALL_CXA_END_CATCH,
					       Type::tvoid, 0);
		catchbody = build2 (TRY_FINALLY_EXPR, void_type_node,
				    catchbody, endcatch);
	      }

	    add_stmt (build2 (CATCH_EXPR, void_type_node,
			      catchtype, catchbody));
	  }
      }

    tree catches = pop_stmt_list ();

    /* Back-end expects all catches in a TRY_CATCH_EXPR to be enclosed in a
       statement list, however pop_stmt_list may optimize away the list
       if there is only a single catch to push.  */
    if (TREE_CODE (catches) != STATEMENT_LIST)
      {
	tree stmt_list = alloc_stmt_list ();
	append_to_statement_list_force (catches, &stmt_list);
	catches = stmt_list;
      }

    add_stmt (build2 (TRY_CATCH_EXPR, void_type_node, trybody, catches));
  }

  /* Build a try-finally statement, one of the building blocks for exception
     handling generated by the frontend.  This is also used to implement
     `scope (exit)' statements.  */

  void visit (TryFinallyStatement *s)
  {
    this->start_scope (level_try);
    if (s->_body)
      this->build_stmt (s->_body);

    tree trybody = this->end_scope ();

    this->start_scope (level_finally);
    if (s->finalbody)
      this->build_stmt (s->finalbody);

    tree finally = this->end_scope ();

    add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, trybody, finally));
  }

  /* The frontend lowers `synchronized (...)' statements as a call to
     monitor/critical enter and exit wrapped around try/finally.
     This visitor is not strictly required other than to enforce that
     these kinds of statements never reach here.  */

  void visit (SynchronizedStatement *)
  {
    gcc_unreachable ();
  }

  /* D Inline Assembler is not implemented, as it would require writing
     an assembly parser for each supported target.  Instead we leverage
     GCC extended assembler using the GccAsmStatement class.  */

  void visit (AsmStatement *)
  {
    sorry ("D inline assembler statements are not supported in GDC.");
  }

  /* Build a GCC extended assembler expression, whose components are
     an INSN string, some OUTPUTS, some INPUTS, and some CLOBBERS.  */

  void visit (GccAsmStatement *s)
  {
    StringExp *insn = s->insn->toStringExp ();
    tree outputs = NULL_TREE;
    tree inputs = NULL_TREE;
    tree clobbers = NULL_TREE;
    tree labels = NULL_TREE;

    /* Collect all arguments, which may be input or output operands.  */
    if (s->args)
      {
	for (size_t i = 0; i < s->args->length; i++)
	  {
	    Identifier *name = (*s->names)[i];
	    const char *sname = name ? name->toChars () : NULL;
	    tree id = name ? build_string (strlen (sname), sname) : NULL_TREE;

	    StringExp *constr = (*s->constraints)[i]->toStringExp ();
	    const char *cstring = (const char *)(constr->len
						 ? constr->string : "");
	    tree str = build_string (constr->len, cstring);

	    Expression *earg = (*s->args)[i];
	    tree val = build_expr (earg);

	    if (i < s->outputargs)
	      {
		tree arg = build_tree_list (id, str);
		outputs = chainon (outputs, build_tree_list (arg, val));
	      }
	    else
	      {
		tree arg = build_tree_list (id, str);
		inputs = chainon (inputs, build_tree_list (arg, val));
	      }
	  }
      }

    /* Collect all clobber arguments.  */
    if (s->clobbers)
      {
	for (size_t i = 0; i < s->clobbers->length; i++)
	  {
	    StringExp *clobber = (*s->clobbers)[i]->toStringExp ();
	    const char *cstring = (const char *)(clobber->len
						 ? clobber->string : "");

	    tree val = build_string (clobber->len, cstring);
	    clobbers = chainon (clobbers, build_tree_list (0, val));
	  }
      }

    /* Collect all goto labels, these should have been already checked
       by the front-end, so pass down the label symbol to the back-end.  */
    if (s->labels)
      {
	for (size_t i = 0; i < s->labels->length; i++)
	  {
	    Identifier *ident = (*s->labels)[i];
	    GotoStatement *gs = (*s->gotos)[i];

	    gcc_assert (gs->label->statement != NULL);
	    gcc_assert (gs->tf == gs->label->statement->tf);

	    const char *sident = ident->toChars ();
	    tree name = build_string (strlen (sident), sident);
	    tree label = this->lookup_label (gs->label->statement,
					     gs->label->ident);
	    TREE_USED (label) = 1;

	    labels = chainon (labels, build_tree_list (name, label));
	  }
      }

    /* Do some extra validation on all input and output operands.  */
    const char *insnstring = (const char *)(insn->len ? insn->string : "");
    tree string = build_string (insn->len, insnstring);
    string = resolve_asm_operand_names (string, outputs, inputs, labels);

    if (s->args)
      {
	unsigned noutputs = s->outputargs;
	unsigned ninputs = (s->args->length - noutputs);
	const char **oconstraints = XALLOCAVEC (const char *, noutputs);
	bool allows_mem, allows_reg, is_inout;
	size_t i;
	tree t;

	for (i = 0, t = outputs; t != NULL_TREE; t = TREE_CHAIN (t), i++)
	  {
	    tree output = TREE_VALUE (t);
	    const char *constraint
	      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));

	    oconstraints[i] = constraint;

	    if (parse_output_constraint (&constraint, i, ninputs, noutputs,
					 &allows_mem, &allows_reg, &is_inout))
	      {
		/* If the output argument is going to end up in memory.  */
		if (!allows_reg)
		  d_mark_addressable (output);
	      }
	    else
	      output = error_mark_node;

	    TREE_VALUE (t) = output;
	  }

	for (i = 0, t = inputs; t != NULL_TREE; t = TREE_CHAIN (t), i++)
	  {
	    tree input = TREE_VALUE (t);
	    const char *constraint
	      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));

	    if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
					oconstraints, &allows_mem, &allows_reg))
	      {
		/* If the input argument is going to end up in memory.  */
		if (!allows_reg && allows_mem)
		  d_mark_addressable (input);
	      }
	    else
	      input = error_mark_node;

	    TREE_VALUE (t) = input;
	  }
      }

    tree exp = build5 (ASM_EXPR, void_type_node, string,
		       outputs, inputs, clobbers, labels);
    SET_EXPR_LOCATION (exp, make_location_t (s->loc));

    /* If the extended syntax was not used, mark the ASM_EXPR as being an
       ASM_INPUT expression instead of an ASM_OPERAND with no operands.  */
    if (s->args == NULL && s->clobbers == NULL)
      ASM_INPUT_P (exp) = 1;

    /* All asm statements are assumed to have a side effect.  As a future
       optimization, this could be unset when building in release mode.  */
    ASM_VOLATILE_P (exp) = 1;

    /* If the function has been annotated with `pragma(inline)', then mark
       the asm expression as being inline as well.  */
    if (this->func_->inlining == PINLINEalways)
      ASM_INLINE_P (exp) = 1;

    add_stmt (exp);
  }

  /* Import symbols from another module.  */

  void visit (ImportStatement *s)
  {
    if (s->imports == NULL)
      return;

    for (size_t i = 0; i < s->imports->length; i++)
      {
	Dsymbol *dsym = (*s->imports)[i];

	if (dsym != NULL)
	  build_decl_tree (dsym);
      }
  }
};

/* Main entry point for the IRVisitor interface to generate
   code for the body of function FD.  */

void
build_function_body (FuncDeclaration *fd)
{
  IRVisitor v = IRVisitor (fd);
  location_t saved_location = input_location;
  input_location = make_location_t (fd->loc);
  v.build_stmt (fd->fbody);
  input_location = saved_location;
}
