/* decl.cc -- Lower D frontend declarations to GCC trees.
   Copyright (C) 2006-2018 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/attrib.h"
#include "dmd/ctfe.h"
#include "dmd/declaration.h"
#include "dmd/enum.h"
#include "dmd/errors.h"
#include "dmd/globals.h"
#include "dmd/hdrgen.h"
#include "dmd/identifier.h"
#include "dmd/import.h"
#include "dmd/init.h"
#include "dmd/mangle.h"
#include "dmd/module.h"
#include "dmd/nspace.h"
#include "dmd/target.h"
#include "dmd/template.h"

#include "tree.h"
#include "tree-iterator.h"
#include "fold-const.h"
#include "diagnostic.h"
#include "langhooks.h"
#include "target.h"
#include "common/common-target.h"
#include "cgraph.h"
#include "toplev.h"
#include "stringpool.h"
#include "varasm.h"
#include "stor-layout.h"
#include "attribs.h"
#include "function.h"
#include "debug.h"
#include "tree-pretty-print.h"

#include "d-tree.h"


/* Return identifier for the external mangled name of DECL.  */

static const char *
mangle_decl (Dsymbol *decl)
{
  if (decl->isFuncDeclaration ())
    return mangleExact ((FuncDeclaration *)decl);
  else
    {
      OutBuffer buf;
      mangleToBuffer (decl, &buf);
      return buf.extractString ();
    }
}

/* Generate a mangled identifier using NAME and SUFFIX, prefixed by the
   assembler name for DECL.  */

tree
mangle_internal_decl (Dsymbol *decl, const char *name, const char *suffix)
{
  const char *prefix = mangle_decl (decl);
  unsigned namelen = strlen (name);
  unsigned buflen = (2 + strlen (prefix) + namelen + strlen (suffix)) * 2;
  char *buf = (char *) alloca (buflen);

  snprintf (buf, buflen, "_D%s%u%s%s", prefix, namelen, name, suffix);
  tree ident = get_identifier (buf);

  /* Symbol is not found in user code, but generate a readable name for it
     anyway for debug and diagnostic reporting.  */
  snprintf (buf, buflen, "%s.%s", decl->toPrettyChars (), name);
  IDENTIFIER_PRETTY_NAME (ident) = get_identifier (buf);

  return ident;
}

/* Returns true if DECL is from the gcc.attribute module.  */

static bool
gcc_attribute_p (Dsymbol *decl)
{
  ModuleDeclaration *md = decl->getModule ()->md;

  if (md && md->packages && md->packages->dim == 1)
    {
      if (!strcmp ((*md->packages)[0]->toChars (), "gcc")
	  && !strcmp (md->id->toChars (), "attribute"))
	return true;
    }

  return false;
}

/* Implements the visitor interface to lower all Declaration AST classes
   emitted from the D Front-end to GCC trees.
   All visit methods accept one parameter D, which holds the frontend AST
   of the declaration to compile.  These also don't return any value, instead
   generated code are appened to global_declarations or added to the
   current_binding_level by d_pushdecl().  */

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

public:
  DeclVisitor (void)
  {
  }

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

  void visit (Dsymbol *)
  {
  }

  /* Compile a D module, and all members of it.  */

  void visit (Module *d)
  {
    if (d->semanticRun >= PASSobj)
      return;

    build_module_tree (d);
    d->semanticRun = PASSobj;
  }

  /* Write the imported symbol to debug.  */

  void visit (Import *d)
  {
    /* Implements import declarations by telling the debug back-end we are
       importing the NAMESPACE_DECL of the module or IMPORTED_DECL of the
       declaration into the current lexical scope CONTEXT.  NAME is set if
       this is a renamed import.  */
    if (d->isstatic)
      return;

    /* Get the context of this import, this should never be null.  */
    tree context = d_module_context ();

    if (d->ident == NULL)
      {
	/* Importing declaration list.  */
	for (size_t i = 0; i < d->names.dim; i++)
	  {
	    AliasDeclaration *aliasdecl = d->aliasdecls[i];
	    tree decl = build_import_decl (aliasdecl);

	    /* Skip over unhandled imports.  */
	    if (decl == NULL_TREE)
	      continue;

	    Identifier *alias = d->aliases[i];
	    tree name = (alias != NULL)
	      ? get_identifier (alias->toChars ()) : NULL_TREE;

	    debug_hooks->imported_module_or_decl (decl, name, context,
						  false, false);
	  }
      }
    else
      {
	/* Importing the entire module.  */
	tree decl = build_import_decl (d->mod);

	tree name = (d->aliasId != NULL)
	  ? get_identifier (d->aliasId->toChars ()) : NULL_TREE;

	debug_hooks->imported_module_or_decl (decl, name, context,
					      false, false);
      }
  }

  /* Expand any local variables found in tuples.  */

  void visit (TupleDeclaration *d)
  {
    for (size_t i = 0; i < d->objects->dim; i++)
      {
	RootObject *o = (*d->objects)[i];
	if ((o->dyncast () == DYNCAST_EXPRESSION)
	    && ((Expression *) o)->op == TOKdsymbol)
	  {
	    Declaration *d = ((DsymbolExp *) o)->s->isDeclaration ();
	    if (d)
	      d->accept (this);
	  }
      }
  }

  /* Walk over all declarations in the attribute scope.  */

  void visit (AttribDeclaration *d)
  {
    Dsymbols *ds = d->include (NULL, NULL);

    if (!ds)
      return;

    for (size_t i = 0; i < ds->dim; i++)
      {
	Dsymbol *s = (*ds)[i];
	s->accept (this);
      }
  }

  /* Pragmas are a way to pass special information to the compiler and to add
     vendor specific extensions to D.  We don't do anything here, yet.  */

  void visit (PragmaDeclaration *d)
  {
    if (!global.params.ignoreUnsupportedPragmas)
      {
	if (d->ident == Identifier::idPool ("lib")
	    || d->ident == Identifier::idPool ("startaddress"))
	  {
	    warning_at (make_location_t (d->loc), OPT_Wunknown_pragmas,
			"pragma(%s) not implemented", d->ident->toChars ());
	  }
      }

    visit ((AttribDeclaration *) d);
  }

  /* Walk over all members in the namespace scope.  */

  void visit (Nspace *d)
  {
    if (isError (d) || !d->members)
      return;

    for (size_t i = 0; i < d->members->dim; i++)
      {
	Dsymbol *s = (*d->members)[i];
	s->accept (this);
      }
  }

  /* Walk over all members in the instantiated template.  */

  void visit (TemplateInstance *d)
  {
    if (isError (d)|| !d->members)
      return;

    if (!d->needsCodegen ())
      return;

    for (size_t i = 0; i < d->members->dim; i++)
      {
	Dsymbol *s = (*d->members)[i];
	s->accept (this);
      }
  }

  /* Walk over all members in the mixin template scope.  */

  void visit (TemplateMixin *d)
  {
    if (isError (d)|| !d->members)
      return;

    for (size_t i = 0; i < d->members->dim; i++)
      {
	Dsymbol *s = (*d->members)[i];
	s->accept (this);
      }
  }

  /* Write out compiler generated TypeInfo, initializer and functions for the
     given struct declaration, walking over all static members.  */

  void visit (StructDeclaration *d)
  {
    if (d->type->ty == Terror)
      {
	error_at (make_location_t (d->loc),
		  "had semantic errors when compiling");
	return;
      }

    /* Add this decl to the current binding level.  */
    tree ctype = build_ctype (d->type);
    if (TYPE_NAME (ctype))
      d_pushdecl (TYPE_NAME (ctype));

    /* Anonymous structs/unions only exist as part of others,
       do not output forward referenced structs.  */
    if (d->isAnonymous () || !d->members)
      return;

    /* Don't emit any symbols from gcc.attribute module.  */
    if (gcc_attribute_p (d))
      return;

    /* Generate TypeInfo.  */
    create_typeinfo (d->type, NULL);

    /* Generate static initializer.  */
    d->sinit = aggregate_initializer_decl (d);
    DECL_INITIAL (d->sinit) = layout_struct_initializer (d);

    if (d->isInstantiated ())
      d_linkonce_linkage (d->sinit);

    d_finish_decl (d->sinit);

    /* Put out the members.  */
    for (size_t i = 0; i < d->members->dim; i++)
      {
	Dsymbol *member = (*d->members)[i];
	/* There might be static ctors in the members, and they cannot
	   be put in separate object files.  */
	member->accept (this);
      }

    /* Put out xopEquals, xopCmp and xopHash.  */
    if (d->xeq && d->xeq != d->xerreq)
      d->xeq->accept (this);

    if (d->xcmp && d->xcmp != d->xerrcmp)
      d->xcmp->accept (this);

    if (d->xhash)
      d->xhash->accept (this);
  }

  /* Finish semantic analysis of functions in vtbl for class CD.  */

  bool finish_vtable (ClassDeclaration *d)
  {
    bool has_errors = false;

    /* Finish semantic analysis of functions in vtbl[].  */
    for (size_t i = d->vtblOffset (); i < d->vtbl.dim; i++)
      {
	FuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration ();

	if (!fd || (!fd->fbody && d->isAbstract ()))
	  continue;

	/* Ensure function has a return value.  */
	if (!fd->functionSemantic ())
	  has_errors = true;

	/* No name hiding to check for.  */
	if (!d->isFuncHidden (fd) || fd->isFuture ())
	  continue;

	/* The function fd is hidden from the view of the class.
	   If it overlaps with any function in the vtbl[], then
	   issue an error.  */
	for (size_t j = 1; j < d->vtbl.dim; j++)
	  {
	    if (j == i)
	      continue;

	    FuncDeclaration *fd2 = d->vtbl[j]->isFuncDeclaration ();
	    if (!fd2->ident->equals (fd->ident))
	      continue;

	    /* The function is marked as @__future, a deprecation has
	       already been given by the frontend.  */
	    if (fd2->isFuture ())
	      continue;

	    if (fd->leastAsSpecialized (fd2) || fd2->leastAsSpecialized (fd))
	      {
		TypeFunction *tf = (TypeFunction *) fd->type;
		if (tf->ty == Tfunction)
		  {
		    error_at (make_location_t (fd->loc), "use of %qs",
			      fd->toPrettyChars ());
		    inform (make_location_t (fd2->loc), "is hidden by %qs",
			    fd2->toPrettyChars ());
		    inform (make_location_t (d->loc),
			    "use %<alias %s = %s.%s;%> to introduce base class "
			    "overload set.", fd->toChars (),
			    fd->parent->toChars (), fd->toChars ());
		  }
		else
		  {
		    error_at (make_location_t (fd->loc), "use of %qs",
			      fd->toPrettyChars ());
		    inform (make_location_t (fd2->loc), "is hidden by %qs",
			      fd2->toPrettyChars ());
		  }

		has_errors = true;
		break;
	      }
	  }
      }

    return !has_errors;
  }

  /* Write out compiler generated TypeInfo, initializer and vtables for the
     given class declaration, walking over all static members.  */

  void visit (ClassDeclaration *d)
  {
    if (d->type->ty == Terror)
      {
	error_at (make_location_t (d->loc),
		  "had semantic errors when compiling");
	return;
      }

    if (!d->members)
      return;

    /* Put out the members.  */
    for (size_t i = 0; i < d->members->dim; i++)
      {
	Dsymbol *member = (*d->members)[i];
	member->accept (this);
      }

    /* If something goes wrong during final semantic pass, don't bother with
       the rest as we may have incomplete info.  */
    if (!this->finish_vtable (d))
      return;

    /* Generate C symbols.  */
    d->csym = get_classinfo_decl (d);
    d->vtblsym = get_vtable_decl (d);
    d->sinit = aggregate_initializer_decl (d);

    /* Generate static initializer.  */
    DECL_INITIAL (d->sinit) = layout_class_initializer (d);
    d_linkonce_linkage (d->sinit);
    d_finish_decl (d->sinit);

    /* Put out the TypeInfo.  */
    create_typeinfo (d->type, NULL);
    DECL_INITIAL (d->csym) = layout_classinfo (d);
    d_linkonce_linkage (d->csym);
    d_finish_decl (d->csym);

    /* Put out the vtbl[].  */
    vec<constructor_elt, va_gc> *elms = NULL;

    /* First entry is ClassInfo reference.  */
    if (d->vtblOffset ())
      CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, build_address (d->csym));

    for (size_t i = d->vtblOffset (); i < d->vtbl.dim; i++)
      {
	FuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration ();

	if (fd && (fd->fbody || !d->isAbstract()))
	  {
	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
				    build_address (get_symbol_decl (fd)));
	  }
      }

    DECL_INITIAL (d->vtblsym)
      = build_constructor (TREE_TYPE (d->vtblsym), elms);
    d_comdat_linkage (d->vtblsym);
    d_finish_decl (d->vtblsym);

    /* Add this decl to the current binding level.  */
    tree ctype = TREE_TYPE (build_ctype (d->type));
    if (TYPE_NAME (ctype))
      d_pushdecl (TYPE_NAME (ctype));
  }

  /* Write out compiler generated TypeInfo and vtables for the given interface
     declaration, walking over all static members.  */

  void visit (InterfaceDeclaration *d)
  {
    if (d->type->ty == Terror)
      {
	error_at (make_location_t (d->loc),
		  "had semantic errors when compiling");
	return;
      }

    if (!d->members)
      return;

    /* Put out the members.  */
    for (size_t i = 0; i < d->members->dim; i++)
      {
	Dsymbol *member = (*d->members)[i];
	member->accept (this);
      }

    /* Generate C symbols.  */
    d->csym = get_classinfo_decl (d);

    /* Put out the TypeInfo.  */
    create_typeinfo (d->type, NULL);
    d->type->vtinfo->accept (this);

    DECL_INITIAL (d->csym) = layout_classinfo (d);
    d_linkonce_linkage (d->csym);
    d_finish_decl (d->csym);

    /* Add this decl to the current binding level.  */
    tree ctype = TREE_TYPE (build_ctype (d->type));
    if (TYPE_NAME (ctype))
      d_pushdecl (TYPE_NAME (ctype));
  }

  /* Write out compiler generated TypeInfo and initializer for the given
     enum declaration.  */

  void visit (EnumDeclaration *d)
  {
    if (d->semanticRun >= PASSobj)
      return;

    if (d->errors || d->type->ty == Terror)
      {
	error_at (make_location_t (d->loc),
		  "had semantic errors when compiling");
	return;
      }

    if (d->isAnonymous ())
      return;

    /* Generate TypeInfo.  */
    create_typeinfo (d->type, NULL);

    TypeEnum *tc = (TypeEnum *) d->type;
    if (tc->sym->members && !d->type->isZeroInit ())
      {
	/* Generate static initializer.  */
	d->sinit = enum_initializer_decl (d);
	DECL_INITIAL (d->sinit) = build_expr (tc->sym->defaultval, true);

	if (d->isInstantiated ())
	  d_linkonce_linkage (d->sinit);

	d_finish_decl (d->sinit);

	/* Add this decl to the current binding level.  */
	tree ctype = build_ctype (d->type);
	if (TREE_CODE (ctype) == ENUMERAL_TYPE && TYPE_NAME (ctype))
	  d_pushdecl (TYPE_NAME (ctype));
      }

    d->semanticRun = PASSobj;
  }

  /* Finish up a variable declaration and push it into the current scope.
     This can either be a static, local or manifest constant.  */

  void visit (VarDeclaration *d)
  {
    if (d->type->ty == Terror)
      {
	error_at (make_location_t (d->loc),
		  "had semantic errors when compiling");
	return;
      }

    if (d->aliassym)
      {
	d->toAlias ()->accept (this);
	return;
      }

    /* Do not store variables we cannot take the address of,
       but keep the values for purposes of debugging.  */
    if (!d->canTakeAddressOf ())
      {
	/* Don't know if there is a good way to handle instantiations.  */
	if (d->isInstantiated ())
	  return;

	tree decl = get_symbol_decl (d);
	gcc_assert (d->_init && !d->_init->isVoidInitializer ());
	Expression *ie = initializerToExpression (d->_init);

	/* CONST_DECL was initially intended for enumerals and may be used for
	   scalars in general, but not for aggregates.  Here a non-constant
	   value is generated anyway so as the CONST_DECL only serves as a
	   placeholder for the value, however the DECL itself should never be
	   referenced in any generated code, or passed to the back-end.  */
	if (!d->type->isscalar ())
	  DECL_INITIAL (decl) = build_expr (ie, false);
	else
	  {
	    DECL_INITIAL (decl) = build_expr (ie, true);
	    d_pushdecl (decl);
	    rest_of_decl_compilation (decl, 1, 0);
	  }
      }
    else if (d->isDataseg () && !(d->storage_class & STCextern))
      {
	tree decl = get_symbol_decl (d);

	/* Duplicated VarDeclarations map to the same symbol.  Check if this
	   is the one declaration which will be emitted.  */
	tree ident = DECL_ASSEMBLER_NAME (decl);
	if (IDENTIFIER_DSYMBOL (ident) && IDENTIFIER_DSYMBOL (ident) != d)
	  return;

	/* How big a symbol can be should depend on back-end.  */
	tree size = build_integer_cst (d->type->size (d->loc),
				       build_ctype (Type::tsize_t));
	if (!valid_constant_size_p (size))
	  {
	    error_at (make_location_t (d->loc), "size is too large");
	    return;
	  }

	if (d->_init && !d->_init->isVoidInitializer ())
	  {
	    Expression *e = initializerToExpression (d->_init, d->type);
	    DECL_INITIAL (decl) = build_expr (e, true);
	  }
	else
	  {
	    if (d->type->ty == Tstruct)
	      {
		StructDeclaration *sd = ((TypeStruct *) d->type)->sym;
		DECL_INITIAL (decl) = layout_struct_initializer (sd);
	      }
	    else
	      {
		Expression *e = d->type->defaultInitLiteral (d->loc);
		DECL_INITIAL (decl) = build_expr (e, true);
	      }
	  }

	/* Frontend should have already caught this.  */
	gcc_assert (!integer_zerop (size)
		    || d->type->toBasetype ()->ty == Tsarray);

	d_finish_decl (decl);

	/* Maybe record the var against the current module.  */
	register_module_decl (d);
      }
    else if (!d->isDataseg () && !d->isMember ())
      {
	/* This is needed for VarDeclarations in mixins that are to be local
	   variables of a function.  Otherwise, it would be enough to make
	   a check for isVarDeclaration() in DeclarationExp codegen.  */
	declare_local_var (d);

	if (d->_init)
	  {
	    tree decl = get_symbol_decl (d);

	    if (!d->_init->isVoidInitializer ())
	      {
		ExpInitializer *vinit = d->_init->isExpInitializer ();
		Expression *ie = initializerToExpression (vinit);
		tree exp = build_expr (ie);

		/* Maybe put variable on list of things needing destruction.  */
		if (d->needsScopeDtor ())
		  {
		    vec_safe_push (d_function_chain->vars_in_scope, decl);
		    /* Force a TARGET_EXPR to add the corresponding cleanup.  */
		    exp = force_target_expr (compound_expr (exp, decl));
		    TARGET_EXPR_CLEANUP (exp) = build_expr (d->edtor);
		  }

		add_stmt (exp);
	      }
	    else if (d->size (d->loc) != 0)
	      {
		/* Zero-length arrays do not have an initializer.  */
		warning (OPT_Wuninitialized, "uninitialized variable '%s'",
			 d->ident ? d->ident->toChars () : "(no name)");
	      }
	  }
      }
  }

  /* Generate and compile a static TypeInfo declaration, but only if it is
     needed in the current compilation.  */

  void visit (TypeInfoDeclaration *d)
  {
    if (speculative_type_p (d->tinfo))
      return;

    tree t = get_typeinfo_decl (d);
    DECL_INITIAL (t) = layout_typeinfo (d);
    d_finish_decl (t);
  }

  /* Finish up a function declaration and compile it all the way
     down to assembler language output.  */

  void visit (FuncDeclaration *d)
  {
    /* Already generated the function.  */
    if (d->semanticRun >= PASSobj)
      return;

    /* Don't emit any symbols from gcc.attribute module.  */
    if (gcc_attribute_p (d))
      return;

    /* Not emitting unittest functions.  */
    if (!global.params.useUnitTests && d->isUnitTestDeclaration ())
      return;

    /* Check if any errors occurred when running semantic.  */
    if (d->type->ty == Tfunction)
      {
	TypeFunction *tf = (TypeFunction *) d->type;
	if (tf->next == NULL || tf->next->ty == Terror)
	  return;
      }

    if (d->semantic3Errors)
      return;

    if (d->isNested ())
      {
	FuncDeclaration *fdp = d;
	while (fdp && fdp->isNested ())
	  {
	    fdp = fdp->toParent2 ()->isFuncDeclaration ();

	    if (fdp == NULL)
	      break;

	    /* Parent failed to compile, but errors were gagged.  */
	    if (fdp->semantic3Errors)
	      return;
	  }
      }

    /* Ensure all semantic passes have run.  */
    if (d->semanticRun < PASSsemantic3)
      {
	d->functionSemantic3 ();
	Module::runDeferredSemantic3 ();
      }

    if (global.errors)
      return;

    /* Duplicated FuncDeclarations map to the same symbol.  Check if this
       is the one declaration which will be emitted.  */
    tree fndecl = get_symbol_decl (d);
    tree ident = DECL_ASSEMBLER_NAME (fndecl);
    if (IDENTIFIER_DSYMBOL (ident) && IDENTIFIER_DSYMBOL (ident) != d)
      return;

    if (!d->fbody)
      {
	rest_of_decl_compilation (fndecl, 1, 0);
	return;
      }

    if (global.params.verbose)
      message ("function  %s", d->toPrettyChars ());

    /* Start generating code for this function.  */
    gcc_assert (d->semanticRun == PASSsemantic3done);
    d->semanticRun = PASSobj;

    tree old_context = start_function (d);

    tree parm_decl = NULL_TREE;
    tree param_list = NULL_TREE;

    /* Special arguments...  */

    /* 'this' parameter:
       For nested functions, D still generates a vthis, but it
       should not be referenced in any expression.  */
    if (d->vthis)
      {
	parm_decl = get_symbol_decl (d->vthis);
	DECL_ARTIFICIAL (parm_decl) = 1;
	TREE_READONLY (parm_decl) = 1;

	if (d->vthis->type == Type::tvoidptr)
	  {
	    /* Replace generic pointer with back-end closure type
	       (this wins for gdb).  */
	    tree frame_type = FRAMEINFO_TYPE (get_frameinfo (d));
	    gcc_assert (frame_type != NULL_TREE);
	    TREE_TYPE (parm_decl) = build_pointer_type (frame_type);
	  }

	param_list = chainon (param_list, parm_decl);
	d_function_chain->static_chain = parm_decl;
      }

    /* _arguments parameter.  */
    if (d->v_arguments)
      {
	parm_decl = get_symbol_decl (d->v_arguments);
	param_list = chainon (param_list, parm_decl);
      }

    /* formal function parameters.  */
    size_t n_parameters = d->parameters ? d->parameters->dim : 0;

    for (size_t i = 0; i < n_parameters; i++)
      {
	VarDeclaration *param = (*d->parameters)[i];
	parm_decl = get_symbol_decl (param);
	/* Chain them in the correct order.  */
	param_list = chainon (param_list, parm_decl);
      }

    DECL_ARGUMENTS (fndecl) = param_list;
    rest_of_decl_compilation (fndecl, 1, 0);

    /* If this is a member function that nested (possibly indirectly) in another
       function, construct an expession for this member function's static chain
       by going through parent link of nested classes.  */
    if (d->isThis ())
      {
	AggregateDeclaration *ad = d->isThis ();
	tree this_tree = get_symbol_decl (d->vthis);

	while (ad->isNested ())
	  {
	    Dsymbol *pd = ad->toParent2 ();
	    tree vthis_field = get_symbol_decl (ad->vthis);
	    this_tree = component_ref (build_deref (this_tree), vthis_field);

	    ad = pd->isAggregateDeclaration ();
	    if (ad == NULL)
	      {
		cfun->language->static_chain = this_tree;
		break;
	      }
	  }
      }

    /* May change cfun->static_chain.  */
    build_closure (d);

    if (d->vresult)
      declare_local_var (d->vresult);

    if (d->v_argptr)
      push_stmt_list ();

    /* Named return value optimisation support for D.
       Implemented by overriding all the RETURN_EXPRs and replacing all
       occurrences of VAR with the RESULT_DECL for the function.
       This is only worth doing for functions that can return in memory.  */
    if (d->nrvo_can)
      {
	tree restype = TREE_TYPE (DECL_RESULT (fndecl));

	if (!AGGREGATE_TYPE_P (restype))
	  d->nrvo_can = 0;
	else
	  d->nrvo_can = aggregate_value_p (restype, fndecl);
      }

    if (d->nrvo_can)
      {
	tree resdecl = DECL_RESULT (fndecl);

	TREE_TYPE (resdecl)
	  = build_reference_type (TREE_TYPE (resdecl));
	DECL_BY_REFERENCE (resdecl) = 1;
	TREE_ADDRESSABLE (resdecl) = 0;
	relayout_decl (resdecl);

	if (d->nrvo_var)
	  {
	    tree var = get_symbol_decl (d->nrvo_var);

	    /* Copy name from VAR to RESULT.  */
	    DECL_NAME (resdecl) = DECL_NAME (var);
	    /* Don't forget that we take its address.  */
	    TREE_ADDRESSABLE (var) = 1;
	    resdecl = build_deref (resdecl);

	    SET_DECL_VALUE_EXPR (var, resdecl);
	    DECL_HAS_VALUE_EXPR_P (var) = 1;
	    SET_DECL_LANG_NRVO (var, resdecl);
	  }
      }

    build_function_body (d);

    /* Initialize the _argptr variable.  */
    if (d->v_argptr)
      {
	tree body = pop_stmt_list ();
	tree var = get_decl_tree (d->v_argptr);
	var = build_address (var);

	tree init = build_call_expr (builtin_decl_explicit (BUILT_IN_VA_START),
				     2, var, parm_decl);
	declare_local_var (d->v_argptr);
	add_stmt (init);

	tree cleanup = build_call_expr (builtin_decl_explicit (BUILT_IN_VA_END),
					1, var);
	add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, body, cleanup));
      }

    finish_function (old_context);

    /* Maybe record the function against the current module.  */
    register_module_decl (d);
  }
};

/* Main entry point for the DeclVisitor interface to send
   the Declaration AST class D to GCC back-end.  */

void
build_decl_tree (Dsymbol *d)
{
  location_t saved_location = input_location;

  /* Set input location, empty DECL_SOURCE_FILE can crash debug generator.  */
  if (d->loc.filename)
    input_location = make_location_t (d->loc);
  else
    input_location = make_location_t (Loc ("<no_file>", 1, 0));

  DeclVisitor v = DeclVisitor ();
  d->accept (&v);

  input_location = saved_location;
}

/* Return the decl for the symbol, create it if it doesn't already exist.  */

tree
get_symbol_decl (Declaration *decl)
{
  if (decl->csym)
    return decl->csym;

  /* Deal with placeholder symbols immediately:
     SymbolDeclaration is used as a shell around an initializer symbol.  */
  SymbolDeclaration *sd = decl->isSymbolDeclaration ();
  if (sd)
    {
      decl->csym = aggregate_initializer_decl (sd->dsym);
      return decl->csym;
    }

  /* Global static TypeInfo declaration.  */
  if (decl->isTypeInfoDeclaration ())
    return get_typeinfo_decl ((TypeInfoDeclaration *) decl);

  /* FuncAliasDeclaration is used to import functions from another scope.  */
  FuncAliasDeclaration *fad = decl->isFuncAliasDeclaration ();
  if (fad)
    {
      decl->csym = get_symbol_decl (fad->funcalias);
      return decl->csym;
    }

  /* It is possible for a field declaration symbol to be requested
     before the parent type has been built.  */
  if (decl->isField ())
    {
      AggregateDeclaration *ad = decl->toParent ()->isAggregateDeclaration ();
      gcc_assert (ad != NULL);

      /* Finishing off the type should create the associated FIELD_DECL.  */
      build_ctype (ad->type);
      gcc_assert (decl->csym != NULL);

      return decl->csym;
    }

  /* Build the tree for the symbol.  */
  FuncDeclaration *fd = decl->isFuncDeclaration ();
  if (fd)
    {
      /* Run full semantic on functions we need to know about.  */
      if (!fd->functionSemantic ())
	{
	  decl->csym = error_mark_node;
	  return decl->csym;
	}

      decl->csym = build_decl (make_location_t (decl->loc), FUNCTION_DECL,
			       get_identifier (decl->ident->toChars ()),
			       NULL_TREE);

      /* Set function type afterwards as there could be self references.  */
      TREE_TYPE (decl->csym) = build_ctype (fd->type);

      if (!fd->fbody)
	DECL_EXTERNAL (decl->csym) = 1;
    }
  else
    {
      /* Build the variable declaration.  */
      VarDeclaration *vd = decl->isVarDeclaration ();
      gcc_assert (vd != NULL);

      tree_code code = vd->isParameter () ? PARM_DECL
	: !vd->canTakeAddressOf () ? CONST_DECL
	: VAR_DECL;
      decl->csym = build_decl (make_location_t (decl->loc), code,
			       get_identifier (decl->ident->toChars ()),
			       declaration_type (vd));

      /* If any alignment was set on the declaration.  */
      if (vd->alignment != STRUCTALIGN_DEFAULT)
	{
	  SET_DECL_ALIGN (decl->csym, vd->alignment * BITS_PER_UNIT);
	  DECL_USER_ALIGN (decl->csym) = 1;
	}

      if (vd->storage_class & STCextern)
	DECL_EXTERNAL (decl->csym) = 1;
    }

  /* Set the declaration mangled identifier if static.  */
  if (decl->isCodeseg () || decl->isDataseg ())
    {
      tree mangled_name;

      if (decl->mangleOverride)
	mangled_name = get_identifier (decl->mangleOverride);
      else
	mangled_name = get_identifier (mangle_decl (decl));

      mangled_name = targetm.mangle_decl_assembler_name (decl->csym,
							 mangled_name);
      /* The frontend doesn't handle duplicate definitions of unused symbols
	 with the same mangle.  So a check is done here instead.  */
      if (!DECL_EXTERNAL (decl->csym))
	{
	  if (IDENTIFIER_DSYMBOL (mangled_name))
	    {
	      Declaration *other = IDENTIFIER_DSYMBOL (mangled_name);

	      /* Non-templated variables shouldn't be defined twice.  */
	      if (!decl->isInstantiated ())
		ScopeDsymbol::multiplyDefined (decl->loc, decl, other);

	      decl->csym = get_symbol_decl (other);
	      return decl->csym;
	    }

	  IDENTIFIER_PRETTY_NAME (mangled_name)
	    = get_identifier (decl->toPrettyChars (true));
	  IDENTIFIER_DSYMBOL (mangled_name) = decl;
	}

      SET_DECL_ASSEMBLER_NAME (decl->csym, mangled_name);
    }

  DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (decl);
  DECL_CONTEXT (decl->csym) = d_decl_context (decl);

  if (TREE_CODE (decl->csym) == PARM_DECL)
    {
      /* Pass non-trivial structs by invisible reference.  */
      if (TREE_ADDRESSABLE (TREE_TYPE (decl->csym)))
	{
	  tree argtype = build_reference_type (TREE_TYPE (decl->csym));
	  argtype = build_qualified_type (argtype, TYPE_QUAL_RESTRICT);
	  gcc_assert (!DECL_BY_REFERENCE (decl->csym));
	  TREE_TYPE (decl->csym) = argtype;
	  DECL_BY_REFERENCE (decl->csym) = 1;
	  TREE_ADDRESSABLE (decl->csym) = 0;
	  relayout_decl (decl->csym);
	  decl->storage_class |= STCref;
	}

      DECL_ARG_TYPE (decl->csym) = TREE_TYPE (decl->csym);
      gcc_assert (TREE_CODE (DECL_CONTEXT (decl->csym)) == FUNCTION_DECL);
    }
  else if (TREE_CODE (decl->csym) == CONST_DECL)
    {
      /* Manifest constants have no address in memory.  */
      TREE_CONSTANT (decl->csym) = 1;
      TREE_READONLY (decl->csym) = 1;
    }
  else if (TREE_CODE (decl->csym) == FUNCTION_DECL)
    {
      /* The real function type may differ from its declaration.  */
      tree fntype = TREE_TYPE (decl->csym);
      tree newfntype = NULL_TREE;

      if (fd->isNested ())
	{
	  /* Add an extra argument for the frame/closure pointer, this is also
	     required to be compatible with D delegates.  */
	  newfntype = build_vthis_function (void_type_node, fntype);
	}
      else if (fd->isThis ())
	{
	  /* Add an extra argument for the 'this' parameter.  The handle type is
	     used even if there is no debug info.  It is needed to make sure
	     virtual member functions are not called statically.  */
	  AggregateDeclaration *ad = fd->isMember2 ();
	  tree handle = build_ctype (ad->handleType ());

	  /* If handle is a pointer type, get record type.  */
	  if (!ad->isStructDeclaration ())
	    handle = TREE_TYPE (handle);

	  newfntype = build_vthis_function (handle, fntype);

	  /* Set the vindex on virtual functions.  */
	  if (fd->isVirtual () && fd->vtblIndex != -1)
	    {
	      DECL_VINDEX (decl->csym) = size_int (fd->vtblIndex);
	      DECL_VIRTUAL_P (decl->csym) = 1;
	    }
	}
      else if (fd->isMain () || fd->isCMain ())
	{
	  /* The main function is named 'D main' to distinguish from C main.  */
	  if (fd->isMain ())
	    DECL_NAME (decl->csym) = get_identifier (fd->toPrettyChars (true));

	  /* 'void main' is implicitly converted to returning an int.  */
	  newfntype = build_function_type (d_int_type, TYPE_ARG_TYPES (fntype));
	}

      if (newfntype != NULL_TREE)
	{
	  /* Copy the old attributes from the original type.  */
	  TYPE_ATTRIBUTES (newfntype) = TYPE_ATTRIBUTES (fntype);
	  TYPE_LANG_SPECIFIC (newfntype) = TYPE_LANG_SPECIFIC (fntype);
	  TREE_ADDRESSABLE (newfntype) = TREE_ADDRESSABLE (fntype);
	  TREE_TYPE (decl->csym) = newfntype;
	  d_keep (newfntype);
	}

      /* Miscellaneous function flags.  */
      if (fd->isMember2 () || fd->isFuncLiteralDeclaration ())
	{
	  /* See grokmethod in cp/decl.c.  Maybe we shouldn't be setting inline
	     flags without reason or proper handling.  */
	  DECL_DECLARED_INLINE_P (decl->csym) = 1;
	  DECL_NO_INLINE_WARNING_P (decl->csym) = 1;
	}

      /* Function was declared 'naked'.  */
      if (fd->naked)
	{
	  insert_decl_attribute (decl->csym, "naked");
	  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl->csym) = 1;
	}

      /* Vector array operations are always compiler generated.  */
      if (fd->isArrayOp)
	{
	  TREE_PUBLIC (decl->csym) = 1;
	  DECL_ARTIFICIAL (decl->csym) = 1;
	  DECL_DECLARED_INLINE_P (decl->csym) = 1;
	  d_comdat_linkage (decl->csym);
	}

      /* And so are ensure and require contracts.  */
      if (fd->ident == Identifier::idPool ("ensure")
	  || fd->ident == Identifier::idPool ("require"))
	{
	  DECL_ARTIFICIAL (decl->csym) = 1;
	  TREE_PUBLIC (decl->csym) = 1;
	}

      if (decl->storage_class & STCfinal)
	DECL_FINAL_P (decl->csym) = 1;

      /* Check whether this function is expanded by the frontend.  */
      DECL_INTRINSIC_CODE (decl->csym) = INTRINSIC_NONE;
      maybe_set_intrinsic (fd);

      /* For nested functions in particular, unnest fndecl in the cgraph, as
	 all static chain passing is handled by the front-end.  Do this even
	 if we are not emitting the body.  */
      struct cgraph_node *node = cgraph_node::get_create (decl->csym);
      if (node->origin)
	node->unnest ();
    }

  /* Mark compiler generated temporaries as artificial.  */
  if (decl->storage_class & STCtemp)
    DECL_ARTIFICIAL (decl->csym) = 1;

  /* Propagate shared on the decl.  */
  if (TYPE_SHARED (TREE_TYPE (decl->csym)))
    TREE_ADDRESSABLE (decl->csym) = 1;

  /* Symbol was marked volatile.  */
  if (decl->storage_class & STCvolatile)
    TREE_THIS_VOLATILE (decl->csym) = 1;

  /* Protection attributes are used by the debugger.  */
  if (decl->protection.kind == PROTprivate)
    TREE_PRIVATE (decl->csym) = 1;
  else if (decl->protection.kind == PROTprotected)
    TREE_PROTECTED (decl->csym) = 1;

  /* Likewise, so could the deprecated attribute.  */
  if (decl->storage_class & STCdeprecated)
    TREE_DEPRECATED (decl->csym) = 1;

#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
  /* Have to test for import first.  */
  if (decl->isImportedSymbol ())
    {
      insert_decl_attribute (decl->csym, "dllimport");
      DECL_DLLIMPORT_P (decl->csym) = 1;
    }
  else if (decl->isExport ())
    insert_decl_attribute (decl->csym, "dllexport");
#endif

  if (decl->isDataseg () || decl->isCodeseg () || decl->isThreadlocal ())
    {
      /* Set TREE_PUBLIC by default, but allow private template to override.  */
      if (!fd || !fd->isNested ())
	TREE_PUBLIC (decl->csym) = 1;

      TREE_STATIC (decl->csym) = 1;
      /* The decl has not been defined -- yet.  */
      DECL_EXTERNAL (decl->csym) = 1;

      if (decl->isInstantiated ())
	d_linkonce_linkage (decl->csym);
    }

  /* Symbol is going in thread local storage.  */
  if (decl->isThreadlocal () && !DECL_ARTIFICIAL (decl->csym))
    {
      if (global.params.vtls)
	message (decl->loc, "`%s` is thread local", decl->toChars ());

      set_decl_tls_model (decl->csym, decl_default_tls_model (decl->csym));
    }

  /* Apply any user attributes that may affect semantic meaning.  */
  if (decl->userAttribDecl)
    {
      Expressions *attrs = decl->userAttribDecl->getAttributes ();
      decl_attributes (&decl->csym, build_attributes (attrs), 0);
    }
  else if (DECL_ATTRIBUTES (decl->csym) != NULL)
    decl_attributes (&decl->csym, DECL_ATTRIBUTES (decl->csym), 0);

  /* %% Probably should be a little more intelligent about setting this.  */
  TREE_USED (decl->csym) = 1;
  d_keep (decl->csym);

  return decl->csym;
}

/* Returns a declaration for a VAR_DECL.  Used to create compiler-generated
   global variables.  */

tree
declare_extern_var (tree ident, tree type)
{
  /* If the VAR_DECL has already been declared, return it.  */
  if (IDENTIFIER_DECL_TREE (ident))
    return IDENTIFIER_DECL_TREE (ident);

  tree name = IDENTIFIER_PRETTY_NAME (ident)
    ? IDENTIFIER_PRETTY_NAME (ident) : ident;
  tree decl = build_decl (input_location, VAR_DECL, name, type);

  IDENTIFIER_DECL_TREE (ident) = decl;
  d_keep (decl);

  SET_DECL_ASSEMBLER_NAME (decl, ident);
  DECL_ARTIFICIAL (decl) = 1;
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 1;

  /* The decl has not been defined -- yet.  */
  DECL_EXTERNAL (decl) = 1;

  return decl;
}

/* Add local variable VAR into the current function body.  */

void
declare_local_var (VarDeclaration *var)
{
  gcc_assert (!var->isDataseg () && !var->isMember ());
  gcc_assert (current_function_decl != NULL_TREE);

  FuncDeclaration *fd = cfun->language->function;
  tree decl = get_symbol_decl (var);

  gcc_assert (!TREE_STATIC (decl));
  d_pushdecl (decl);
  DECL_CONTEXT (decl) = current_function_decl;

  /* Compiler generated symbols.  */
  if (var == fd->vresult || var == fd->v_argptr)
    DECL_ARTIFICIAL (decl) = 1;

  if (DECL_LANG_FRAME_FIELD (decl))
    {
      /* Fixes debugging local variables.  */
      SET_DECL_VALUE_EXPR (decl, get_decl_tree (var));
      DECL_HAS_VALUE_EXPR_P (decl) = 1;
    }
}

/* Return an unnamed local temporary of type TYPE.  */

tree
build_local_temp (tree type)
{
  tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, type);

  DECL_CONTEXT (decl) = current_function_decl;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  d_pushdecl (decl);

  return decl;
}

/* Return the correct decl to be used for DECL.  For VAR_DECLs, this could
   instead be a FIELD_DECL from a closure, or a RESULT_DECL from a named return
   value.  For PARM_DECLs, this could be a FIELD_DECL for a non-local `this'.
   For all other kinds of decls, this just returns the result of
   get_symbol_decl().  */

tree
get_decl_tree (Declaration *decl)
{
  tree t = get_symbol_decl (decl);
  FuncDeclaration *fd = cfun ? cfun->language->function : NULL;
  VarDeclaration *vd = decl->isVarDeclaration ();

  /* If cfun is NULL, then this is a global static.  */
  if (vd == NULL || fd == NULL)
    return t;

  /* Get the named return value.  */
  if (DECL_LANG_NRVO (t))
    return DECL_LANG_NRVO (t);

  /* Get the closure holding the var decl.  */
  if (DECL_LANG_FRAME_FIELD (t))
    {
      FuncDeclaration *parent = vd->toParent2 ()->isFuncDeclaration ();
      tree frame_ref = get_framedecl (fd, parent);

      return component_ref (build_deref (frame_ref),
			    DECL_LANG_FRAME_FIELD (t));
    }

  /* Get the non-local 'this' value by going through parent link
     of nested classes, this routine pretty much undoes what
     getRightThis in the frontend removes from codegen.  */
  if (vd->parent != fd && vd->isThisDeclaration ())
    {
      /* Find the first parent that is a member function.  */
      while (!fd->isMember2 ())
	{
	  gcc_assert (fd->vthis);
	  fd = fd->toParent2 ()->isFuncDeclaration ();
	  gcc_assert (fd != NULL);
	}

      AggregateDeclaration *ad = fd->isThis ();
      gcc_assert (ad != NULL);

      t = get_decl_tree (fd->vthis);
      Dsymbol *outer = fd;

      while (outer != vd->parent)
	{
	  gcc_assert (ad != NULL);
	  outer = ad->toParent2 ();

	  /* Get the this->this parent link.  */
	  tree vfield = get_symbol_decl (ad->vthis);
	  t = component_ref (build_deref (t), vfield);

	  ad = outer->isAggregateDeclaration ();
	  if (ad != NULL)
	    continue;

	  fd = outer->isFuncDeclaration ();
	  while (fd != NULL)
	    {
	      /* If outer function creates a closure, then the 'this'
		 value would be the closure pointer, and the real
		 'this' the first field of that closure.  */
	      tree ff = get_frameinfo (fd);
	      if (FRAMEINFO_CREATES_FRAME (ff))
		{
		  t = build_nop (build_pointer_type (FRAMEINFO_TYPE (ff)), t);
		  t = indirect_ref (build_ctype (fd->vthis->type), t);
		}

	      if (fd == vd->parent)
		break;

	      /* Continue looking for the right `this'.  */
	      outer = outer->toParent2 ();
	      fd = outer->isFuncDeclaration ();
	    }

	  ad = outer->isAggregateDeclaration ();
	}

      return t;
    }

  /* Auto variable that the back end will handle for us.  */
  return t;
}

/* Finish up a variable declaration and compile it all the way to
   the assembler language output.  */

void
d_finish_decl (tree decl)
{
  gcc_assert (!error_operand_p (decl));

  /* We are sending this symbol to object file, can't be extern.  */
  TREE_STATIC (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  /* Update the TLS model as the linkage has been modified.  */
  if (DECL_THREAD_LOCAL_P (decl))
    set_decl_tls_model (decl, decl_default_tls_model (decl));

  relayout_decl (decl);

  if (flag_checking && DECL_INITIAL (decl))
    {
      /* Initializer must never be bigger than symbol size.  */
      dinteger_t tsize = int_size_in_bytes (TREE_TYPE (decl));
      dinteger_t dtsize = int_size_in_bytes (TREE_TYPE (DECL_INITIAL (decl)));

      if (tsize < dtsize)
	{
	  tree name = DECL_ASSEMBLER_NAME (decl);

	  internal_error ("Mismatch between declaration %qE size (%wd) and "
			  "its initializer size (%wd).",
			  IDENTIFIER_PRETTY_NAME (name)
			  ? IDENTIFIER_PRETTY_NAME (name) : name,
			  tsize, dtsize);
	}
    }

  /* Without weak symbols, symbol should be put in .common, but that can't
     be done if there is a nonzero initializer.  */
  if (DECL_COMDAT (decl) && DECL_COMMON (decl)
      && initializer_zerop (DECL_INITIAL (decl)))
    DECL_INITIAL (decl) = error_mark_node;

  /* Add this decl to the current binding level.  */
  d_pushdecl (decl);

  rest_of_decl_compilation (decl, 1, 0);
}

/* Thunk code is based on g++.  */

static int thunk_labelno;

/* Create a static alias to function.  */

static tree
make_alias_for_thunk (tree function)
{
  tree alias;
  char buf[256];

  /* Thunks may reference extern functions which cannot be aliased.  */
  if (DECL_EXTERNAL (function))
    return function;

  targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno);
  thunk_labelno++;

  alias = build_decl (DECL_SOURCE_LOCATION (function), FUNCTION_DECL,
		      get_identifier (buf), TREE_TYPE (function));
  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
  lang_hooks.dup_lang_specific_decl (alias);
  DECL_CONTEXT (alias) = NULL_TREE;
  TREE_READONLY (alias) = TREE_READONLY (function);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);
  TREE_PUBLIC (alias) = 0;

  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;

  DECL_DECLARED_INLINE_P (alias) = 0;
  DECL_INITIAL (alias) = error_mark_node;
  DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (function));

  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));

  if (!flag_syntax_only)
    {
      cgraph_node *aliasn;
      aliasn = cgraph_node::create_same_body_alias (alias, function);
      gcc_assert (aliasn != NULL);
    }
  return alias;
}

/* Emit the definition of a D vtable thunk.  */

static void
finish_thunk (tree thunk, tree function)
{
  /* Setup how D thunks are outputted.  */
  int fixed_offset = -THUNK_LANG_OFFSET (thunk);
  bool this_adjusting = true;
  tree alias;

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
    alias = make_alias_for_thunk (function);
  else
    alias = function;

  TREE_ADDRESSABLE (function) = 1;
  TREE_USED (function) = 1;

  if (flag_syntax_only)
    {
      TREE_ASM_WRITTEN (thunk) = 1;
      return;
    }

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
      && targetm_common.have_named_sections)
    {
      tree fn = function;
      symtab_node *symbol = symtab_node::get (function);

      if (symbol != NULL && symbol->alias)
	{
	  if (symbol->analyzed)
	    fn = symtab_node::get (function)->ultimate_alias_target ()->decl;
	  else
	    fn = symtab_node::get (function)->alias_target;
	}
      resolve_unique_section (fn, 0, flag_function_sections);

      if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn))
	{
	  resolve_unique_section (thunk, 0, flag_function_sections);

	  /* Output the thunk into the same section as function.  */
	  set_decl_section_name (thunk, DECL_SECTION_NAME (fn));
	  symtab_node::get (thunk)->implicit_section
	    = symtab_node::get (fn)->implicit_section;
	}
    }

  /* Set up cloned argument trees for the thunk.  */
  tree t = NULL_TREE;
  for (tree a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))
    {
      tree x = copy_node (a);
      DECL_CHAIN (x) = t;
      DECL_CONTEXT (x) = thunk;
      SET_DECL_RTL (x, NULL);
      DECL_HAS_VALUE_EXPR_P (x) = 0;
      TREE_ADDRESSABLE (x) = 0;
      t = x;
    }
  DECL_ARGUMENTS (thunk) = nreverse (t);
  TREE_ASM_WRITTEN (thunk) = 1;

  cgraph_node *funcn, *thunk_node;

  funcn = cgraph_node::get_create (function);
  gcc_assert (funcn);
  thunk_node = funcn->create_thunk (thunk, thunk, this_adjusting,
				    fixed_offset, 0, 0, 0, alias);

  if (DECL_ONE_ONLY (function))
    thunk_node->add_to_same_comdat_group (funcn);

  /* Target assemble_mi_thunk doesn't work across section boundaries
     on many targets, instead force thunk to be expanded in gimple.  */
  if (DECL_EXTERNAL (function))
    {
      /* cgraph::expand_thunk writes over current_function_decl, so if this
	 could ever be in use by the codegen pass, we want to know about it.  */
      gcc_assert (current_function_decl == NULL_TREE);

      if (!stdarg_p (TREE_TYPE (thunk)))
	{
	  thunk_node->create_edge (funcn, NULL, thunk_node->count);
	  thunk_node->expand_thunk (false, true);
	}

      /* Tell the back-end to not bother inlining the function, this is
	 assumed not to work as it could be referencing symbols outside
	 of the current compilation unit.  */
      DECL_UNINLINABLE (function) = 1;
    }
}

/* Return a thunk to DECL.  Thunks adjust the incoming `this' pointer by OFFSET.
   Adjustor thunks are created and pointers to them stored in the method entries
   in the vtable in order to set the this pointer to the start of the object
   instance corresponding to the implementing method.  */

tree
make_thunk (FuncDeclaration *decl, int offset)
{
  tree function = get_symbol_decl (decl);

  if (!DECL_ARGUMENTS (function) || !DECL_RESULT (function))
    {
      /* Compile the function body before generating the thunk, this is done
	 even if the decl is external to the current module.  */
      if (decl->fbody)
	build_decl_tree (decl);
      else
	{
	  /* Build parameters for functions that are not being compiled,
	     so that they can be correctly cloned in finish_thunk.  */
	  tree fntype = TREE_TYPE (function);
	  tree params = NULL_TREE;

	  for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
	    {
	      if (t == void_list_node)
		break;

	      tree param = build_decl (DECL_SOURCE_LOCATION (function),
				       PARM_DECL, NULL_TREE, TREE_VALUE (t));
	      DECL_ARG_TYPE (param) = TREE_TYPE (param);
	      DECL_ARTIFICIAL (param) = 1;
	      DECL_IGNORED_P (param) = 1;
	      DECL_CONTEXT (param) = function;
	      params = chainon (params, param);
	    }

	  DECL_ARGUMENTS (function) = params;

	  /* Also build the result decl, which is needed when force creating
	     the thunk in gimple inside cgraph_node::expand_thunk.  */
	  tree resdecl = build_decl (DECL_SOURCE_LOCATION (function),
				     RESULT_DECL, NULL_TREE,
				     TREE_TYPE (fntype));
	  DECL_ARTIFICIAL (resdecl) = 1;
	  DECL_IGNORED_P (resdecl) = 1;
	  DECL_CONTEXT (resdecl) = function;
	  DECL_RESULT (function) = resdecl;
	}
    }

  /* Don't build the thunk if the compilation step failed.  */
  if (global.errors)
    return error_mark_node;

  /* See if we already have the thunk in question.  */
  for (tree t = DECL_LANG_THUNKS (function); t; t = DECL_CHAIN (t))
    {
      if (THUNK_LANG_OFFSET (t) == offset)
	return t;
    }

  tree thunk = build_decl (DECL_SOURCE_LOCATION (function),
			   FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
  DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
  lang_hooks.dup_lang_specific_decl (thunk);
  THUNK_LANG_OFFSET (thunk) = offset;

  TREE_READONLY (thunk) = TREE_READONLY (function);
  TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
  TREE_NOTHROW (thunk) = TREE_NOTHROW (function);

  DECL_CONTEXT (thunk) = d_decl_context (decl);

  /* Thunks inherit the public access of the function they are targetting.  */
  TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
  DECL_EXTERNAL (thunk) = 0;

  /* Thunks are always addressable.  */
  TREE_ADDRESSABLE (thunk) = 1;
  TREE_USED (thunk) = 1;
  DECL_ARTIFICIAL (thunk) = 1;
  DECL_DECLARED_INLINE_P (thunk) = 0;

  DECL_VISIBILITY (thunk) = DECL_VISIBILITY (function);
  DECL_COMDAT (thunk) = DECL_COMDAT (function);
  DECL_WEAK (thunk) = DECL_WEAK (function);

  tree target_name = DECL_ASSEMBLER_NAME (function);
  unsigned identlen = IDENTIFIER_LENGTH (target_name) + 14;
  const char *ident = XNEWVEC (const char, identlen);
  snprintf (CONST_CAST (char *, ident), identlen,
	    "_DT%u%s", offset, IDENTIFIER_POINTER (target_name));

  DECL_NAME (thunk) = get_identifier (ident);
  SET_DECL_ASSEMBLER_NAME (thunk, DECL_NAME (thunk));

  d_keep (thunk);

  finish_thunk (thunk, function);

  /* Add it to the list of thunks associated with the function.  */
  DECL_LANG_THUNKS (thunk) = NULL_TREE;
  DECL_CHAIN (thunk) = DECL_LANG_THUNKS (function);
  DECL_LANG_THUNKS (function) = thunk;

  return thunk;
}

/* Create the FUNCTION_DECL for a function definition.
   This function creates a binding context for the function body
   as well as setting up the FUNCTION_DECL in current_function_decl.
   Returns the previous function context if it was already set.  */

tree
start_function (FuncDeclaration *fd)
{
  tree fndecl = get_symbol_decl (fd);

  /* Function has been defined, check now whether we intend to send it to
     object file, or it really is extern.  Such as inlinable functions from
     modules not in this compilation, or thunk aliases.  */
  TemplateInstance *ti = fd->isInstantiated ();
  if (ti && ti->needsCodegen ())
    {
      /* Warn about templates instantiated in this compilation.  */
      if (ti == fd->parent)
	{
	  warning (OPT_Wtemplates, "%s %qs instantiated",
		   ti->kind (), ti->toPrettyChars (false));
	}

      DECL_EXTERNAL (fndecl) = 0;
    }
  else
    {
      Module *md = fd->getModule ();
      if (md && md->isRoot ())
	DECL_EXTERNAL (fndecl) = 0;
    }

  DECL_INITIAL (fndecl) = error_mark_node;

  /* Add this decl to the current binding level.  */
  d_pushdecl (fndecl);

  /* Save the current function context.  */
  tree old_context = current_function_decl;

  if (old_context)
    push_function_context ();

  /* Let GCC know the current scope is this function.  */
  current_function_decl = fndecl;

  tree restype = TREE_TYPE (TREE_TYPE (fndecl));
  tree resdecl = build_decl (make_location_t (fd->loc), RESULT_DECL,
			     NULL_TREE, restype);

  DECL_RESULT (fndecl) = resdecl;
  DECL_CONTEXT (resdecl) = fndecl;
  DECL_ARTIFICIAL (resdecl) = 1;
  DECL_IGNORED_P (resdecl) = 1;

  /* Initialize the RTL code for the function.  */
  allocate_struct_function (fndecl, false);

  /* Store the end of the function.  */
  if (fd->endloc.filename)
    cfun->function_end_locus = make_location_t (fd->endloc);
  else
    cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl);

  cfun->language = ggc_cleared_alloc<language_function> ();
  cfun->language->function = fd;

  /* Default chain value is 'null' unless parent found.  */
  cfun->language->static_chain = null_pointer_node;

  /* Find module for this function.  */
  for (Dsymbol *p = fd->parent; p != NULL; p = p->parent)
    {
      cfun->language->module = p->isModule ();
      if (cfun->language->module)
	break;
    }
  gcc_assert (cfun->language->module != NULL);

  /* Begin the statement tree for this function.  */
  push_stmt_list ();
  push_binding_level (level_function);

  return old_context;
}

/* Finish up a function declaration and compile that function all
   the way to assembler language output.  The free the storage for
   the function definition.  Restores the previous function context.  */

void
finish_function (tree old_context)
{
  tree fndecl = current_function_decl;

  /* Tie off the statement tree for this function.  */
  tree block = pop_binding_level ();
  tree body = pop_stmt_list ();
  tree bind = build3 (BIND_EXPR, void_type_node,
		      BLOCK_VARS (block), body, block);

  gcc_assert (vec_safe_is_empty (d_function_chain->stmt_list));

  /* Back-end expects a statement list to come from somewhere, however
     pop_stmt_list returns expressions when there is a single statement.
     So here we create a statement list unconditionally.  */
  if (TREE_CODE (body) != STATEMENT_LIST)
    {
      tree stmtlist = alloc_stmt_list ();
      append_to_statement_list_force (body, &stmtlist);
      BIND_EXPR_BODY (bind) = stmtlist;
    }
  else if (!STATEMENT_LIST_HEAD (body))
    {
      /* For empty functions add a void return.  */
      append_to_statement_list_force (return_expr (NULL_TREE), &body);
    }

  DECL_SAVED_TREE (fndecl) = bind;

  if (!errorcount && !global.errors)
    {
      /* Dump the D-specific tree IR.  */
      dump_function (TDI_original, fndecl);

      cgraph_node::finalize_function (fndecl, true);
    }

  /* We're leaving the context of this function, so free it.  */
  ggc_free (cfun->language);
  cfun->language = NULL;
  set_cfun (NULL);

  if (old_context)
    pop_function_context ();

  current_function_decl = old_context;
}

/* Mark DECL, which is a VAR_DECL or FUNCTION_DECL as a symbol that
   must be emitted in this, output module.  */

void
mark_needed (tree decl)
{
  TREE_USED (decl) = 1;

  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      struct cgraph_node *node = cgraph_node::get_create (decl);
      node->forced_by_abi = true;
    }
  else if (VAR_P (decl))
    {
      struct varpool_node *node = varpool_node::get_create (decl);
      node->forced_by_abi = true;
    }
}

/* Get the offset to the BC's vtbl[] initializer from the start of CD.
   Returns "~0u" if the base class is not found in any vtable interfaces.  */

unsigned
base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
{
  unsigned csymoffset = Target::classinfosize;
  unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
  csymoffset += cd->vtblInterfaces->dim * interfacesize;

  for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
    {
      BaseClass *b = (*cd->vtblInterfaces)[i];
      if (b == bc)
	return csymoffset;
      csymoffset += b->sym->vtbl.dim * Target::ptrsize;
    }

  /* Check all overriding interface vtbl[]s.  */
  for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)
    {
      for (size_t k = 0; k < cd2->vtblInterfaces->dim; k++)
	{
	  BaseClass *bs = (*cd2->vtblInterfaces)[k];
	  if (bs->fillVtbl (cd, NULL, 0))
	    {
	      if (bc == bs)
		return csymoffset;
	      csymoffset += bs->sym->vtbl.dim * Target::ptrsize;
	    }
	}
    }

  return ~0u;
}

/* Get the VAR_DECL of the vtable symbol for DECL.  If this does not yet exist,
   create it.  The vtable is accessible via ClassInfo, but since it is needed
   frequently (like for rtti comparisons), make it directly accessible.  */

tree
get_vtable_decl (ClassDeclaration *decl)
{
  if (decl->vtblsym)
    return decl->vtblsym;

  tree ident = mangle_internal_decl (decl, "__vtbl", "Z");
  /* Note: Using a static array type for the VAR_DECL, the DECL_INITIAL value
     will have a different type.  However the back-end seems to accept this.  */
  tree type = build_ctype (Type::tvoidptr->sarrayOf (decl->vtbl.dim));

  decl->vtblsym = declare_extern_var (ident, type);
  DECL_LANG_SPECIFIC (decl->vtblsym) = build_lang_decl (NULL);

  /* Class is a reference, want the record type.  */
  DECL_CONTEXT (decl->vtblsym) = TREE_TYPE (build_ctype (decl->type));
  TREE_READONLY (decl->vtblsym) = 1;
  DECL_VIRTUAL_P (decl->vtblsym) = 1;

  SET_DECL_ALIGN (decl->vtblsym, TARGET_VTABLE_ENTRY_ALIGN);
  DECL_USER_ALIGN (decl->vtblsym) = true;

  return decl->vtblsym;
}

/* Helper function of build_class_instance.  Find the field inside aggregate
   TYPE identified by IDENT at field OFFSET.  */

static tree
find_aggregate_field (tree type, tree ident, tree offset)
{
  tree fields = TYPE_FIELDS (type);

  for (tree field = fields; field != NULL_TREE; field = TREE_CHAIN (field))
    {
      if (DECL_NAME (field) == NULL_TREE
	  && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
	{
	  /* Search nesting anonymous structs and unions.  */
	  tree vfield = find_aggregate_field (TREE_TYPE (field),
					      ident, offset);
	  if (vfield != NULL_TREE)
	    return vfield;
	}
      else if (DECL_NAME (field) == ident
	       && (offset == NULL_TREE
		   || DECL_FIELD_OFFSET (field) == offset))
	{
	  /* Found matching field at offset.  */
	  return field;
	}
    }

  return NULL_TREE;
}

/* Helper function of build_new_class_expr.  Return a constructor that matches
   the layout of the class expression EXP.  */

static tree
build_class_instance (ClassReferenceExp *exp)
{
  ClassDeclaration *cd = exp->originalClass ();
  tree type = TREE_TYPE (build_ctype (exp->value->stype));
  vec<constructor_elt, va_gc> *ve = NULL;

  /* The set base vtable field.  */
  tree vptr = build_address (get_vtable_decl (cd));
  CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type), vptr);

  /* Go through the inheritance graph from top to bottom.  This will add all
     values to the constructor out of order, however build_struct_literal
     will re-order all values before returning the finished literal.  */
  for (ClassDeclaration *bcd = cd; bcd != NULL; bcd = bcd->baseClass)
    {
      /* Anonymous vtable interface fields are laid out before the fields of
	 each class.  The interface offset is used to determine where to put
	 the classinfo offset reference.  */
      for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++)
	{
	  BaseClass *bc = (*bcd->vtblInterfaces)[i];

	  for (ClassDeclaration *cd2 = cd; 1; cd2 = cd2->baseClass)
	    {
	      gcc_assert (cd2 != NULL);

	      unsigned csymoffset = base_vtable_offset (cd2, bc);
	      /* If the base class vtable was found.  */
	      if (csymoffset != ~0u)
		{
		  tree csym = build_address (get_classinfo_decl (cd2));
		  csym = build_offset (csym, size_int (csymoffset));

		  tree field = find_aggregate_field (type, NULL_TREE,
						     size_int (bc->offset));
		  gcc_assert (field != NULL_TREE);

		  CONSTRUCTOR_APPEND_ELT (ve, field, csym);
		  break;
		}
	    }
	}

      /* Generate initial values of all fields owned by current class.
	 Use both the name and offset to find the right field.  */
      for (size_t i = 0; i < bcd->fields.dim; i++)
	{
	  VarDeclaration *vfield = bcd->fields[i];
	  int index = exp->findFieldIndexByName (vfield);
	  gcc_assert (index != -1);

	  Expression *value = (*exp->value->elements)[index];
	  if (!value)
	    continue;

	  /* Use find_aggregate_field to get the overridden field decl,
	     instead of the field associated with the base class.  */
	  tree field = get_symbol_decl (bcd->fields[i]);
	  field = find_aggregate_field (type, DECL_NAME (field),
					DECL_FIELD_OFFSET (field));
	  gcc_assert (field != NULL_TREE);

	  CONSTRUCTOR_APPEND_ELT (ve, field, build_expr (value, true));
	}
    }

  return build_struct_literal (type, ve);
}

/* Get the VAR_DECL of a class instance representing EXPR as static data.
   If this does not yet exist, create it.  This is used to support initializing
   a static variable that is of a class type using values known during CTFE.
   In user code, it is analogous to the following code snippet.

    enum E = new C(1, 2, 3);

   That we write the contents of `C(1, 2, 3)' to static data is only a compiler
   implementation detail.  The initialization of these symbols could be done at
   run-time using during as part of the module initialization or shared static
   constructors phase of run-time start-up - whichever comes after `gc_init()'.
   And infact that would be the better thing to do here eventually.  */

tree
build_new_class_expr (ClassReferenceExp *expr)
{
  if (expr->value->sym)
    return expr->value->sym;

  /* Build the reference symbol.  */
  tree type = build_ctype (expr->value->stype);
  expr->value->sym = build_artificial_decl (TREE_TYPE (type), NULL_TREE, "C");

  DECL_INITIAL (expr->value->sym) = build_class_instance (expr);
  d_pushdecl (expr->value->sym);
  rest_of_decl_compilation (expr->value->sym, 1, 0);

  return expr->value->sym;
}

/* Get the VAR_DECL of the static initializer symbol for the struct/class DECL.
   If this does not yet exist, create it.  The static initializer data is
   accessible via TypeInfo, and is also used in 'new class' and default
   initializing struct literals.  */

tree
aggregate_initializer_decl (AggregateDeclaration *decl)
{
  if (decl->sinit)
    return decl->sinit;

  /* Class is a reference, want the record type.  */
  tree type = build_ctype (decl->type);
  StructDeclaration *sd = decl->isStructDeclaration ();
  if (!sd)
    type = TREE_TYPE (type);

  tree ident = mangle_internal_decl (decl, "__init", "Z");

  decl->sinit = declare_extern_var (ident, type);
  DECL_LANG_SPECIFIC (decl->sinit) = build_lang_decl (NULL);

  DECL_CONTEXT (decl->sinit) = type;
  TREE_READONLY (decl->sinit) = 1;

  /* Honor struct alignment set by user.  */
  if (sd && sd->alignment != STRUCTALIGN_DEFAULT)
    {
      SET_DECL_ALIGN (decl->sinit, sd->alignment * BITS_PER_UNIT);
      DECL_USER_ALIGN (decl->sinit) = true;
    }

  return decl->sinit;
}

/* Generate the data for the static initializer.  */

tree
layout_class_initializer (ClassDeclaration *cd)
{
  NewExp *ne = NewExp::create (cd->loc, NULL, NULL, cd->type, NULL);
  ne->type = cd->type;

  Expression *e = ne->ctfeInterpret ();
  gcc_assert (e->op == TOKclassreference);

  return build_class_instance ((ClassReferenceExp *) e);
}

tree
layout_struct_initializer (StructDeclaration *sd)
{
  StructLiteralExp *sle = StructLiteralExp::create (sd->loc, sd, NULL);

  if (!sd->fill (sd->loc, sle->elements, true))
    gcc_unreachable ();

  sle->type = sd->type;
  return build_expr (sle, true);
}

/* Get the VAR_DECL of the static initializer symbol for the enum DECL.
   If this does not yet exist, create it.  The static initializer data is
   accessible via TypeInfo_Enum, but the field member type is a byte[] that
   requires a pointer to a symbol reference.  */

tree
enum_initializer_decl (EnumDeclaration *decl)
{
  if (decl->sinit)
    return decl->sinit;

  tree type = build_ctype (decl->type);

  Identifier *ident_save = decl->ident;
  if (!decl->ident)
    decl->ident = Identifier::generateId ("__enum");
  tree ident = mangle_internal_decl (decl, "__init", "Z");
  decl->ident = ident_save;

  decl->sinit = declare_extern_var (ident, type);
  DECL_LANG_SPECIFIC (decl->sinit) = build_lang_decl (NULL);

  DECL_CONTEXT (decl->sinit) = d_decl_context (decl);
  TREE_READONLY (decl->sinit) = 1;

  return decl->sinit;
}

/* Return an anonymous static variable of type TYPE, initialized with INIT,
   and optionally prefixing the name with PREFIX.  */

tree
build_artificial_decl (tree type, tree init, const char *prefix)
{
  tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, type);
  const char *name = prefix ? prefix : "___s";
  char *label;

  ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
  SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
  DECL_NAME (decl) = DECL_ASSEMBLER_NAME (decl);

  TREE_PUBLIC (decl) = 0;
  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;

  /* Perhaps at some point the initializer constant should be hashed
     to remove duplicates.  */
  DECL_INITIAL (decl) = init;

  return decl;
}

/* Build TYPE_DECL for the declaration DSYM.  */

void
build_type_decl (tree type, Dsymbol *dsym)
{
  if (TYPE_STUB_DECL (type))
    return;

  gcc_assert (!POINTER_TYPE_P (type));

  tree decl = build_decl (make_location_t (dsym->loc), TYPE_DECL,
			  get_identifier (dsym->ident->toChars ()), type);
  SET_DECL_ASSEMBLER_NAME (decl, get_identifier (mangle_decl (dsym)));
  TREE_PUBLIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_CONTEXT (decl) = d_decl_context (dsym);

  TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
  TYPE_NAME (type) = decl;

  /* Not sure if there is a need for separate TYPE_DECLs in
     TYPE_NAME and TYPE_STUB_DECL.  */
  if (TREE_CODE (type) == ENUMERAL_TYPE || RECORD_OR_UNION_TYPE_P (type))
    TYPE_STUB_DECL (type) = decl;

  rest_of_decl_compilation (decl, SCOPE_FILE_SCOPE_P (decl), 0);
}

/* Create a declaration for field NAME of a given TYPE, setting the flags
   for whether the field is ARTIFICIAL and/or IGNORED.  */

tree
create_field_decl (tree type, const char *name, int artificial, int ignored)
{
  tree decl = build_decl (input_location, FIELD_DECL,
			  name ? get_identifier (name) : NULL_TREE, type);
  DECL_ARTIFICIAL (decl) = artificial;
  DECL_IGNORED_P (decl) = ignored;

  return decl;
}

/* Return the COMDAT group into which DECL should be placed.  */

static tree
d_comdat_group (tree decl)
{
  /* If already part of a comdat group, use that.  */
  if (DECL_COMDAT_GROUP (decl))
    return DECL_COMDAT_GROUP (decl);

  return DECL_ASSEMBLER_NAME (decl);
}

/* Set DECL up to have the closest approximation of "initialized common"
   linkage available.  */

void
d_comdat_linkage (tree decl)
{
  if (flag_weak)
    make_decl_one_only (decl, d_comdat_group (decl));
  else if (TREE_CODE (decl) == FUNCTION_DECL
	   || (VAR_P (decl) && DECL_ARTIFICIAL (decl)))
    /* We can just emit function and compiler-generated variables statically;
       having multiple copies is (for the most part) only a waste of space.  */
    TREE_PUBLIC (decl) = 0;
  else if (DECL_INITIAL (decl) == NULL_TREE
	   || DECL_INITIAL (decl) == error_mark_node)
    /* Fallback, cannot have multiple copies.  */
    DECL_COMMON (decl) = 1;

  if (TREE_PUBLIC (decl))
    DECL_COMDAT (decl) = 1;
}

/* Set DECL up to have the closest approximation of "linkonce" linkage.  */

void
d_linkonce_linkage (tree decl)
{
  /* Weak definitions have to be public.  */
  if (!TREE_PUBLIC (decl))
    return;

  /* Necessary to allow DECL_ONE_ONLY or DECL_WEAK functions to be inlined.  */
  if (TREE_CODE (decl) == FUNCTION_DECL)
    DECL_DECLARED_INLINE_P (decl) = 1;

  /* No weak support, fallback to COMDAT linkage.  */
  if (!flag_weak)
   return d_comdat_linkage (decl);

  make_decl_one_only (decl, d_comdat_group (decl));
}
