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