/* toir.cc -- Lower D frontend statements to GCC trees.
   Copyright (C) 2006-2019 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 (OnScopeStatement *)
  {
  }

  /* 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->dim);
	vec<constructor_elt, va_gc> *elms = NULL;

	s->cases->sort ();

	for (size_t i = 0; i < s->cases->dim; 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->dim),
			      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->dim; 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 = (TypeFunction *)this->func_->type;
    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_->nrvo_can && this->func_->nrvo_var)
      {
	/* 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.  */
	tree decl = DECL_RESULT (get_symbol_decl (this->func_));
	add_stmt (return_expr (decl));
      }
    else
      {
	/* Convert for initializing the DECL_RESULT.  */
	tree expr = build_return_dtor (s->exp, type, tf);
	add_stmt (expr);
      }
  }

  /* 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->dim; 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->dim; 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->dim; 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 = (StringExp *)s->insn;
    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->dim; 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 = (StringExp *)(*s->constraints)[i];
	    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->dim; i++)
	  {
	    StringExp *clobber = (StringExp *)(*s->clobbers)[i];
	    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->dim; 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->dim - 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.  */
    if (s->args == NULL && s->clobbers == NULL)
      ASM_INPUT_P (exp) = 1;

    /* Asm statements are treated as volatile unless 'pure'.  */
    ASM_VOLATILE_P (exp) = !(s->stc & STCpure);

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