/* 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 (d_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;

	if (DotVarExp *dve = (s->exp->op == TOKcall
			      && s->exp->isCallExp ()->e1->op == TOKdotvar
			      ? s->exp->isCallExp ()->e1->isDotVarExp ()
			      : NULL))
	  {
	    sle = (dve->var->isCtorDeclaration ()
		   ? dve->e1->isStructLiteralExp () : NULL);
	  }
	else
	  sle = s->exp->isStructLiteralExp ();

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

	    /* 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));

	    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;
}
