Esempio n. 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);
    }
Esempio n. 2
0
bool
emit_tinfo_decl (tree decl)
{
  tree type = TREE_TYPE (DECL_NAME (decl));
  int in_library = typeinfo_in_lib_p (type);
  tree var_desc, var_init;

  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))
    {
      DECL_EXTERNAL (decl) = 0;
      var_desc = get_pseudo_ti_desc (type);
      var_init = get_pseudo_ti_init (type, var_desc);
      DECL_INITIAL (decl) = var_init;
      mark_used (decl);
      cp_finish_decl (decl, var_init, NULL_TREE, 0);
      return true;
    }
  else
    return false;
}