Exemple #1
0
tree
get_tinfo_decl (tree type)
{
    tree name;
    tree d;

    if (COMPLETE_TYPE_P (type)
            && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
    {
        error ("cannot create type information for type %qT because "
               "its size is variable",
               type);
        return error_mark_node;
    }

    if (TREE_CODE (type) == METHOD_TYPE)
        type = build_function_type (TREE_TYPE (type),
                                    TREE_CHAIN (TYPE_ARG_TYPES (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)
    {
        tree var_desc = get_pseudo_ti_desc (type);

        d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
        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;
#ifdef KEY /* g++ does not actually ignore it (note push operation below),
              so we cannot either */
        if (!flag_spin_file)
#endif
            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;
        if (CLASS_TYPE_P (type))
            CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
        set_linkage_according_to_type (type, d);
        pushdecl_top_level_and_finish (d, NULL_TREE);

        /* Add decl to the global array of tinfo decls.  */
        VEC_safe_push (tree, unemitted_tinfo_decls, d);
    }
Exemple #2
0
static tree
create_pseudo_type_info (const char *real_name, int ident, ...)
{
  tree pseudo_type;
  char *pseudo_name;
  tree fields;
  tree field_decl;
  tree result;
  va_list ap;

  va_start (ap, ident);

  /* Generate the pseudo type name.  */
  pseudo_name = alloca (strlen (real_name) + 30);
  strcpy (pseudo_name, real_name);
  strcat (pseudo_name, "_pseudo");
  if (ident)
    sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
  
  /* First field is the pseudo type_info base class.  */
  fields = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
  
  /* Now add the derived fields.  */
  while ((field_decl = va_arg (ap, tree)))
    {
      TREE_CHAIN (field_decl) = fields;
      fields = field_decl;
    }
  
  /* Create the pseudo type.  */
  pseudo_type = make_aggr_type (RECORD_TYPE);
  finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
  CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;

  result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
  TINFO_REAL_NAME (result) = get_identifier (real_name);
  TINFO_PSEUDO_TYPE (result) =
    cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
  
  va_end (ap);
  return result;
}