const struct _prop_list_t * const properties;
const uint32_t size;
const uint32_t flags;
+ const char ** extended_method_types;
+ const char * demangled_name;
+ const struct _prop_list_t * class_properties;
}
*/
static void
/* const uint32_t flags; */
add_field_decl (integer_type_node, "flags", &chain);
+ /* const char **extendedMethodTypes; */
+ tree ptr_to_ptr_to_char = build_pointer_type (string_type_node);
+ add_field_decl (ptr_to_ptr_to_char, "extended_method_types", &chain);
+
+ /* const char *demangledName; */
+ add_field_decl (string_type_node, "demangled_name", &chain);
+
+ /* const struct _prop_list_t *class_properties; */
+ add_field_decl (objc_prop_list_ptr, "class_properties", &chain);
+
objc_finish_struct (objc_v2_protocol_template, decls);
}
objc_method_prototype_template which is missing this field. */
static tree
generate_v2_meth_descriptor_table (tree chain, tree protocol,
- const char *prefix, tree attr)
+ const char *prefix, tree attr,
+ vec<tree>& all_meths)
{
- tree method_list_template, initlist, decl, methods;
+ tree method_list_template, initlist, decl;
int size, entsize;
vec<constructor_elt, va_gc> *v = NULL;
char buf[BUFSIZE];
if (!chain || !prefix)
return NULL_TREE;
- methods = chain;
+ tree method = chain;
size = 0;
- while (methods)
+ while (method)
{
- if (! METHOD_ENCODING (methods))
- METHOD_ENCODING (methods) = encode_method_prototype (methods);
- methods = TREE_CHAIN (methods);
+ if (! METHOD_ENCODING (method))
+ METHOD_ENCODING (method) = encode_method_prototype (method);
+ all_meths.safe_push (method);
+ method = TREE_CHAIN (method);
size++;
}
return decl;
}
+static tree
+generate_v2_meth_type_list (vec<tree>& all_meths, tree protocol,
+ const char *prefix)
+{
+ if (all_meths.is_empty () || !prefix)
+ return NULL_TREE;
+
+ unsigned size = all_meths.length ();
+ tree list_type = build_sized_array_type (string_type_node, size);
+ char *nam;
+ asprintf (&nam, "%s_%s", prefix,
+ IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
+ tree decl = start_var_decl (list_type, nam);
+ free (nam);
+ OBJCMETA (decl, objc_meta, meta_base);
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ for (unsigned i = 0; i < size; ++i)
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ add_objc_string (METHOD_ENCODING (all_meths[i]),
+ meth_var_types));
+ finish_var_decl (decl, objc_build_constructor (list_type, v));
+ return decl;
+}
+
/* This routine builds the initializer list to initialize the 'struct
_prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */
build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
tree inst_methods, tree class_methods,
tree opt_ins_meth, tree opt_cls_meth,
- tree property_list)
+ tree property_list, tree ext_meth_types,
+ tree demangled_name, tree class_prop_list)
{
tree expr, ttyp;
location_t loc;
/* const uint32_t flags; = 0 */
CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node);
- return objc_build_constructor (type, inits);
+ ttyp = build_pointer_type (string_type_node);
+ if (ext_meth_types)
+ expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, ext_meth_types, 0));
+ else
+ expr = convert (ttyp, null_pointer_node);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+
+ ttyp = string_type_node;
+ if (demangled_name)
+ expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, demangled_name, 0));
+ else
+ expr = convert (ttyp, null_pointer_node);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+
+ ttyp = objc_prop_list_ptr;
+ if (class_prop_list)
+ expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_prop_list, 0));
+ else
+ expr = convert (ttyp, null_pointer_node);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+
+ return objc_build_constructor (type, inits);
}
/* Main routine to build all meta data for all protocols used in a
loc = DECL_SOURCE_LOCATION (decl);
some = true;
+ vec<tree> all_meths = vNULL;
inst_meth =
generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
"_OBJC_ProtocolInstanceMethods",
- meta_proto_nst_meth);
+ meta_proto_nst_meth, all_meths);
class_meth =
generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
"_OBJC_ProtocolClassMethods",
- meta_proto_cls_meth);
+ meta_proto_cls_meth, all_meths);
opt_inst_meth =
generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p,
- "_OBJC_OptProtocolInstMethods",
- meta_proto_nst_meth);
+ "_OBJC_ProtocolOptInstMethods",
+ meta_proto_nst_meth, all_meths);
opt_class_meth =
generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p,
- "_OBJC_OptProtocolClassMethods",
- meta_proto_cls_meth);
+ "_OBJC_ProtocolOptClassMethods",
+ meta_proto_cls_meth, all_meths);
if (PROTOCOL_LIST (p))
refs_decl = generate_v2_protocol_list (p, NULL_TREE);
props = generate_v2_property_table (p, NULL_TREE);
+ tree ext_meth_types
+ = generate_v2_meth_type_list (all_meths, p,
+ "_OBJC_ProtocolMethodTypes");
+ tree demangled_name = NULL_TREE;
+ tree class_prop_list = NULL_TREE;
+
initlist = build_v2_protocol_initializer (TREE_TYPE (decl),
protocol_name_expr, refs_expr,
inst_meth, class_meth,
opt_inst_meth, opt_class_meth,
- props);
+ props, ext_meth_types,
+ demangled_name,class_prop_list);
finish_var_decl (decl, initlist);
objc_add_to_protocol_list (p, decl);
+ all_meths.truncate (0);
}
if (some)