/* RunTime Type Identification
   Copyright (C) 1995-2025 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 "coretypes.h"
#include "target.h"
#include "cp-tree.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "intl.h"
#include "stor-layout.h"
#include "c-family/c-pragma.h"
#include "gcc-rich-location.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
   get_global_binding 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.  */
struct GTY (()) tinfo_s {
  tree type;  /* The (const-qualified) 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.  */
};


enum tinfo_kind
{
  TK_TYPE_INFO_TYPE,    /* abi::__type_info_pseudo */
  TK_BASE_TYPE,		/* abi::__base_class_type_info */
  TK_DERIVED_TYPES,	/* Start of types derived from abi::__type_info  */
  TK_BUILTIN_TYPE = TK_DERIVED_TYPES,	/* 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_VMI_CLASS_TYPES,	/* abi::__vmi_class_type_info<int> */
  TK_MAX
};

/* Names of the tinfo types.  Must be same order as TK enumeration
   above.  */

static const char *const tinfo_names[TK_MAX] =
{
  "__type_info",
  "__base_class_type_info",
  "__fundamental_type_info",
  "__array_type_info",
  "__function_type_info",
  "__enum_type_info",
  "__pointer_type_info",
  "__pointer_to_member_type_info",
  "__class_type_info",
  "__si_class_type_info",
  "__vmi_class_type_info"
};

/* 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 tinfo_name (tree, bool);
static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
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 tree get_pseudo_ti_init (tree, unsigned);
static unsigned get_pseudo_ti_index (tree);
static tinfo_s *get_tinfo_desc (unsigned);
static void create_tinfo_types (void);
static bool typeinfo_in_lib_p (tree);

static int doing_runtime = 0;

/* Create the internal versions of the ABI types.  */

void
init_rtti_processing (void)
{
  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_fold_indirect_ref (exp),
                           index);

  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++-v3/libsupc++/eh_aux_runtime.cc' for '__cxa_bad_cast'.  */

static tree
throw_bad_cast (void)
{
  static tree fn;
  if (!fn)
    {
      tree name = get_identifier ("__cxa_bad_cast");
      fn = get_global_binding (name);
      if (!fn)
	fn = push_throw_library_fn
	  (name, build_function_type_list (void_type_node, NULL_TREE));
    }

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

/* See 'libstdc++-v3/libsupc++/eh_aux_runtime.cc' for '__cxa_bad_typeid'.  */

static tree
throw_bad_typeid (void)
{
  static tree fn;
  if (!fn)
    {
      tree name = get_identifier ("__cxa_bad_typeid");
      fn = get_global_binding (name);
      if (!fn)
	fn = push_throw_library_fn
	  (name, build_function_type_list (void_type_node, NULL_TREE));
    }

  return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
}

/* const type_info*.  */

inline tree
type_info_ptr_type ()
{
  return build_pointer_type (const_type_info_type_node);
}

/* Return a pointer to a type_info object describing TYPE, suitably
   cast to the language defined type (for typeid) or void (for building
   up the descriptors).  */

static tree
get_tinfo_ptr (tree type, bool voidp = false)
{
  tree decl = get_tinfo_decl (type);
  mark_used (decl);

  tree ptype = voidp ? const_ptr_type_node : type_info_ptr_type ();
  return build_nop (ptype, build_address (decl));
}
static inline tree
get_void_tinfo_ptr (tree type)
{
  return get_tinfo_ptr (type, true);
}

/* 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_ptr_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 (unlowered_expr_type (exp));

  /* Peel off cv qualifiers.  */
  type = cv_unqualified (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);

  return t;
}

static bool
typeid_ok_p (void)
{
  if (! flag_rtti)
    {
      error ("cannot use %<typeid%> with %<-fno-rtti%>");
      return false;
    }

  if (!const_type_info_type_node)
    {
      tree name = get_identifier ("type_info");
      tree decl = lookup_qualified_name (std_node, name);
      if (TREE_CODE (decl) != TYPE_DECL)
	{
	  gcc_rich_location richloc (input_location);
	  maybe_add_include_fixit (&richloc, "<typeinfo>", false);
	  error_at (&richloc,
		    "must %<#include <typeinfo>%> before using"
		    " %<typeid%>");

	  return false;
	}
      const_type_info_type_node
	= cp_build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_CONST);
    }

  tree pseudo = TYPE_MAIN_VARIANT (get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);
  tree real = 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_ALIAS_SET (pseudo) = get_alias_set (real);
  else
    gcc_assert (TYPE_ALIAS_SET (pseudo) == get_alias_set (real));

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

  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_fold_indirect_ref (exp);
    }

  exp = get_tinfo_ptr_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 cp_build_fold_indirect_ref (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)
{
  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)));

  return get_tinfo_decl_direct (type, NULL, -1);
}

/* Get or create a tinfo VAR_DECL directly from the provided information.
   The caller must have already checked it is valid to do so.  */

tree
get_tinfo_decl_direct (tree type, tree name, int pseudo_ix)
{
  /* For a class type, the variable is cached in the type node
     itself.  */
  tree d = NULL_TREE;

  gcc_checking_assert (TREE_CODE (type) != METHOD_TYPE);

  if (CLASS_TYPE_P (type))
    d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));

  if (!name)
    name = mangle_typeinfo_for_type (type);

  if (!CLASS_TYPE_P (type) || TYPE_TRANSPARENT_AGGR (type))
    d = get_global_binding (name);

  if (!d)
    {
      /* Create it.  */
      if (pseudo_ix < 0)
	pseudo_ix = get_pseudo_ti_index (type);

      const tinfo_s *ti = get_tinfo_desc (pseudo_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;
      TREE_ADDRESSABLE (d) = 1;
      /* Tell equal_address_to that different tinfo decls never
	 overlap.  */
      if (vec_safe_is_empty (unemitted_tinfo_decls))
	DECL_ATTRIBUTES (d)
	  = build_tree_list (get_identifier ("non overlapping"),
			     NULL_TREE);
      else
	DECL_ATTRIBUTES (d)
	  = DECL_ATTRIBUTES ((*unemitted_tinfo_decls)[0]);

      /* 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 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 = cv_unqualified (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_fold_indirect_ref (get_tinfo_ptr (type));
}

/* 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.  */

tree
build_if_nonnull (tree test, tree result, tsubst_flags_t complain)
{
  tree null_ptr = cp_convert (TREE_TYPE (test), nullptr_node, complain);
  tree cond = build2 (NE_EXPR, boolean_type_node, test, null_ptr);

  /* This is a compiler generated comparison, don't emit
     e.g. -Wnonnull-compare warning for it.  */
  suppress_warning (cond, OPT_Wnonnull);

  null_ptr = cp_convert (TREE_TYPE (result), nullptr_node, complain);
  cond = build3 (COND_EXPR, TREE_TYPE (result), cond, result, null_ptr);

  /* Likewise, don't emit -Wnonnull for using the result to call
     a member function.  */
  suppress_warning (cond, OPT_Wnonnull);
  return cond;
}

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

static tree
build_dynamic_cast_1 (location_t loc, 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 = 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 (exprtype))
	{
	  errstr = _("source is not of class type");
	  goto fail;
	}
      if (!COMPLETE_TYPE_P (complete_type (exprtype)))
	{
	  errstr = _("source is of incomplete class type");
	  goto fail;
	}

      exprtype = cp_build_reference_type (exprtype, !lvalue_p (expr));
    }

  /* 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 (loc, 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 build_if_nonnull (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_at (loc, 0,
				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
				type, old_expr);
		  /* 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_at (loc, 0,
				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
				type, op);
		  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_at (loc,
			  "%<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)
	    {
	      unsigned flags = push_abi_namespace ();
	      tree tinfo_ptr = xref_tag (class_type,
					 get_identifier ("__class_type_info"));
	      tinfo_ptr = cp_build_qualified_type (tinfo_ptr, TYPE_QUAL_CONST);
	      tinfo_ptr = build_pointer_type (tinfo_ptr);

	      const char *fn_name = "__dynamic_cast";
	      /* void *() (void const *, __class_type_info const *,
		           __class_type_info const *, ptrdiff_t)  */
	      tree fn_type = (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
			  (fn_name, fn_type, ECF_LEAF | ECF_PURE | ECF_NOTHROW));
	      /* As with __cxa_atexit in get_atexit_node.  */
	      DECL_CONTEXT (dcast_fn) = FROB_CONTEXT (current_namespace);
	      DECL_SOURCE_LOCATION (dcast_fn) = BUILTINS_LOCATION;
	      dcast_fn = pushdecl (dcast_fn, /*hiding=*/true);
	      pop_abi_namespace (flags);
	      dynamic_cast_node = dcast_fn;
	    }
	  if (dcast_fn == error_mark_node)
	    return error_mark_node;
	  result = build_cxx_call (dcast_fn, 4, elems, complain);
	  SET_EXPR_LOCATION (result, loc);

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

	      result = save_expr (result);
	      neq = cp_truthvalue_conversion (result, complain);
	      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 build_if_nonnull (expr, result, complain);
	}
    }
  else
    errstr = _("source type is not polymorphic");

 fail:
  if (complain & tf_error)
    error_at (loc, "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 (location_t loc, 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;
      r = convert_from_reference (expr);
      protected_set_expr_location (r, loc);
      return r;
    }

  r = convert_from_reference (build_dynamic_cast_1 (loc, type, expr,
						    complain));
  if (r != error_mark_node)
    maybe_warn_about_useless_cast (loc, type, expr, complain);
  protected_set_expr_location (r, loc);
  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;
      /* Fall through.  */
    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)
    {
      int flags = push_abi_namespace ();
      tree real_type = xref_tag (class_type, ti->name);
      tree real_decl = TYPE_NAME (real_type);
      DECL_SOURCE_LOCATION (real_decl) = BUILTINS_LOCATION;
      pop_abi_namespace (flags);

      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;
  if (tx_safe_fn_type_p (to))
    {
      flags |= 0x20;
      to = tx_unsafe_fn_variant (to);
    }
  if (flag_noexcept_type
      && FUNC_OR_METHOD_TYPE_P (to)
      && TYPE_NOTHROW_P (to))
    {
      flags |= 0x40;
      to = build_exception_variant (to, NULL_TREE);
    }
  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_void_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_void_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, get_void_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 = get_tinfo_desc (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_void_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);
	unsigned nbases = BINFO_N_BASE_BINFOS (binfo);
	vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
	tree offset_type = LONGPTR_T;
	vec<constructor_elt, va_gc> *init_vec = NULL;

	gcc_assert (tk_index - TK_VMI_CLASS_TYPES + 1 == nbases);

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

	    if ((*base_accesses)[ix] == access_public_node)
	      flags |= 2;
	    tinfo = get_void_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);
	    tree base_init = build_constructor (init_list_type_node, v);
	    constructor_elt *e = &(*init_vec)[ix];
	    e->index = NULL_TREE;
	    e->value = base_init;
	  }
	tree 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);
      }
    }
}

/* 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;
      else if (!COMPLETE_TYPE_P (type))
	{
	  if (!at_eof)
	    cxx_incomplete_type_error (NULL_TREE, type);
	  ix = TK_CLASS_TYPE;
	}
      else if (!TYPE_BINFO (type)
	       || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
	ix = TK_CLASS_TYPE;
      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;
	  else
	    ix = TK_VMI_CLASS_TYPES + num_bases - 1;
	}
      break;

    default:
      ix = TK_BUILTIN_TYPE;
      break;
    }
  return ix;
}

/* Return pointer to tinfo descriptor.  Possibly creating the tinfo
   descriptor in the first place.  */

static tinfo_s *
get_tinfo_desc (unsigned ix)
{
  if (tinfo_descs->length () <= ix)
    /* too short, extend.  */
    vec_safe_grow_cleared (tinfo_descs, ix + 1);

  tinfo_s *res = &(*tinfo_descs)[ix];

  if (res->type)
    return res;

  /* Ok, we have to create it.  This layout must be consistent with
     that defined in the runtime support.  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.  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.  */

  /* Fields to add, chained in reverse order.  */
  tree fields = NULL_TREE;

  if (ix >= TK_DERIVED_TYPES)
    {
      /* First field is the pseudo type_info base class.  */
      tree fld_base = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
				  get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);

      DECL_CHAIN (fld_base) = fields;
      fields = fld_base;
    }

  switch (ix)
    {
    case TK_TYPE_INFO_TYPE:
      {
	tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, const_ptr_type_node);
	fields = fld_ptr;

	tree fld_str = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, const_string_type_node);
	DECL_CHAIN (fld_str) = fields;
	fields = fld_str;
	break;
      }

    case TK_BASE_TYPE:
      {
	/* Base class internal helper. Pointer to base type, offset to
	   base, flags.  */
	tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, const_ptr_type_node);
	DECL_CHAIN (fld_ptr) = fields;
	fields = fld_ptr;

	tree fld_flag = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				    NULL_TREE, LONGPTR_T);
	DECL_CHAIN (fld_flag) = fields;
	fields = fld_flag;
	break;
      }

    case TK_BUILTIN_TYPE:
      /* Fundamental type_info */
      break;

    case TK_ARRAY_TYPE:
      break;

    case TK_FUNCTION_TYPE:
      break;

    case TK_ENUMERAL_TYPE:
      break;

    case TK_POINTER_TYPE:
    case TK_POINTER_MEMBER_TYPE:
      {
	/* Pointer type_info. Adds two fields, qualification mask and
	   pointer to the pointed to type.  This is really a
	   descendant of __pbase_type_info.  */
	tree fld_mask = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				    NULL_TREE, integer_type_node);
	DECL_CHAIN (fld_mask) = fields;
	fields = fld_mask;

	tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, const_ptr_type_node);
	DECL_CHAIN (fld_ptr) = fields;
	fields = fld_ptr;

	if (ix == TK_POINTER_MEMBER_TYPE)
	  {
	    /* Add a pointer to the class too.  */
	    tree fld_cls = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, const_ptr_type_node);
	    DECL_CHAIN (fld_cls) = fields;
	    fields = fld_cls;
	  }
	break;
      }

    case TK_CLASS_TYPE:
      /* Class type_info.  No additional fields.  */
      break;

    case TK_SI_CLASS_TYPE:
      {
	/* Single public non-virtual base class. Add pointer to base
	   class.  This is really a descendant of
	   __class_type_info.  */
	tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, const_ptr_type_node);
	DECL_CHAIN (fld_ptr) = fields;
	fields = fld_ptr;
	break;
      }

    default: /* Multiple inheritance.  */
      {
	unsigned num_bases = ix - TK_VMI_CLASS_TYPES + 1;

	tree fld_flg = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, integer_type_node);
	DECL_CHAIN (fld_flg) = fields;
	fields = fld_flg;

	tree fld_cnt = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, integer_type_node);
	DECL_CHAIN (fld_cnt) = fields;
	fields = fld_cnt;

	/* Create the array of __base_class_type_info entries.  */
	tree domain = build_index_type (size_int (num_bases - 1));
	tree array = build_array_type (get_tinfo_desc (TK_BASE_TYPE)->type,
				       domain);
	tree fld_ary = build_decl (BUILTINS_LOCATION, FIELD_DECL,
				   NULL_TREE, array);
	DECL_CHAIN (fld_ary) = fields;
	fields = fld_ary;
	break;
      }
    }

  /* Generate the pseudo type name.  */
  const char *real_name = tinfo_names[ix < TK_VMI_CLASS_TYPES
				      ? ix : unsigned (TK_VMI_CLASS_TYPES)];
  size_t name_len = strlen (real_name);
  char *pseudo_name = (char *) alloca (name_len + 30);
  memcpy (pseudo_name, real_name, name_len);
  /* Those >= TK_VMI_CLASS_TYPES need a discriminator, may as well
     apply it to all.  See get_peudo_tinfo_index where we make use of
     this.  */
  sprintf (pseudo_name + name_len, "_pseudo_%d", ix);

  /* Create the pseudo type.  */
  tree pseudo_type = make_class_type (RECORD_TYPE);
  /* Pass the fields chained in reverse.  */
  finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
  CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
  DECL_CONTEXT (TYPE_NAME (pseudo_type)) = FROB_CONTEXT (global_namespace);
  DECL_TINFO_P (TYPE_NAME (pseudo_type)) = true;
  xref_basetypes (pseudo_type, /*bases=*/NULL_TREE);

  res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
  res->name = get_identifier (real_name);

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

  return res;
}

/* Return an identifying index for the pseudo type_info TYPE.
   We wrote the index at the end of the name, so just scan it from
   there.  This isn't critical, as it's only on the first use of this
   type during module stream out.  */

unsigned
get_pseudo_tinfo_index (tree type)
{
  tree name = DECL_NAME (TYPE_NAME (type));
  unsigned ix = 0, scale = 1;
  size_t len = IDENTIFIER_LENGTH (name);
  const char *ptr = IDENTIFIER_POINTER (name) + len;

  for (; *--ptr != '_'; scale *= 10)
    {
      len--;
      gcc_checking_assert (len && ISDIGIT (*ptr));
      ix += (*ptr - '0') * scale;
    }

  gcc_assert (len != IDENTIFIER_LENGTH (name));
  return ix;
}

tree
get_pseudo_tinfo_type (unsigned ix)
{
  return get_tinfo_desc (ix)->type;
}

/* We lazily create the type info types.  */

static void
create_tinfo_types (void)
{
  gcc_assert (!tinfo_descs);

  vec_alloc (tinfo_descs, TK_MAX + 20);
}

/* 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 it right away if not emitted already.  */
      if (DECL_INITIAL (tinfo) == NULL_TREE)
	{
	  bool ok = emit_tinfo_decl (tinfo);
	  gcc_assert (ok);
	  /* When compiling libsupc++.a (fundamental_type_info.o),
	     unemitted_tinfo_decls->last () will be tinfo, so pop it
	     from the vector as it is emitted now.  If one uses typeid
	     etc. in the same TU as the definition of
	     ~fundamental_type_info (), the tinfo might be emitted
	     already earlier, in such case keep it in the vector
	     (as otherwise we'd need to walk the whole vector) and
	     let c_parse_final_cleanups ignore it when it will have
	     non-NULL DECL_INITIAL.  */
	  if (unemitted_tinfo_decls->last () == tinfo)
	    unemitted_tinfo_decls->pop ();
	}
    }
}

/* 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, &char8_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,
    &bfloat16_type_node, &float16_type_node, &float32_type_node,
    &float64_type_node, &float128_type_node, &float32x_type_node,
    &float64x_type_node, &float128x_type_node, &nullptr_type_node,
    0
  };
  /* Similar, but for floating point types only which should get type info
     regardless whether they are non-NULL or NULL.  */
  static tree *const fundamentals_with_fallback[] =
  {
    &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node,
    0
  };
  int ix;

  /* Look for a defined class.  */
  tree bltn_type = lookup_qualified_name
    (abi_node, "__fundamental_type_info", LOOK_want::TYPE, false);
  if (TREE_CODE (bltn_type) != TYPE_DECL)
    return;

  bltn_type = TREE_TYPE (bltn_type);
  if (!COMPLETE_TYPE_P (bltn_type))
    return;
  tree dtor = CLASSTYPE_DESTRUCTOR (bltn_type);
  if (!dtor || DECL_EXTERNAL (dtor))
    return;

  /* All these are really builtins.  So set the location.  */
  location_t saved_loc = input_location;
  input_location = BUILTINS_LOCATION;
  doing_runtime = 1;
  tree fallback = NULL_TREE;
  for (ix = 0; fundamentals[ix]; ix++)
    emit_support_tinfo_1 (*fundamentals[ix]);
  for (ix = 0; fundamentals_with_fallback[ix]; ix++)
    if (*fundamentals_with_fallback[ix])
      emit_support_tinfo_1 (*fundamentals_with_fallback[ix]);
    else
      {
	if (fallback == NULL_TREE)
	  fallback = make_node (REAL_TYPE);
	*fundamentals_with_fallback[ix] = fallback;
	emit_support_tinfo_1 (fallback);
	*fundamentals_with_fallback[ix] = NULL_TREE;
      }
  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));

  /* Emit additional typeinfos as requested by target.  */
  targetm.emit_support_tinfos (emit_support_tinfo_1);

  input_location = saved_loc;
}

/* 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)
{
  gcc_assert (DECL_TINFO_P (decl));

  tree type = TREE_TYPE (DECL_NAME (decl));
  if (typeinfo_in_lib_p (type))
    {
      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;
      int pseudo_ix = get_pseudo_ti_index (type);
      const tinfo_s *ti = get_tinfo_desc (pseudo_ix);
      if (TREE_TYPE (decl) != ti->type)
	{
	  /* If the class became complete since we first called get_tinfo_decl,
	     its type_info descriptor may have switched from __class_type_info
	     to e.g. __si_class_type_info.  */
	  TREE_TYPE (decl) = ti->type;
	  relayout_decl (decl);
	}
      init = get_pseudo_ti_init (type, pseudo_ix);
      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
      SET_DECL_ALIGN (decl, DATA_ABI_ALIGNMENT (TREE_TYPE (decl),
						TYPE_ALIGN (TREE_TYPE (decl))));
      DECL_USER_ALIGN (decl) = true;
#endif
      return true;
    }
  else
    return false;
}

#include "gt-cp-rtti.h"
