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; }
static tree call_eh_info () { tree fn; fn = get_identifier ("__start_cp_handler"); if (IDENTIFIER_GLOBAL_VALUE (fn)) fn = IDENTIFIER_GLOBAL_VALUE (fn); else { tree t1, t, fields[7]; /* Declare cp_eh_info * __start_cp_handler (void), as defined in exception.cc. */ /* struct cp_eh_info. This must match exception.cc. Note that this type is not pushed anywhere. */ t1= make_aggr_type (RECORD_TYPE); fields[0] = build_decl (FIELD_DECL, get_identifier ("handler_label"), ptr_type_node); fields[1] = build_decl (FIELD_DECL, get_identifier ("dynamic_handler_chain"), ptr_type_node); fields[2] = build_decl (FIELD_DECL, get_identifier ("info"), ptr_type_node); fields[3] = build_decl (FIELD_DECL, get_identifier ("table_index"), ptr_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t1, "eh_context", fields, 3, ptr_type_node); t1 = build_pointer_type (t1); t1= make_aggr_type (RECORD_TYPE); #ifdef TARG_XTENSA fields[0] = build_decl (FIELD_DECL, get_identifier ("version"), integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t1, "__eh_info", fields, 0, ptr_type_node); #else fields[0] = build_decl (FIELD_DECL, get_identifier ("match_function"), ptr_type_node); fields[1] = build_decl (FIELD_DECL, get_identifier ("language"), short_integer_type_node); fields[2] = build_decl (FIELD_DECL, get_identifier ("version"), short_integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t1, "__eh_info", fields, 2, ptr_type_node); #endif t = make_aggr_type (RECORD_TYPE); fields[0] = build_decl (FIELD_DECL, get_identifier ("eh_info"), t1); fields[1] = build_decl (FIELD_DECL, get_identifier ("value"), ptr_type_node); fields[2] = build_decl (FIELD_DECL, get_identifier ("type"), ptr_type_node); fields[3] = build_decl (FIELD_DECL, get_identifier ("cleanup"), build_pointer_type (build_function_type (ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, void_list_node)))); fields[4] = build_decl (FIELD_DECL, get_identifier ("caught"), boolean_type_node); fields[5] = build_decl (FIELD_DECL, get_identifier ("next"), build_pointer_type (t)); fields[6] = build_decl (FIELD_DECL, get_identifier ("handlers"), long_integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t, "cp_eh_info", fields, 6, ptr_type_node); t = build_pointer_type (t); /* And now the function. */ fn = push_library_fn (fn, build_function_type (t, void_list_node)); } return build_function_call (fn, NULL_TREE); }
static void create_tinfo_types (void) { gcc_assert (!ti_desc_type_node); push_nested_namespace (abi_node); /* Create the internal type_info structure. This is used as a base for the other structures. */ { tree field, fields; ti_desc_type_node = make_aggr_type (RECORD_TYPE); field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node); fields = field; field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node); TREE_CHAIN (field) = fields; fields = field; finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo", fields, NULL_TREE); TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1; } /* Fundamental type_info */ bltn_desc_type_node = create_pseudo_type_info ("__fundamental_type_info", 0, NULL); /* Array, function and enum type_info. No additional fields. */ ary_desc_type_node = create_pseudo_type_info ("__array_type_info", 0, NULL); func_desc_type_node = create_pseudo_type_info ("__function_type_info", 0, NULL); enum_desc_type_node = create_pseudo_type_info ("__enum_type_info", 0, NULL); /* Class type_info. Add a flags field. */ class_desc_type_node = create_pseudo_type_info ("__class_type_info", 0, NULL); /* Single public non-virtual base class. Add pointer to base class. This is really a descendant of __class_type_info. */ si_class_desc_type_node = create_pseudo_type_info ("__si_class_type_info", 0, build_decl (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 (FIELD_DECL, NULL_TREE, type_info_ptr_type); fields = field; field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]); TREE_CHAIN (field) = fields; fields = field; base_desc_type_node = make_aggr_type (RECORD_TYPE); finish_builtin_struct (base_desc_type_node, "__base_class_type_info_pseudo", fields, NULL_TREE); TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1; } /* General hierarchy is created as necessary in this vector. */ vmi_class_desc_type_node = make_tree_vec (10); /* Pointer type_info. Adds two fields, qualification mask and pointer to the pointed to type. This is really a descendant of __pbase_type_info. */ ptr_desc_type_node = create_pseudo_type_info ("__pointer_type_info", 0, build_decl (FIELD_DECL, NULL_TREE, integer_type_node), build_decl (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. */ ptm_desc_type_node = create_pseudo_type_info ("__pointer_to_member_type_info", 0, build_decl (FIELD_DECL, NULL_TREE, integer_type_node), build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), NULL); pop_nested_namespace (abi_node); }