/* RunTime Type Identification
   Copyright (C) 1995-2015 Free Software Foundation, Inc.
   Mostly written by Jason Merrill (jason@cygnus.com).

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 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 "intl.h"
#include "coretypes.h"
#include "tm.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "tm_p.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "cp-tree.h"
#include "flags.h"
#include "convert.h"
#include "target.h"
#include "c-family/c-pragma.h"

/* C++ returns type information to the user in struct type_info
   objects. We also use type information to implement dynamic_cast and
   exception handlers. Type information for a particular type is
   indicated with an ABI defined structure derived from type_info.
   This would all be very straight forward, but for the fact that the
   runtime library provides the definitions of the type_info structure
   and the ABI defined derived classes. We cannot build declarations
   of them directly in the compiler, but we need to layout objects of
   their type.  Somewhere we have to lie.

   We define layout compatible POD-structs with compiler-defined names
   and generate the appropriate initializations for them (complete
   with explicit mention of their vtable). When we have to provide a
   type_info to the user we reinterpret_cast the internal compiler
   type to type_info.  A well formed program can only explicitly refer
   to the type_infos of complete types (& cv void).  However, we chain
   pointer type_infos to the pointed-to-type, and that can be
   incomplete.  We only need the addresses of such incomplete
   type_info objects for static initialization.

   The type information VAR_DECL of a type is held on the
   IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL
   will be the internal type.  It will usually have the correct
   internal type reflecting the kind of type it represents (pointer,
   array, function, class, inherited class, etc).  When the type it
   represents is incomplete, it will have the internal type
   corresponding to type_info.  That will only happen at the end of
   translation, when we are emitting the type info objects.  */

/* Auxiliary data we hold for each type_info derived object we need.  */
typedef struct GTY (()) tinfo_s {
  tree type;  /* The RECORD_TYPE for this type_info object */

  tree vtable; /* The VAR_DECL of the vtable.  Only filled at end of
		  translation.  */

  tree name;  /* IDENTIFIER_NODE for the ABI specified name of
		 the type_info derived type.  */
} tinfo_s;


typedef enum tinfo_kind
{
  TK_TYPE_INFO_TYPE,    /* abi::__type_info_pseudo */
  TK_BASE_TYPE,		/* abi::__base_class_type_info */
  TK_BUILTIN_TYPE,	/* abi::__fundamental_type_info */
  TK_ARRAY_TYPE,	/* abi::__array_type_info */
  TK_FUNCTION_TYPE,	/* abi::__function_type_info */
  TK_ENUMERAL_TYPE,	/* abi::__enum_type_info */
  TK_POINTER_TYPE,	/* abi::__pointer_type_info */
  TK_POINTER_MEMBER_TYPE, /* abi::__pointer_to_member_type_info */
  TK_CLASS_TYPE,	/* abi::__class_type_info */
  TK_SI_CLASS_TYPE,	/* abi::__si_class_type_info */
  TK_FIXED		/* end of fixed descriptors. */
  /* ...		   abi::__vmi_type_info<I> */
} tinfo_kind;

/* Helper macro to get maximum scalar-width of pointer or of the 'long'-type.
   This of interest for llp64 targets.  */
#define LONGPTR_T \
  integer_types[(POINTER_SIZE <= TYPE_PRECISION (integer_types[itk_long]) \
		 ? itk_long : itk_long_long)]

/* A vector of all tinfo decls that haven't yet been emitted.  */
vec<tree, va_gc> *unemitted_tinfo_decls;

/* A vector of all type_info derived types we need.  The first few are
   fixed and created early. The remainder are for multiple inheritance
   and are generated as needed. */
static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;

static tree ifnonnull (tree, tree, tsubst_flags_t);
static tree tinfo_name (tree, bool);
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
static tree get_tinfo_ptr (tree);
static bool typeid_ok_p (void);
static int qualifier_flags (tree);
static bool target_incomplete_p (tree);
static tree tinfo_base_init (tinfo_s *, tree);
static tree generic_initializer (tinfo_s *, tree);
static tree ptr_initializer (tinfo_s *, tree);
static tree ptm_initializer (tinfo_s *, tree);
static tree class_initializer (tinfo_s *, tree, unsigned, ...);
static void create_pseudo_type_info (int, const char *, ...);
static tree get_pseudo_ti_init (tree, unsigned);
static unsigned get_pseudo_ti_index (tree);
static void create_tinfo_types (void);
static bool typeinfo_in_lib_p (tree);

static int doing_runtime = 0;

static void
push_abi_namespace (void)
{
  push_nested_namespace (abi_node);
  push_visibility ("default", 2);
}

static void
pop_abi_namespace (void)
{
  pop_visibility (2);
  pop_nested_namespace (abi_node);
}

/* Declare language defined type_info type and a pointer to const
   type_info.  This is incomplete here, and will be completed when
   the user #includes <typeinfo>.  There are language defined
   restrictions on what can be done until that is included.  Create
   the internal versions of the ABI types.  */

void
init_rtti_processing (void)
{
  tree type_info_type;

  push_namespace (std_identifier);
  type_info_type = xref_tag (class_type, get_identifier ("type_info"),
			     /*tag_scope=*/ts_current, false);
  pop_namespace ();
  const_type_info_type_node
    = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST);
  type_info_ptr_type = build_pointer_type (const_type_info_type_node);

  vec_alloc (unemitted_tinfo_decls, 124);

  create_tinfo_types ();
}

/* Given the expression EXP of type `class *', return the head of the
   object pointed to by EXP with type cv void*, if the class has any
   virtual functions (TYPE_POLYMORPHIC_P), else just return the
   expression.  */

tree
build_headof (tree exp)
{
  tree type = TREE_TYPE (exp);
  tree offset;
  tree index;

  gcc_assert (TYPE_PTR_P (type));
  type = TREE_TYPE (type);

  if (!TYPE_POLYMORPHIC_P (type))
    return exp;

  /* We use this a couple of times below, protect it.  */
  exp = save_expr (exp);

  /* The offset-to-top field is at index -2 from the vptr.  */
  index = build_int_cst (NULL_TREE,
			 -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);

  offset = build_vtbl_ref (cp_build_indirect_ref (exp, RO_NULL, 
                                                  tf_warning_or_error), 
                           index);

  type = cp_build_qualified_type (ptr_type_node,
				  cp_type_quals (TREE_TYPE (exp)));
  return fold_build_pointer_plus (exp, offset);
}

/* Get a bad_cast node for the program to throw...

   See libstdc++/exception.cc for __throw_bad_cast */

static tree
throw_bad_cast (void)
{
  tree fn = get_identifier ("__cxa_bad_cast");
  if (!get_global_value_if_present (fn, &fn))
    fn = push_throw_library_fn (fn, build_function_type_list (ptr_type_node,
							      NULL_TREE));

  return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
}

/* Return an expression for "__cxa_bad_typeid()".  The expression
   returned is an lvalue of type "const std::type_info".  */

static tree
throw_bad_typeid (void)
{
  tree fn = get_identifier ("__cxa_bad_typeid");
  if (!get_global_value_if_present (fn, &fn))
    {
      tree t;

      t = build_reference_type (const_type_info_type_node);
      t = build_function_type_list (t, NULL_TREE);
      fn = push_throw_library_fn (fn, t);
    }

  return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
}

/* Return an lvalue expression whose type is "const std::type_info"
   and whose value indicates the type of the expression EXP.  If EXP
   is a reference to a polymorphic class, return the dynamic type;
   otherwise return the static type of the expression.  */

static tree
get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
{
  tree type;
  tree t;

  if (error_operand_p (exp))
    return error_mark_node;

  exp = resolve_nondeduced_context (exp, complain);

  /* peel back references, so they match.  */
  type = non_reference (TREE_TYPE (exp));

  /* Peel off cv qualifiers.  */
  type = TYPE_MAIN_VARIANT (type);

  /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics.  */
  if (CLASS_TYPE_P (type) || type == unknown_type_node
      || type == init_list_type_node)
    type = complete_type_or_maybe_complain (type, exp, complain);

  if (!type)
    return error_mark_node;

  /* If exp is a reference to polymorphic type, get the real type_info.  */
  if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
    {
      /* build reference to type_info from vtable.  */
      tree index;

      /* The RTTI information is at index -1.  */
      index = build_int_cst (NULL_TREE,
			     -1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
      t = build_vtbl_ref (exp, index);
      t = convert (type_info_ptr_type, t);
    }
  else
    /* Otherwise return the type_info for the static type of the expr.  */
    t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));

  return cp_build_indirect_ref (t, RO_NULL, complain);
}

static bool
typeid_ok_p (void)
{
  tree pseudo_type_info, type_info_type;

  if (! flag_rtti)
    {
      error ("cannot use typeid with -fno-rtti");
      return false;
    }

  if (!COMPLETE_TYPE_P (const_type_info_type_node))
    {
      error ("must #include <typeinfo> before using typeid");
      return false;
    }

  pseudo_type_info = (*tinfo_descs)[TK_TYPE_INFO_TYPE].type;
  type_info_type = TYPE_MAIN_VARIANT (const_type_info_type_node);

  /* Make sure abi::__type_info_pseudo has the same alias set
     as std::type_info.  */
  if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
  else
    gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
		== get_alias_set (type_info_type));

  return true;
}

/* Return an expression for "typeid(EXP)".  The expression returned is
   an lvalue of type "const std::type_info".  */

tree
build_typeid (tree exp, tsubst_flags_t complain)
{
  tree cond = NULL_TREE, initial_expr = exp;
  int nonnull = 0;

  if (exp == error_mark_node || !typeid_ok_p ())
    return error_mark_node;

  if (processing_template_decl)
    return build_min (TYPEID_EXPR, const_type_info_type_node, exp);

  /* FIXME when integrating with c_fully_fold, mark
     resolves_to_fixed_type_p case as a non-constant expression.  */
  if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
      && ! resolves_to_fixed_type_p (exp, &nonnull)
      && ! nonnull)
    {
      /* So we need to look into the vtable of the type of exp.
         Make sure it isn't a null lvalue.  */
      exp = cp_build_addr_expr (exp, complain);
      exp = save_expr (exp);
      cond = cp_convert (boolean_type_node, exp, complain);
      exp = cp_build_indirect_ref (exp, RO_NULL, complain);
    }

  exp = get_tinfo_decl_dynamic (exp, complain);

  if (exp == error_mark_node)
    return error_mark_node;

  if (cond)
    {
      tree bad = throw_bad_typeid ();

      exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
    }
  else
    mark_type_use (initial_expr);

  return exp;
}

/* Generate the NTBS name of a type.  If MARK_PRIVATE, put a '*' in front so that
   comparisons will be done by pointer rather than string comparison.  */
static tree
tinfo_name (tree type, bool mark_private)
{
  const char *name;
  int length;
  tree name_string;

  name = mangle_type_string (type);
  length = strlen (name);

  if (mark_private)
    {
      /* Inject '*' at beginning of name to force pointer comparison.  */
      char* buf = (char*) XALLOCAVEC (char, length + 2);
      buf[0] = '*';
      memcpy (buf + 1, name, length + 1);
      name_string = build_string (length + 2, buf);
    }
  else
    name_string = build_string (length + 1, name);

  return fix_string_type (name_string);
}

/* Return a VAR_DECL for the internal ABI defined type_info object for
   TYPE. You must arrange that the decl is mark_used, if actually use
   it --- decls in vtables are only used if the vtable is output.  */

tree
get_tinfo_decl (tree type)
{
  tree name;
  tree d;

  if (variably_modified_type_p (type, /*fn=*/NULL_TREE))
    {
      error ("cannot create type information for type %qT because "
	     "it involves types of variable size",
	     type);
      return error_mark_node;
    }

  if (TREE_CODE (type) == METHOD_TYPE)
    type = build_function_type (TREE_TYPE (type),
				TREE_CHAIN (TYPE_ARG_TYPES (type)));

  type = complete_type (type);

  /* For a class type, the variable is cached in the type node
     itself.  */
  if (CLASS_TYPE_P (type))
    {
      d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
      if (d)
	return d;
    }

  name = mangle_typeinfo_for_type (type);

  d = IDENTIFIER_GLOBAL_VALUE (name);
  if (!d)
    {
      int ix = get_pseudo_ti_index (type);
      tinfo_s *ti = &(*tinfo_descs)[ix];

      d = build_lang_decl (VAR_DECL, name, ti->type);
      SET_DECL_ASSEMBLER_NAME (d, name);
      /* Remember the type it is for.  */
      TREE_TYPE (name) = type;
      DECL_TINFO_P (d) = 1;
      DECL_ARTIFICIAL (d) = 1;
      DECL_IGNORED_P (d) = 1;
      TREE_READONLY (d) = 1;
      TREE_STATIC (d) = 1;
      /* Mark the variable as undefined -- but remember that we can
	 define it later if we need to do so.  */
      DECL_EXTERNAL (d) = 1;
      DECL_NOT_REALLY_EXTERN (d) = 1;
      set_linkage_according_to_type (type, d);

      d = pushdecl_top_level_and_finish (d, NULL_TREE);
      if (CLASS_TYPE_P (type))
	CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;

      /* Add decl to the global array of tinfo decls.  */
      vec_safe_push (unemitted_tinfo_decls, d);
    }

  return d;
}

/* Return a pointer to a type_info object describing TYPE, suitably
   cast to the language defined type.  */

static tree
get_tinfo_ptr (tree type)
{
  tree decl = get_tinfo_decl (type);

  mark_used (decl);
  return build_nop (type_info_ptr_type,
		    build_address (decl));
}

/* Return the type_info object for TYPE.  */

tree
get_typeid (tree type, tsubst_flags_t complain)
{
  if (type == error_mark_node || !typeid_ok_p ())
    return error_mark_node;

  if (processing_template_decl)
    return build_min (TYPEID_EXPR, const_type_info_type_node, type);

  /* If the type of the type-id is a reference type, the result of the
     typeid expression refers to a type_info object representing the
     referenced type.  */
  type = non_reference (type);

  /* This is not one of the uses of a qualified function type in 8.3.5.  */
  if (TREE_CODE (type) == FUNCTION_TYPE
      && (type_memfn_quals (type) != TYPE_UNQUALIFIED
	  || type_memfn_rqual (type) != REF_QUAL_NONE))
    {
      if (complain & tf_error)
	error ("typeid of qualified function type %qT", type);
      return error_mark_node;
    }

  /* The top-level cv-qualifiers of the lvalue expression or the type-id
     that is the operand of typeid are always ignored.  */
  type = TYPE_MAIN_VARIANT (type);

  /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics.  */
  if (CLASS_TYPE_P (type) || type == unknown_type_node
      || type == init_list_type_node)
    type = complete_type_or_maybe_complain (type, NULL_TREE, complain);

  if (!type)
    return error_mark_node;

  return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, complain);
}

/* Check whether TEST is null before returning RESULT.  If TEST is used in
   RESULT, it must have previously had a save_expr applied to it.  */

static tree
ifnonnull (tree test, tree result, tsubst_flags_t complain)
{
  return build3 (COND_EXPR, TREE_TYPE (result),
		 build2 (EQ_EXPR, boolean_type_node, test,
			 cp_convert (TREE_TYPE (test), nullptr_node,
				     complain)),
		 cp_convert (TREE_TYPE (result), nullptr_node, complain),
		 result);
}

/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
   paper.  */

static tree
build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
{
  enum tree_code tc = TREE_CODE (type);
  tree exprtype;
  tree dcast_fn;
  tree old_expr = expr;
  const char *errstr = NULL;

  /* Save casted types in the function's used types hash table.  */
  used_types_insert (type);

  /* T shall be a pointer or reference to a complete class type, or
     `pointer to cv void''.  */
  switch (tc)
    {
    case POINTER_TYPE:
      if (VOID_TYPE_P (TREE_TYPE (type)))
	break;
      /* Fall through.  */
    case REFERENCE_TYPE:
      if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
	{
	  errstr = _("target is not pointer or reference to class");
	  goto fail;
	}
      if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
	{
	  errstr = _("target is not pointer or reference to complete type");
	  goto fail;
	}
      break;

    default:
      errstr = _("target is not pointer or reference");
      goto fail;
    }

  if (tc == POINTER_TYPE)
    {
      expr = decay_conversion (expr, complain);
      exprtype = TREE_TYPE (expr);

      /* If T is a pointer type, v shall be an rvalue of a pointer to
	 complete class type, and the result is an rvalue of type T.  */

      expr = mark_rvalue_use (expr);

      if (!TYPE_PTR_P (exprtype))
	{
	  errstr = _("source is not a pointer");
	  goto fail;
	}
      if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
	{
	  errstr = _("source is not a pointer to class");
	  goto fail;
	}
      if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
	{
	  errstr = _("source is a pointer to incomplete type");
	  goto fail;
	}
    }
  else
    {
      expr = mark_lvalue_use (expr);

      exprtype = build_reference_type (TREE_TYPE (expr));

      /* T is a reference type, v shall be an lvalue of a complete class
	 type, and the result is an lvalue of the type referred to by T.  */

      if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
	{
	  errstr = _("source is not of class type");
	  goto fail;
	}
      if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
	{
	  errstr = _("source is of incomplete class type");
	  goto fail;
	}
    }

  /* The dynamic_cast operator shall not cast away constness.  */
  if (!at_least_as_qualified_p (TREE_TYPE (type),
				TREE_TYPE (exprtype)))
    {
      errstr = _("conversion casts away constness");
      goto fail;
    }

  /* If *type is an unambiguous accessible base class of *exprtype,
     convert statically.  */
  {
    tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
			      ba_check, NULL, complain);
    if (binfo)
      return build_static_cast (type, expr, complain);
  }

  /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
  if (tc == REFERENCE_TYPE)
    expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
				 LOOKUP_NORMAL, NULL_TREE, complain);

  /* Otherwise *exprtype must be a polymorphic class (have a vtbl).  */
  if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
    {
      tree expr1;
      /* if TYPE is `void *', return pointer to complete object.  */
      if (tc == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type)))
	{
	  /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b.  */
	  if (TREE_CODE (expr) == ADDR_EXPR
	      && VAR_P (TREE_OPERAND (expr, 0))
	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
	    return build1 (NOP_EXPR, type, expr);

	  /* Since expr is used twice below, save it.  */
	  expr = save_expr (expr);

	  expr1 = build_headof (expr);
	  if (TREE_TYPE (expr1) != type)
	    expr1 = build1 (NOP_EXPR, type, expr1);
	  return ifnonnull (expr, expr1, complain);
	}
      else
	{
	  tree retval;
	  tree result, td2, td3;
	  tree elems[4];
	  tree static_type, target_type, boff;

	  /* If we got here, we can't convert statically.  Therefore,
	     dynamic_cast<D&>(b) (b an object) cannot succeed.  */
	  if (tc == REFERENCE_TYPE)
	    {
	      if (VAR_P (old_expr)
		  && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
		{
		  tree expr = throw_bad_cast ();
                  if (complain & tf_warning)
                    warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
                             old_expr, type);
		  /* Bash it to the expected type.  */
		  TREE_TYPE (expr) = type;
		  return expr;
		}
	    }
	  /* Ditto for dynamic_cast<D*>(&b).  */
	  else if (TREE_CODE (expr) == ADDR_EXPR)
	    {
	      tree op = TREE_OPERAND (expr, 0);
	      if (VAR_P (op)
		  && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
		{
                  if (complain & tf_warning)
                    warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
                             op, type);
		  retval = build_int_cst (type, 0);
		  return retval;
		}
	    }

	  /* Use of dynamic_cast when -fno-rtti is prohibited.  */
	  if (!flag_rtti)
	    {
              if (complain & tf_error)
                error ("%<dynamic_cast%> not permitted with -fno-rtti");
	      return error_mark_node;
	    }

	  target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
	  static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
	  td2 = get_tinfo_decl (target_type);
	  if (!mark_used (td2, complain) && !(complain & tf_error))
	    return error_mark_node;
	  td2 = cp_build_addr_expr (td2, complain);
	  td3 = get_tinfo_decl (static_type);
	  if (!mark_used (td3, complain) && !(complain & tf_error))
	    return error_mark_node;
	  td3 = cp_build_addr_expr (td3, complain);

	  /* Determine how T and V are related.  */
	  boff = dcast_base_hint (static_type, target_type);

	  /* Since expr is used twice below, save it.  */
	  expr = save_expr (expr);

	  expr1 = expr;
	  if (tc == REFERENCE_TYPE)
	    expr1 = cp_build_addr_expr (expr1, complain);

	  elems[0] = expr1;
	  elems[1] = td3;
	  elems[2] = td2;
	  elems[3] = boff;

	  dcast_fn = dynamic_cast_node;
	  if (!dcast_fn)
	    {
	      tree tmp;
	      tree tinfo_ptr;
	      const char *name;

	      push_abi_namespace ();
	      tinfo_ptr = xref_tag (class_type,
				    get_identifier ("__class_type_info"),
				    /*tag_scope=*/ts_current, false);

	      tinfo_ptr = build_pointer_type
		(cp_build_qualified_type
		 (tinfo_ptr, TYPE_QUAL_CONST));
	      name = "__dynamic_cast";
	      tmp = build_function_type_list (ptr_type_node,
					      const_ptr_type_node,
					      tinfo_ptr, tinfo_ptr,
					      ptrdiff_type_node, NULL_TREE);
	      dcast_fn = build_library_fn_ptr (name, tmp,
					       ECF_LEAF | ECF_PURE | ECF_NOTHROW);
	      pop_abi_namespace ();
	      dynamic_cast_node = dcast_fn;
	    }
	  result = build_cxx_call (dcast_fn, 4, elems, complain);

	  if (tc == REFERENCE_TYPE)
	    {
	      tree bad = throw_bad_cast ();
	      tree neq;

	      result = save_expr (result);
	      neq = cp_truthvalue_conversion (result);
	      return cp_convert (type,
				 build3 (COND_EXPR, TREE_TYPE (result),
					 neq, result, bad), complain);
	    }

	  /* Now back to the type we want from a void*.  */
	  result = cp_convert (type, result, complain);
	  return ifnonnull (expr, result, complain);
	}
    }
  else
    errstr = _("source type is not polymorphic");

 fail:
  if (complain & tf_error)
    error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)",
           old_expr, TREE_TYPE (old_expr), type, errstr);
  return error_mark_node;
}

tree
build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain)
{
  tree r;

  if (type == error_mark_node || expr == error_mark_node)
    return error_mark_node;

  if (processing_template_decl)
    {
      expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
      TREE_SIDE_EFFECTS (expr) = 1;
      return convert_from_reference (expr);
    }

  r = convert_from_reference (build_dynamic_cast_1 (type, expr, complain));
  if (r != error_mark_node)
    maybe_warn_about_useless_cast (type, expr, complain);
  return r;
}

/* Return the runtime bit mask encoding the qualifiers of TYPE.  */

static int
qualifier_flags (tree type)
{
  int flags = 0;
  int quals = cp_type_quals (type);

  if (quals & TYPE_QUAL_CONST)
    flags |= 1;
  if (quals & TYPE_QUAL_VOLATILE)
    flags |= 2;
  if (quals & TYPE_QUAL_RESTRICT)
    flags |= 4;
  return flags;
}

/* Return true, if the pointer chain TYPE ends at an incomplete type, or
   contains a pointer to member of an incomplete class.  */

static bool
target_incomplete_p (tree type)
{
  while (true)
    if (TYPE_PTRDATAMEM_P (type))
      {
	if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
	  return true;
	type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
      }
    else if (TYPE_PTR_P (type))
      type = TREE_TYPE (type);
    else
      return !COMPLETE_OR_VOID_TYPE_P (type);
}

/* Returns true if TYPE involves an incomplete class type; in that
   case, typeinfo variables for TYPE should be emitted with internal
   linkage.  */

static bool
involves_incomplete_p (tree type)
{
  switch (TREE_CODE (type))
    {
    case POINTER_TYPE:
      return target_incomplete_p (TREE_TYPE (type));

    case OFFSET_TYPE:
    ptrmem:
      return
	(target_incomplete_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))
	 || !COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)));

    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (type))
	goto ptrmem;
      /* Fall through.  */
    case UNION_TYPE:
      if (!COMPLETE_TYPE_P (type))
	return true;

    default:
      /* All other types do not involve incomplete class types.  */
      return false;
    }
}

/* Return a CONSTRUCTOR for the common part of the type_info objects. This
   is the vtable pointer and NTBS name.  The NTBS name is emitted as a
   comdat const char array, so it becomes a unique key for the type. Generate
   and emit that VAR_DECL here.  (We can't always emit the type_info itself
   as comdat, because of pointers to incomplete.) */

static tree
tinfo_base_init (tinfo_s *ti, tree target)
{
  tree init;
  tree name_decl;
  tree vtable_ptr;
  vec<constructor_elt, va_gc> *v;

  {
    tree name_name, name_string;

    /* Generate the NTBS array variable.  */
    tree name_type = build_cplus_array_type
		     (cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST),
		     NULL_TREE);

    /* Determine the name of the variable -- and remember with which
       type it is associated.  */
    name_name = mangle_typeinfo_string_for_type (target);
    TREE_TYPE (name_name) = target;

    name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
    SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
    DECL_ARTIFICIAL (name_decl) = 1;
    DECL_IGNORED_P (name_decl) = 1;
    TREE_READONLY (name_decl) = 1;
    TREE_STATIC (name_decl) = 1;
    DECL_EXTERNAL (name_decl) = 0;
    DECL_TINFO_P (name_decl) = 1;
    set_linkage_according_to_type (target, name_decl);
    import_export_decl (name_decl);
    name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
    DECL_INITIAL (name_decl) = name_string;
    mark_used (name_decl);
    pushdecl_top_level_and_finish (name_decl, name_string);
  }

  vtable_ptr = ti->vtable;
  if (!vtable_ptr)
    {
      tree real_type;
      push_abi_namespace ();
      real_type = xref_tag (class_type, ti->name,
			    /*tag_scope=*/ts_current, false);
      pop_abi_namespace ();

      if (!COMPLETE_TYPE_P (real_type))
	{
	  /* We never saw a definition of this type, so we need to
	     tell the compiler that this is an exported class, as
	     indeed all of the __*_type_info classes are.  */
	  SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
	  CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
	}

      vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
      vtable_ptr = cp_build_addr_expr (vtable_ptr, tf_warning_or_error);

      /* We need to point into the middle of the vtable.  */
      vtable_ptr = fold_build_pointer_plus
	(vtable_ptr,
	 size_binop (MULT_EXPR,
		     size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
		     TYPE_SIZE_UNIT (vtable_entry_type)));

      ti->vtable = vtable_ptr;
    }

  vec_alloc (v, 2);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, vtable_ptr);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  decay_conversion (name_decl, tf_warning_or_error));

  init = build_constructor (init_list_type_node, v);
  TREE_CONSTANT (init) = 1;
  TREE_STATIC (init) = 1;

  return init;
}

/* Return the CONSTRUCTOR expr for a type_info of TYPE. TI provides the
   information about the particular type_info derivation, which adds no
   additional fields to the type_info base.  */

static tree
generic_initializer (tinfo_s *ti, tree target)
{
  tree init = tinfo_base_init (ti, target);

  init = build_constructor_single (init_list_type_node, NULL_TREE, init);
  TREE_CONSTANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;
}

/* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
   TI provides information about the particular type_info derivation,
   which adds target type and qualifier flags members to the type_info base.  */

static tree
ptr_initializer (tinfo_s *ti, tree target)
{
  tree init = tinfo_base_init (ti, target);
  tree to = TREE_TYPE (target);
  int flags = qualifier_flags (to);
  bool incomplete = target_incomplete_p (to);
  vec<constructor_elt, va_gc> *v;
  vec_alloc (v, 3);

  if (incomplete)
    flags |= 8;
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
                          get_tinfo_ptr (TYPE_MAIN_VARIANT (to)));

  init = build_constructor (init_list_type_node, v);
  TREE_CONSTANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;
}

/* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
   TI provides information about the particular type_info derivation,
   which adds class, target type and qualifier flags members to the type_info
   base.  */

static tree
ptm_initializer (tinfo_s *ti, tree target)
{
  tree init = tinfo_base_init (ti, target);
  tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
  tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
  int flags = qualifier_flags (to);
  bool incomplete = target_incomplete_p (to);
  vec<constructor_elt, va_gc> *v;
  vec_alloc (v, 4);

  if (incomplete)
    flags |= 0x8;
  if (!COMPLETE_TYPE_P (klass))
    flags |= 0x10;
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
                          get_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, get_tinfo_ptr (klass));

  init = build_constructor (init_list_type_node, v);
  TREE_CONSTANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;
}

/* Return the CONSTRUCTOR expr for a type_info of class TYPE.
   TI provides information about the particular __class_type_info derivation,
   which adds hint flags and N extra initializers to the type_info base.  */

static tree
class_initializer (tinfo_s *ti, tree target, unsigned n, ...)
{
  tree init = tinfo_base_init (ti, target);
  va_list extra_inits;
  unsigned i;
  vec<constructor_elt, va_gc> *v;
  vec_alloc (v, n+1);

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
  va_start (extra_inits, n);
  for (i = 0; i < n; i++)
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, va_arg (extra_inits, tree));
  va_end (extra_inits);

  init = build_constructor (init_list_type_node, v);
  TREE_CONSTANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;
}

/* Returns true if the typeinfo for type should be placed in
   the runtime library.  */

static bool
typeinfo_in_lib_p (tree type)
{
  /* The typeinfo objects for `T*' and `const T*' are in the runtime
     library for simple types T.  */
  if (TYPE_PTR_P (type)
      && (cp_type_quals (TREE_TYPE (type)) == TYPE_QUAL_CONST
	  || cp_type_quals (TREE_TYPE (type)) == TYPE_UNQUALIFIED))
    type = TREE_TYPE (type);

  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case BOOLEAN_TYPE:
    case REAL_TYPE:
    case VOID_TYPE:
    case NULLPTR_TYPE:
      return true;

    case LANG_TYPE:
      /* fall through.  */

    default:
      return false;
    }
}

/* Generate the initializer for the type info describing TYPE.  TK_INDEX is
   the index of the descriptor in the tinfo_desc vector. */

static tree
get_pseudo_ti_init (tree type, unsigned tk_index)
{
  tinfo_s *ti = &(*tinfo_descs)[tk_index];

  gcc_assert (at_eof);
  switch (tk_index)
    {
    case TK_POINTER_MEMBER_TYPE:
      return ptm_initializer (ti, type);

    case TK_POINTER_TYPE:
      return ptr_initializer (ti, type);

    case TK_BUILTIN_TYPE:
    case TK_ENUMERAL_TYPE:
    case TK_FUNCTION_TYPE:
    case TK_ARRAY_TYPE:
      return generic_initializer (ti, type);

    case TK_CLASS_TYPE:
      return class_initializer (ti, type, 0);

    case TK_SI_CLASS_TYPE:
      {
	tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0);
	tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));

	/* get_tinfo_ptr might have reallocated the tinfo_descs vector.  */
	ti = &(*tinfo_descs)[tk_index];
	return class_initializer (ti, type, 1, tinfo);
      }

    default:
      {
	int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0)
		    | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1));
	tree binfo = TYPE_BINFO (type);
	int nbases = BINFO_N_BASE_BINFOS (binfo);
	vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
	tree offset_type = LONGPTR_T;
	tree base_inits = NULL_TREE;
	int ix;
	vec<constructor_elt, va_gc> *init_vec = NULL;
	constructor_elt *e;

	gcc_assert (tk_index >= TK_FIXED);

	vec_safe_grow (init_vec, nbases);
	/* Generate the base information initializer.  */
	for (ix = nbases; ix--;)
	  {
	    tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
	    tree base_init;
	    int flags = 0;
	    tree tinfo;
	    tree offset;
	    vec<constructor_elt, va_gc> *v;

	    if ((*base_accesses)[ix] == access_public_node)
	      flags |= 2;
	    tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
	    if (BINFO_VIRTUAL_P (base_binfo))
	      {
		/* We store the vtable offset at which the virtual
		   base offset can be found.  */
		offset = BINFO_VPTR_FIELD (base_binfo);
		flags |= 1;
	      }
	    else
	      offset = BINFO_OFFSET (base_binfo);

	    /* Combine offset and flags into one field.  */
	    offset = fold_convert (offset_type, offset);
	    offset = fold_build2_loc (input_location,
				  LSHIFT_EXPR, offset_type, offset,
				  build_int_cst (offset_type, 8));
	    offset = fold_build2_loc (input_location,
				  BIT_IOR_EXPR, offset_type, offset,
				  build_int_cst (offset_type, flags));
	    vec_alloc (v, 2);
	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo);
	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset);
	    base_init = build_constructor (init_list_type_node, v);
	    e = &(*init_vec)[ix];
	    e->index = NULL_TREE;
	    e->value = base_init;
	  }
	base_inits = build_constructor (init_list_type_node, init_vec);

	/* get_tinfo_ptr might have reallocated the tinfo_descs vector.  */
	ti = &(*tinfo_descs)[tk_index];
	return class_initializer (ti, type, 3,
				  build_int_cst (NULL_TREE, hint),
				  build_int_cst (NULL_TREE, nbases),
				  base_inits);
      }
    }
}

/* Generate the RECORD_TYPE containing the data layout of a type_info
   derivative as used by the runtime. This layout must be consistent with
   that defined in the runtime support. Also generate the VAR_DECL for the
   type's vtable. We explicitly manage the vtable member, and name it for
   real type as used in the runtime. The RECORD type has a different name,
   to avoid collisions.  Return a TREE_LIST who's TINFO_PSEUDO_TYPE
   is the generated type and TINFO_VTABLE_NAME is the name of the
   vtable.  We have to delay generating the VAR_DECL of the vtable
   until the end of the translation, when we'll have seen the library
   definition, if there was one.

   REAL_NAME is the runtime's name of the type. Trailing arguments are
   additional FIELD_DECL's for the structure. The final argument must be
   NULL.  */

static void
create_pseudo_type_info (int tk, const char *real_name, ...)
{
  tinfo_s *ti;
  tree pseudo_type;
  char *pseudo_name;
  tree fields;
  tree field_decl;
  va_list ap;

  va_start (ap, real_name);

  /* Generate the pseudo type name.  */
  pseudo_name = (char *) alloca (strlen (real_name) + 30);
  strcpy (pseudo_name, real_name);
  strcat (pseudo_name, "_pseudo");
  if (tk >= TK_FIXED)
    sprintf (pseudo_name + strlen (pseudo_name), "%d", tk - TK_FIXED);

  /* First field is the pseudo type_info base class.  */
  fields = build_decl (input_location,
		       FIELD_DECL, NULL_TREE,
		       (*tinfo_descs)[TK_TYPE_INFO_TYPE].type);

  /* Now add the derived fields.  */
  while ((field_decl = va_arg (ap, tree)))
    {
      DECL_CHAIN (field_decl) = fields;
      fields = field_decl;
    }

  /* Create the pseudo type.  */
  pseudo_type = make_class_type (RECORD_TYPE);
  finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
  CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;

  ti = &(*tinfo_descs)[tk];
  ti->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
  ti->name = get_identifier (real_name);
  ti->vtable = NULL_TREE;

  /* Pretend this is public so determine_visibility doesn't give vtables
     internal linkage.  */
  TREE_PUBLIC (TYPE_MAIN_DECL (ti->type)) = 1;

  va_end (ap);
}

/* Return the index of a pseudo type info type node used to describe
   TYPE.  TYPE must be a complete type (or cv void), except at the end
   of the translation unit.  */

static unsigned
get_pseudo_ti_index (tree type)
{
  unsigned ix;

  switch (TREE_CODE (type))
    {
    case OFFSET_TYPE:
      ix = TK_POINTER_MEMBER_TYPE;
      break;

    case POINTER_TYPE:
      ix = TK_POINTER_TYPE;
      break;

    case ENUMERAL_TYPE:
      ix = TK_ENUMERAL_TYPE;
      break;

    case FUNCTION_TYPE:
      ix = TK_FUNCTION_TYPE;
      break;

    case ARRAY_TYPE:
      ix = TK_ARRAY_TYPE;
      break;

    case UNION_TYPE:
    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (type))
	{
	  ix = TK_POINTER_MEMBER_TYPE;
	  break;
	}
      else if (!COMPLETE_TYPE_P (type))
	{
	  if (!at_eof)
	    cxx_incomplete_type_error (NULL_TREE, type);
	  ix = TK_CLASS_TYPE;
	  break;
	}
      else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
	{
	  ix = TK_CLASS_TYPE;
	  break;
	}
      else
	{
	  tree binfo = TYPE_BINFO (type);
	  vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
	  tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
	  int num_bases = BINFO_N_BASE_BINFOS (binfo);

	  if (num_bases == 1
	      && (*base_accesses)[0] == access_public_node
	      && !BINFO_VIRTUAL_P (base_binfo)
	      && integer_zerop (BINFO_OFFSET (base_binfo)))
	    {
	      /* single non-virtual public.  */
	      ix = TK_SI_CLASS_TYPE;
	      break;
	    }
	  else
	    {
	      tinfo_s *ti;
	      tree array_domain, base_array;

	      ix = TK_FIXED + num_bases;
	      if (vec_safe_length (tinfo_descs) <= ix)
		{
		  /* too short, extend.  */
		  unsigned len = vec_safe_length (tinfo_descs);

		  vec_safe_grow (tinfo_descs, ix + 1);
		  while (tinfo_descs->iterate (len++, &ti))
		    ti->type = ti->vtable = ti->name = NULL_TREE;
		}
	      else if ((*tinfo_descs)[ix].type)
		/* already created.  */
		break;

	      /* Create the array of __base_class_type_info entries.  */
	      array_domain = build_index_type (size_int (num_bases - 1));
	      base_array = build_array_type ((*tinfo_descs)[TK_BASE_TYPE].type,
					     array_domain);

	      push_abi_namespace ();
	      create_pseudo_type_info
		(ix, "__vmi_class_type_info",
		 build_decl (input_location,
			     FIELD_DECL, NULL_TREE, integer_type_node),
		 build_decl (input_location,
			     FIELD_DECL, NULL_TREE, integer_type_node),
		 build_decl (input_location,
			     FIELD_DECL, NULL_TREE, base_array),
		 NULL);
	      pop_abi_namespace ();
	      break;
	    }
	}
    default:
      ix = TK_BUILTIN_TYPE;
      break;
    }
  return ix;
}

/* Make sure the required builtin types exist for generating the type_info
   variable definitions.  */

static void
create_tinfo_types (void)
{
  tinfo_s *ti;

  gcc_assert (!tinfo_descs);

  vec_safe_grow (tinfo_descs, TK_FIXED);

  push_abi_namespace ();

  /* Create the internal type_info structure. This is used as a base for
     the other structures.  */
  {
    tree field, fields;

    field = build_decl (BUILTINS_LOCATION,
			FIELD_DECL, NULL_TREE, const_ptr_type_node);
    fields = field;

    field = build_decl (BUILTINS_LOCATION,
			FIELD_DECL, NULL_TREE, const_string_type_node);
    DECL_CHAIN (field) = fields;
    fields = field;

    ti = &(*tinfo_descs)[TK_TYPE_INFO_TYPE];
    ti->type = make_class_type (RECORD_TYPE);
    ti->vtable = NULL_TREE;
    ti->name = NULL_TREE;
    finish_builtin_struct (ti->type, "__type_info_pseudo",
			   fields, NULL_TREE);
  }

  /* Fundamental type_info */
  create_pseudo_type_info (TK_BUILTIN_TYPE, "__fundamental_type_info", NULL);

  /* Array, function and enum type_info. No additional fields.  */
  create_pseudo_type_info (TK_ARRAY_TYPE, "__array_type_info", NULL);
  create_pseudo_type_info (TK_FUNCTION_TYPE, "__function_type_info", NULL);
  create_pseudo_type_info (TK_ENUMERAL_TYPE, "__enum_type_info", NULL);

  /* Class type_info.  No additional fields.  */
  create_pseudo_type_info (TK_CLASS_TYPE, "__class_type_info", NULL);

  /* Single public non-virtual base class. Add pointer to base class.
     This is really a descendant of __class_type_info.  */
  create_pseudo_type_info (TK_SI_CLASS_TYPE, "__si_class_type_info",
	    build_decl (BUILTINS_LOCATION,
			FIELD_DECL, NULL_TREE, type_info_ptr_type),
	    NULL);

  /* Base class internal helper. Pointer to base type, offset to base,
     flags.  */
  {
    tree field, fields;

    field = build_decl (BUILTINS_LOCATION,
			FIELD_DECL, NULL_TREE, type_info_ptr_type);
    fields = field;

    field = build_decl (BUILTINS_LOCATION,
			FIELD_DECL, NULL_TREE, LONGPTR_T);
    DECL_CHAIN (field) = fields;
    fields = field;

    ti = &(*tinfo_descs)[TK_BASE_TYPE];

    ti->type = make_class_type (RECORD_TYPE);
    ti->vtable = NULL_TREE;
    ti->name = NULL_TREE;
    finish_builtin_struct (ti->type, "__base_class_type_info_pseudo",
			   fields, NULL_TREE);
  }

  /* Pointer type_info. Adds two fields, qualification mask
     and pointer to the pointed to type.  This is really a descendant of
     __pbase_type_info.  */
  create_pseudo_type_info (TK_POINTER_TYPE, "__pointer_type_info",
       build_decl (BUILTINS_LOCATION, 
		   FIELD_DECL, NULL_TREE, integer_type_node),
       build_decl (BUILTINS_LOCATION,
		   FIELD_DECL, NULL_TREE, type_info_ptr_type),
       NULL);

  /* Pointer to member data type_info.  Add qualifications flags,
     pointer to the member's type info and pointer to the class.
     This is really a descendant of __pbase_type_info.  */
  create_pseudo_type_info (TK_POINTER_MEMBER_TYPE,
       "__pointer_to_member_type_info",
	build_decl (BUILTINS_LOCATION,
		    FIELD_DECL, NULL_TREE, integer_type_node),
	build_decl (BUILTINS_LOCATION,
		    FIELD_DECL, NULL_TREE, type_info_ptr_type),
	build_decl (BUILTINS_LOCATION,
		    FIELD_DECL, NULL_TREE, type_info_ptr_type),
	NULL);

  pop_abi_namespace ();
}

/* Helper for emit_support_tinfos. Emits the type_info descriptor of
   a single type.  */

void
emit_support_tinfo_1 (tree bltn)
{
  tree types[3];

  if (bltn == NULL_TREE)
    return;
  types[0] = bltn;
  types[1] = build_pointer_type (bltn);
  types[2] = build_pointer_type (cp_build_qualified_type (bltn,
							  TYPE_QUAL_CONST));

  for (int i = 0; i < 3; ++i)
    {
      tree tinfo = get_tinfo_decl (types[i]);
      TREE_USED (tinfo) = 1;
      mark_needed (tinfo);
      /* The C++ ABI requires that these objects be COMDAT.  But,
	 On systems without weak symbols, initialized COMDAT
	 objects are emitted with internal linkage.  (See
	 comdat_linkage for details.)  Since we want these objects
	 to have external linkage so that copies do not have to be
	 emitted in code outside the runtime library, we make them
	 non-COMDAT here.  

	 It might also not be necessary to follow this detail of the
	 ABI.  */
      if (!flag_weak || ! targetm.cxx.library_rtti_comdat ())
	{
	  gcc_assert (TREE_PUBLIC (tinfo) && !DECL_COMDAT (tinfo));
	  DECL_INTERFACE_KNOWN (tinfo) = 1;
	}
    }
}

/* Emit the type_info descriptors which are guaranteed to be in the runtime
   support.  Generating them here guarantees consistency with the other
   structures.  We use the following heuristic to determine when the runtime
   is being generated.  If std::__fundamental_type_info is defined, and its
   destructor is defined, then the runtime is being built.  */

void
emit_support_tinfos (void)
{
  /* Dummy static variable so we can put nullptr in the array; it will be
     set before we actually start to walk the array.  */
  static tree *const fundamentals[] =
  {
    &void_type_node,
    &boolean_type_node,
    &wchar_type_node, &char16_type_node, &char32_type_node,
    &char_type_node, &signed_char_type_node, &unsigned_char_type_node,
    &short_integer_type_node, &short_unsigned_type_node,
    &integer_type_node, &unsigned_type_node,
    &long_integer_type_node, &long_unsigned_type_node,
    &long_long_integer_type_node, &long_long_unsigned_type_node,
    &float_type_node, &double_type_node, &long_double_type_node,
    &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node,
    &nullptr_type_node,
    0
  };
  int ix;
  tree bltn_type, dtor;

  push_abi_namespace ();
  bltn_type = xref_tag (class_type,
			get_identifier ("__fundamental_type_info"),
			/*tag_scope=*/ts_current, false);
  pop_abi_namespace ();
  if (!COMPLETE_TYPE_P (bltn_type))
    return;
  dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
  if (!dtor || DECL_EXTERNAL (dtor))
    return;
  doing_runtime = 1;
  for (ix = 0; fundamentals[ix]; ix++)
    emit_support_tinfo_1 (*fundamentals[ix]);
  for (ix = 0; ix < NUM_INT_N_ENTS; ix ++)
    if (int_n_enabled_p[ix])
      {
	emit_support_tinfo_1 (int_n_trees[ix].signed_type);
	emit_support_tinfo_1 (int_n_trees[ix].unsigned_type);
      }
  for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
    emit_support_tinfo_1 (TREE_VALUE (t));
}

/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
   tinfo decl.  Determine whether it needs emitting, and if so
   generate the initializer.  */

bool
emit_tinfo_decl (tree decl)
{
  tree type = TREE_TYPE (DECL_NAME (decl));
  int in_library = typeinfo_in_lib_p (type);

  gcc_assert (DECL_TINFO_P (decl));

  if (in_library)
    {
      if (doing_runtime)
	DECL_EXTERNAL (decl) = 0;
      else
	{
	  /* If we're not in the runtime, then DECL (which is already
	     DECL_EXTERNAL) will not be defined here.  */
	  DECL_INTERFACE_KNOWN (decl) = 1;
	  return false;
	}
    }
  else if (involves_incomplete_p (type))
    {
      if (!decl_needed_p (decl))
	return false;
      /* If TYPE involves an incomplete class type, then the typeinfo
	 object will be emitted with internal linkage.  There is no
	 way to know whether or not types are incomplete until the end
	 of the compilation, so this determination must be deferred
	 until this point.  */
      TREE_PUBLIC (decl) = 0;
      DECL_EXTERNAL (decl) = 0;
      DECL_INTERFACE_KNOWN (decl) = 1;
    }

  import_export_decl (decl);
  if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
    {
      tree init;

      DECL_EXTERNAL (decl) = 0;
      init = get_pseudo_ti_init (type, get_pseudo_ti_index (type));
      DECL_INITIAL (decl) = init;
      mark_used (decl);
      cp_finish_decl (decl, init, false, NULL_TREE, 0);
      /* Avoid targets optionally bumping up the alignment to improve
	 vector instruction accesses, tinfo are never accessed this way.  */
#ifdef DATA_ABI_ALIGNMENT
      DECL_ALIGN (decl) = DATA_ABI_ALIGNMENT (decl, TYPE_ALIGN (TREE_TYPE (decl)));
      DECL_USER_ALIGN (decl) = true;
#endif
      return true;
    }
  else
    return false;
}

#include "gt-cp-rtti.h"
