/* Routines for GCC for a Symbian OS targeted SH backend.
   Copyright (C) 2004 Free Software Foundation, Inc.
   Contributed by RedHat.
   Most of this code is stolen from i386/winnt.c.

   This file is part of GCC.

   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 2, 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 COPYING.  If not, write to
   the Free Software Foundation, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "output.h"
#include "flags.h"
#include "tree.h"
#include "expr.h"
#include "tm_p.h"
#include "cp/cp-tree.h"	/* We need access to the OVL_... macros.  */
#include "toplev.h"

/* Select the level of debugging information to display.
   0 for no debugging.
   1 for informative messages about decisions to add attributes
   2 for verbose information about what is being done.  */
#define SYMBIAN_DEBUG 0
//#define SYMBIAN_DEBUG 1
//#define SYMBIAN_DEBUG 2

/* A unique character to encode declspec encoded objects.  */
#define SH_SYMBIAN_FLAG_CHAR "$"

/* Unique strings to prefix exported and imported objects.  */
#define DLL_IMPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "i."
#define DLL_EXPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "e."


/* Return the type that we should use to determine if DECL is
   imported or exported.  */

static tree
sh_symbian_associated_type (tree decl)
{
  tree t = NULL_TREE;

  if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
  /* Methods now inherit their dllimport/dllexport attributes correctly
     so there is no need to check their class.  In fact it is wrong to
     check their class since a method can remain unexported from an
     exported class.  */
    return t;

  /* Otherwise we can just take the DECL_CONTEXT as normal.  */
  if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
    t = DECL_CONTEXT (decl);

  return t;
}

/* Return nonzero if DECL is a dllexport'd object.  */

bool
sh_symbian_dllexport_p (tree decl)
{
  tree exp;

  if (   TREE_CODE (decl) != VAR_DECL
      && TREE_CODE (decl) != FUNCTION_DECL)
    return false;

  exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));

  /* Class members get the dllexport status of their class.  */
  if (exp == NULL)
    {
      tree class = sh_symbian_associated_type (decl);

      if (class)
	exp = lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class));
    }
#if SYMBIAN_DEBUG
  if (exp)
    {
      print_node_brief (stderr, "dllexport:", decl, 0);
      fprintf (stderr, "\n");
    }
  else
#if SYMBIAN_DEBUG < 2
    if (TREE_CODE (decl) != FUNCTION_DECL)
#endif
    {
      print_node_brief (stderr, "no dllexport:", decl, 0);
      fprintf (stderr, "\n");
    }
#endif
  return exp ? true : false;
}

/* Return nonzero if DECL is a dllimport'd object.  */

static bool
sh_symbian_dllimport_p (tree decl)
{
  tree imp;

  if (   TREE_CODE (decl) != VAR_DECL
      && TREE_CODE (decl) != FUNCTION_DECL)
    return false;

  imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
  if (imp)
    return true;

  /* Class members get the dllimport status of their class.  */
  imp = sh_symbian_associated_type (decl);
  if (! imp)
    return false;

  imp = lookup_attribute ("dllimport", TYPE_ATTRIBUTES (imp));
  if (!imp)
    return false;

  /* Don't mark defined functions as dllimport.  If the definition itself
     was marked with dllimport, then sh_symbian_handle_dll_attribute reports
     an error. This handles the case when the definition overrides an
     earlier declaration.  */
  if (TREE_CODE (decl) ==  FUNCTION_DECL
      && DECL_INITIAL (decl)
      && !DECL_INLINE (decl))
    {
      /* Don't warn about artificial methods.  */
      if (!DECL_ARTIFICIAL (decl))
	warning ("%H function '%D' is defined after prior declaration as dllimport: attribute ignored",
		 & DECL_SOURCE_LOCATION (decl), decl);
      return false;
    }

  /* We ignore the dllimport attribute for inline member functions.
     This differs from MSVC behavior which treats it like GNUC
     'extern inline' extension.   */
  else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
    {
      if (extra_warnings)
	warning ("%Hinline function '%D' is declared as dllimport: attribute ignored.",
		 & DECL_SOURCE_LOCATION (decl), decl);
      return false;
    }

  /*  Don't allow definitions of static data members in dllimport
      class.  Just ignore the attribute for vtable data.  */
  else if (TREE_CODE (decl) == VAR_DECL
	   && TREE_STATIC (decl)
	   && TREE_PUBLIC (decl)
	   && !DECL_EXTERNAL (decl))
    {
      if (!DECL_VIRTUAL_P (decl))
	error ("%Hdefinition of static data member '%D' of dllimport'd class.",
	       & DECL_SOURCE_LOCATION (decl), decl);
      return false;
    }

  /* Since we can't treat a pointer to a dllimport'd symbol as a
     constant address, we turn off the attribute on C++ virtual
     methods to allow creation of vtables using thunks.  Don't mark
     artificial methods either (in sh_symbian_associated_type, only
     COMDAT artificial method get import status from class context).  */
  else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
	   && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
    return false;

  return true;
}

/* Return nonzero if SYMBOL is marked as being dllexport'd.  */

bool
sh_symbian_dllexport_name_p (const char *symbol)
{
  return strncmp (DLL_EXPORT_PREFIX, symbol,
		  strlen (DLL_EXPORT_PREFIX)) == 0;
}

/* Return nonzero if SYMBOL is marked as being dllimport'd.  */


bool
sh_symbian_dllimport_name_p (const char *symbol)
{
  return strncmp (DLL_IMPORT_PREFIX, symbol,
		  strlen (DLL_IMPORT_PREFIX)) == 0;
}

/* Mark a DECL as being dllexport'd.
   Note that we override the previous setting (e.g.: dllimport).  */

static void
sh_symbian_mark_dllexport (tree decl)
{
  const char *oldname;
  char *newname;
  rtx rtlname;
  tree idp;

  rtlname = XEXP (DECL_RTL (decl), 0);

  if (GET_CODE (rtlname) == SYMBOL_REF)
    oldname = XSTR (rtlname, 0);
  else if (GET_CODE (rtlname) == MEM
	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
    oldname = XSTR (XEXP (rtlname, 0), 0);
  else
    abort ();

  if (sh_symbian_dllimport_name_p (oldname))
    {
     /* Remove DLL_IMPORT_PREFIX.
	Note - we do not issue a warning here.  In Symbian's environment it
	is legitimate for a prototype to be marked as dllimport and the
	corresponding definition to be marked as dllexport.  The prototypes
	are in headers used everywhere and the definition is in a translation
	unit which has included the header in order to ensure argument
	correctness.  */
      oldname += strlen (DLL_IMPORT_PREFIX);
      DECL_NON_ADDR_CONST_P (decl) = 0;
    }
  else if (sh_symbian_dllexport_name_p (oldname))
    return; /* Already done.  */

  newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
  sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);

  /* We pass newname through get_identifier to ensure it has a unique
     address.  RTL processing can sometimes peek inside the symbol ref
     and compare the string's addresses to see if two symbols are
     identical.  */
  idp = get_identifier (newname);

  XEXP (DECL_RTL (decl), 0) =
    gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
}

/* Mark a DECL as being dllimport'd.  */

static void
sh_symbian_mark_dllimport (tree decl)
{
  const char *oldname;
  char *newname;
  tree idp;
  rtx rtlname;
  rtx newrtl;

  rtlname = XEXP (DECL_RTL (decl), 0);

  if (GET_CODE (rtlname) == SYMBOL_REF)
    oldname = XSTR (rtlname, 0);
  else if (GET_CODE (rtlname) == MEM
	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
    oldname = XSTR (XEXP (rtlname, 0), 0);
  else
    abort ();

  if (sh_symbian_dllexport_name_p (oldname))
    {
      error ("%qs declared as both exported to and imported from a DLL",
             IDENTIFIER_POINTER (DECL_NAME (decl)));
    }
  else if (sh_symbian_dllimport_name_p (oldname))
    {
      /* Already done, but do a sanity check to prevent assembler errors.  */
      if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
	error ("%Hfailure in redeclaration of '%D': dllimport'd symbol lacks external linkage.",
	       &DECL_SOURCE_LOCATION (decl), decl);
    }
  else
    {
      newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
      sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);

      /* We pass newname through get_identifier to ensure it has a unique
	 address.  RTL processing can sometimes peek inside the symbol ref
	 and compare the string's addresses to see if two symbols are
	 identical.  */
      idp = get_identifier (newname);
      newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
      XEXP (DECL_RTL (decl), 0) = newrtl;
    }
}

void
sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
{
  default_encode_section_info (decl, rtl, first);

  /* Mark the decl so we can tell from the rtl whether
     the object is dllexport'd or dllimport'd.  */
  if (sh_symbian_dllexport_p (decl))
    sh_symbian_mark_dllexport (decl);
  else if (sh_symbian_dllimport_p (decl))
    sh_symbian_mark_dllimport (decl);
  /* It might be that DECL has already been marked as dllimport, but a
     subsequent definition nullified that.  The attribute is gone but
     DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
     that. Ditto for the DECL_NON_ADDR_CONST_P flag.  */
  else if (  (TREE_CODE (decl) == FUNCTION_DECL
	   || TREE_CODE (decl) == VAR_DECL)
	   && DECL_RTL (decl) != NULL_RTX
	   && GET_CODE (DECL_RTL (decl)) == MEM
	   && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
	   && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
	   && sh_symbian_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
    {
      const char * oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
      /* Remove DLL_IMPORT_PREFIX.  */
      tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
      rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));

      warning ("%H%s '%D' %s after being referenced with dllimport linkage.",
	       & DECL_SOURCE_LOCATION (decl),
	       TREE_CODE (decl) == VAR_DECL ? "variable" : "function",
	       decl, (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
	       ? "defined locally" : "redeclared without dllimport attribute");

      XEXP (DECL_RTL (decl), 0) = newrtl;

      DECL_NON_ADDR_CONST_P (decl) = 0;
    }
}


/* Return the length of a function name prefix
    that starts with the character 'c'.  */

static int
sh_symbian_get_strip_length (int c)
{
  /* XXX Assumes strlen (DLL_EXPORT_PREFIX) == strlen (DLL_IMPORT_PREFIX).  */
  return (c == SH_SYMBIAN_FLAG_CHAR[0]) ? strlen (DLL_EXPORT_PREFIX) : 0;
}

/* Return a pointer to a function's name with any
   and all prefix encodings stripped from it.  */

const char *
sh_symbian_strip_name_encoding (const char *name)
{
  int skip;

  while ((skip = sh_symbian_get_strip_length (*name)))
    name += skip;

  return name;
}

/* Add the named attribute to the given node.  Copes with both DECLs and
   TYPEs.  Will only add the attribute if it is not already present.  */

static void
symbian_add_attribute (tree node, const char *attr_name)
{
  tree attrs;
  tree attr;

  attrs = DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node);

  if (lookup_attribute (attr_name, attrs) != NULL_TREE)
    return;

  attr = get_identifier (attr_name);

  (DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node))
    = tree_cons (attr, NULL_TREE, attrs);

#if SYMBIAN_DEBUG
  fprintf (stderr, "propogate %s attribute", attr_name);
  print_node_brief (stderr, " to", node, 0);
  fprintf (stderr, "\n");
#endif
}

/* Handle a "dllimport" or "dllexport" attribute;
   arguments as in struct attribute_spec.handler.  */

tree
sh_symbian_handle_dll_attribute (tree *pnode, tree name, tree args,
				 int flags, bool *no_add_attrs)
{
  tree thunk;
  tree node = *pnode;
  const char *attr = IDENTIFIER_POINTER (name);

  /* These attributes may apply to structure and union types being
     created, but otherwise should pass to the declaration involved.  */
  if (!DECL_P (node))
    {
      if (flags & ((int) ATTR_FLAG_DECL_NEXT
		   | (int) ATTR_FLAG_FUNCTION_NEXT
		   | (int) ATTR_FLAG_ARRAY_NEXT))
	{
	  warning ("%qs attribute ignored", attr);
	  *no_add_attrs = true;
	  return tree_cons (name, args, NULL_TREE);
	}

      if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
	{
	  warning ("%qs attribute ignored", attr);
	  *no_add_attrs = true;
	}

      return NULL_TREE;
    }

  /* Report error on dllimport ambiguities
     seen now before they cause any damage.  */
  else if (is_attribute_p ("dllimport", name))
    {
      if (TREE_CODE (node) == VAR_DECL)
	{
	  if (DECL_INITIAL (node))
	    {
	      error ("%Hvariable %qD definition is marked dllimport.",
		     & DECL_SOURCE_LOCATION (node), node);
	      *no_add_attrs = true;
	    }

	  /* `extern' needn't be specified with dllimport.
	     Specify `extern' now and hope for the best.  Sigh.  */
	  DECL_EXTERNAL (node) = 1;
	  /* Also, implicitly give dllimport'd variables declared within
	     a function global scope, unless declared static.  */
	  if (current_function_decl != NULL_TREE && ! TREE_STATIC (node))
  	    TREE_PUBLIC (node) = 1;
	}
    }

  /* If the node is an overloaded constructor or destructor, then we must
     make sure that the attribute is propagated along the overload chain,
     as it is these overloaded functions which will be emitted, rather than
     the user declared constructor itself.  */
  if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE
      && (DECL_CONSTRUCTOR_P (node) || DECL_DESTRUCTOR_P (node)))
    {
      tree overload;

      for (overload = OVL_CHAIN (node); overload; overload = OVL_CHAIN (overload))
	{
	  tree node_args;
	  tree func_args;
	  tree function = OVL_CURRENT (overload);

	  if (! function
	      || ! DECL_P (function)
	      || (DECL_CONSTRUCTOR_P (node) && ! DECL_CONSTRUCTOR_P (function))
	      || (DECL_DESTRUCTOR_P (node)  && ! DECL_DESTRUCTOR_P (function)))
	    continue;

	  /* The arguments must match as well.  */
	  for (node_args = DECL_ARGUMENTS (node), func_args = DECL_ARGUMENTS (function);
	       node_args && func_args;
	       node_args = TREE_CHAIN (node_args), func_args = TREE_CHAIN (func_args))
	    if (TREE_TYPE (node_args) != TREE_TYPE (func_args))
	      break;

	  if (node_args || func_args)
	    {
	      /* We can ignore an extraneous __in_chrg arguments in the node.
		 GCC generated destructors, for example, will have this.  */
	      if ((node_args == NULL_TREE
		   || func_args != NULL_TREE)
		  && strcmp (IDENTIFIER_POINTER (DECL_NAME (node)), "__in_chrg") != 0)
		continue;
	    }

	  symbian_add_attribute (function, attr);

	  /* Propagate the attribute to any function thunks as well.  */
	  for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
	    if (TREE_CODE (thunk) == FUNCTION_DECL)
	      symbian_add_attribute (thunk, attr);
	}
    }

  if (TREE_CODE (node) == FUNCTION_DECL && DECL_VIRTUAL_P (node))
    {
      /* Propagate the attribute to any thunks of this function.  */
      for (thunk = DECL_THUNKS (node); thunk; thunk = TREE_CHAIN (thunk))
	if (TREE_CODE (thunk) == FUNCTION_DECL)
	  symbian_add_attribute (thunk, attr);
    }

  /*  Report error if symbol is not accessible at global scope.  */
  if (!TREE_PUBLIC (node)
      && (   TREE_CODE (node) == VAR_DECL
	  || TREE_CODE (node) == FUNCTION_DECL))
    {
      error ("%Hexternal linkage required for symbol '%D' because of '%s' attribute.",
	       & DECL_SOURCE_LOCATION (node), node, IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }

#if SYMBIAN_DEBUG
  print_node_brief (stderr, "mark node", node, 0);
  fprintf (stderr, " as %s\n", attr);
#endif

  return NULL_TREE;
}

/* This code implements a specification for exporting the vtable and rtti of
   classes that have members with the dllexport or dllexport attributes.
   This specification is defined here:

     http://www.armdevzone.com/EABI/exported_class.txt

   Basically it says that a class's vtable and rtti should be exported if
   the following rules apply:

   - If it has any non-inline non-pure virtual functions,
     at least one of these need to be declared dllimport
     OR any of the constructors is declared dllimport.

   AND

   - The class has an inline constructor/destructor and
     a key-function (placement of vtable uniquely defined) that
     is defined in this translation unit.

   The specification also says that for classes which will have their
   vtables and rtti exported that their base class(es) might also need a
   similar exporting if:

   - Every base class needs to have its vtable & rtti exported
     as well, if the following the conditions hold true:
     + The base class has a non-inline declared non-pure virtual function
     + The base class is polymorphic (has or inherits any virtual functions)
       or the base class has any virtual base classes.  */

/* Decide if a base class of a class should
   also have its vtable and rtti exported.  */

static void
symbian_possibly_export_base_class (tree base_class)
{
  tree methods;
  int len;

  if (! (TYPE_CONTAINS_VPTR_P (base_class)))
    return;

  methods = CLASSTYPE_METHOD_VEC (base_class);
  len = methods ? TREE_VEC_LENGTH (methods) : 0;

  for (;len --;)
    {
      tree member = TREE_VEC_ELT (methods, len);

      if (! member)
	continue;

      for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
	{
	  if (TREE_CODE (member) != FUNCTION_DECL)
	    continue;

	  if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
	    continue;

	  if (! DECL_VIRTUAL_P (member))
	    continue;

	  if (DECL_PURE_VIRTUAL_P (member))
	    continue;

	  if (DECL_INLINE (member))
	    continue;

	  break;
	}

      if (member)
	break;
    }

  if (len < 0)
    return;

  /* FIXME: According to the spec this base class should be exported, but
     a) how do we do this ? and
     b) it does not appear to be necessary for compliance with the Symbian
        OS which so far is the only consumer of this code.  */
#if SYMBIAN_DEBUG
  print_node_brief (stderr, "", base_class, 0);
  fprintf (stderr, " EXPORTed [base class of exported class]\n");
#endif
}

/* Decide if a class needs its vtable and rtti exporting.  */

static bool
symbian_export_vtable_and_rtti_p (tree ctype)
{
  bool inline_ctor_dtor;
  bool dllimport_ctor_dtor;
  bool dllimport_member;
  tree binfo, base_binfo;
  tree methods;
  tree key;
  int i;
  int len;

  /* Make sure that we are examining a class...  */
  if (TREE_CODE (ctype) != RECORD_TYPE)
    {
#if SYMBIAN_DEBUG
      print_node_brief (stderr, "", ctype, 0);
      fprintf (stderr, " does NOT need to be EXPORTed [not a class]\n");
#endif
      return false;
    }

  /* If the class does not have a key function it
     does not need to have its vtable exported.  */
  if ((key = CLASSTYPE_KEY_METHOD (ctype)) == NULL_TREE)
    {
#if SYMBIAN_DEBUG
      print_node_brief (stderr, "", ctype, 0);
      fprintf (stderr, " does NOT need to be EXPORTed [no key function]\n");
#endif
      return false;
    }

  /* If the key fn has not been defined
     then the class should not be exported.  */
  if (! TREE_ASM_WRITTEN (key))
    {
#if SYMBIAN_DEBUG
      print_node_brief (stderr, "", ctype, 0);
      fprintf (stderr, " does NOT need to be EXPORTed [key function not defined]\n");
#endif
      return false;
    }

  /* Check the class's member functions.  */
  inline_ctor_dtor = false;
  dllimport_ctor_dtor = false;
  dllimport_member = false;

  methods = CLASSTYPE_METHOD_VEC (ctype);
  len = methods ? TREE_VEC_LENGTH (methods) : 0;

  for (;len --;)
    {
      tree member = TREE_VEC_ELT (methods, len);

      if (! member)
	continue;

      for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
	{
	  if (TREE_CODE (member) != FUNCTION_DECL)
	    continue;

	  if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
	    {
	      if (DECL_INLINE (member)
		  /* Ignore C++ backend created inline ctors/dtors.  */
		  && (   DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (member)
		      || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (member)))
		inline_ctor_dtor = true;

	      if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
		dllimport_ctor_dtor = true;
	    }
	  else
	    {
	      if (DECL_PURE_VIRTUAL_P (member))
		continue;

	      if (! DECL_VIRTUAL_P (member))
		continue;

	      if (DECL_INLINE (member))
		continue;

	      if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
		dllimport_member = true;
	    }
	}
    }

  if (! dllimport_member && ! dllimport_ctor_dtor)
    {
#if SYMBIAN_DEBUG
      print_node_brief (stderr, "", ctype, 0);
      fprintf (stderr,
	       " does NOT need to be EXPORTed [no non-pure virtuals or ctors/dtors with dllimport]\n");
#endif
      return false;
    }

  if (! inline_ctor_dtor)
    {
#if SYMBIAN_DEBUG
      print_node_brief (stderr, "", ctype, 0);
      fprintf (stderr,
	       " does NOT need to be EXPORTed [no inline ctor/dtor]\n");
#endif
      return false;
    }

#if SYMBIAN_DEBUG
  print_node_brief (stderr, "", ctype, 0);
  fprintf (stderr, " DOES need to be EXPORTed\n");
#endif

  /* Now we must check and possibly export the base classes.  */
  for (i = 0, binfo = TYPE_BINFO (ctype);
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    symbian_possibly_export_base_class (BINFO_TYPE (base_binfo));

  return true;
}

/* Add the named attribute to a class and its vtable and rtti.  */

static void
symbian_add_attribute_to_class_vtable_and_rtti (tree ctype, const char *attr_name)
{
  symbian_add_attribute (ctype, attr_name);

  /* If the vtable exists then they need annotating as well.  */
  if (CLASSTYPE_VTABLES (ctype))
    /* XXX - Do we need to annotate any vtables other than the primary ?  */
    symbian_add_attribute (CLASSTYPE_VTABLES (ctype), attr_name);

  /* If the rtti exists then it needs annotating as well.  */
  if (TYPE_MAIN_VARIANT (ctype)
      && CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))
    symbian_add_attribute (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)),
			   attr_name);
}

/* Decide if a class needs to have an attribute because
   one of its member functions has the attribute.  */

static bool
symbian_class_needs_attribute_p (tree ctype, const char *attribute_name)
{
  /* If the key function has the attribute then the class needs it too.  */
  if (TYPE_POLYMORPHIC_P (ctype)
      && CLASSTYPE_KEY_METHOD (ctype)
      && lookup_attribute (attribute_name,
			   DECL_ATTRIBUTES (CLASSTYPE_KEY_METHOD (ctype))))
    return true;

  /* Check the class's member functions.  */
  if (TREE_CODE (ctype) == RECORD_TYPE)
    {
      tree methods = CLASSTYPE_METHOD_VEC (ctype);
      unsigned int len = methods ? TREE_VEC_LENGTH (methods) : 0;

      for (;len --;)
	{
	  tree member = TREE_VEC_ELT (methods, len);

	  if (! member)
	    continue;

	  for (member = OVL_CURRENT (member);
	       member;
	       member = OVL_NEXT (member))
	    {
	      if (TREE_CODE (member) != FUNCTION_DECL)
		continue;

	      if (DECL_PURE_VIRTUAL_P (member))
		continue;

	      if (! DECL_VIRTUAL_P (member))
		continue;

	      if (lookup_attribute (attribute_name, DECL_ATTRIBUTES (member)))
		{
#if SYMBIAN_DEBUG
		  print_node_brief (stderr, "", ctype, 0);
		  fprintf (stderr, " inherits %s because", attribute_name);
		  print_node_brief (stderr, "", member, 0);
		  fprintf (stderr, " has it.\n");
#endif
		  return true;
		}
	    }
	}
    }

#if SYMBIAN_DEBUG
  print_node_brief (stderr, "", ctype, 0);
  fprintf (stderr, " does not inherit %s\n", attribute_name);
#endif
  return false;
}

int
symbian_import_export_class (tree ctype, int import_export)
{
  const char *attr_name = NULL;

  /* If we are exporting the class but it does not have the dllexport
     attribute then we may need to add it.  Similarly imported classes
     may need the dllimport attribute.  */
  switch (import_export)
    {
    case  1: attr_name = "dllexport"; break;
    case -1: attr_name = "dllimport"; break;
    default: break;
    }

  if (attr_name
      && ! lookup_attribute (attr_name, TYPE_ATTRIBUTES (ctype)))
    {
      if (symbian_class_needs_attribute_p (ctype, attr_name))
	symbian_add_attribute_to_class_vtable_and_rtti (ctype, attr_name);

      /* Classes can be forced to export their
	 vtable and rtti under certain conditions.  */
      if (symbian_export_vtable_and_rtti_p (ctype))
	{
	  symbian_add_attribute_to_class_vtable_and_rtti (ctype, "dllexport");

	  /* Make sure that the class and its vtable are exported.  */
	  import_export = 1;

	  if (CLASSTYPE_VTABLES (ctype))
	    DECL_EXTERNAL (CLASSTYPE_VTABLES (ctype)) = 1;

	  /* Check to make sure that if the class has a key method that
	     it is now on the list of keyed classes.  That way its vtable
	     will be emitted.  */
	  if (CLASSTYPE_KEY_METHOD (ctype))
	    {
	      tree class;

	      for (class = keyed_classes; class; class = TREE_CHAIN (class))
		if (class == ctype)
		  break;

	      if (class == NULL_TREE)
		{
#if SYMBIAN_DEBUG
		  print_node_brief (stderr, "Add node", ctype, 0);
		  fprintf (stderr, " to the keyed classes list\n");
#endif
		  keyed_classes = tree_cons (NULL_TREE, ctype, keyed_classes);
		}
	    }

	  /* Make sure that the typeinfo will be emitted as well.  */
	  if (CLASS_TYPE_P (ctype))
	    TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))) = 1;
	}
    }

  return import_export;
}

/* Dummy definition of this array for cc1 building purposes.  */
tree cp_global_trees[CPTI_MAX] __attribute__((weak));

#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)

/* Dummy version of this G++ function for building cc1.  */
void lang_check_failed (const char *, int, const char *) __attribute__((weak));

void
lang_check_failed (const char *file, int line, const char *function)
{
  internal_error ("lang_* check: failed in %s, at %s:%d",
		  function, trim_filename (file), line);
}
#endif /* ENABLE_TREE_CHECKING */
