+/* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
+ current class. */
+#ifdef OBJCPLUS
+static void
+objc_generate_cxx_ctor_or_dtor (bool dtor)
+{
+ tree fn, body, compound_stmt, ivar;
+
+ /* - (id) .cxx_construct { ... return self; } */
+ /* - (void) .cxx_construct { ... } */
+
+ objc_set_method_type (MINUS_EXPR);
+ objc_start_method_definition
+ (objc_build_method_signature (build_tree_list (NULL_TREE,
+ dtor
+ ? void_type_node
+ : objc_object_type),
+ get_identifier (dtor
+ ? TAG_CXX_DESTRUCT
+ : TAG_CXX_CONSTRUCT),
+ make_node (TREE_LIST),
+ false));
+ body = begin_function_body ();
+ compound_stmt = begin_compound_stmt (0);
+
+ ivar = CLASS_IVARS (implementation_template);
+ /* Destroy ivars in reverse order. */
+ if (dtor)
+ ivar = nreverse (copy_list (ivar));
+
+ for (; ivar; ivar = TREE_CHAIN (ivar))
+ {
+ if (TREE_CODE (ivar) == FIELD_DECL)
+ {
+ tree type = TREE_TYPE (ivar);
+
+ /* Call the ivar's default constructor or destructor. Do not
+ call the destructor unless a corresponding constructor call
+ has also been made (or is not needed). */
+ if (IS_AGGR_TYPE (type)
+ && (dtor
+ ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && (!TYPE_NEEDS_CONSTRUCTING (type)
+ || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
+ : (TYPE_NEEDS_CONSTRUCTING (type)
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
+ finish_expr_stmt
+ (build_special_member_call
+ (build_ivar_reference (DECL_NAME (ivar)),
+ dtor ? complete_dtor_identifier : complete_ctor_identifier,
+ NULL_TREE, type, LOOKUP_NORMAL));
+ }
+ }
+
+ /* The constructor returns 'self'. */
+ if (!dtor)
+ finish_return_stmt (self_decl);
+
+ finish_compound_stmt (compound_stmt);
+ finish_function_body (body);
+ fn = current_function_decl;
+ finish_function ();
+ objc_finish_method_definition (fn);
+}
+
+/* The following routine will examine the current @interface for any
+ non-POD C++ ivars requiring non-trivial construction and/or
+ destruction, and then synthesize special '- .cxx_construct' and/or
+ '- .cxx_destruct' methods which will run the appropriate
+ construction or destruction code. Note that ivars inherited from
+ super-classes are _not_ considered. */
+static void
+objc_generate_cxx_cdtors (void)
+{
+ bool need_ctor = false, need_dtor = false;
+ tree ivar;
+
+ /* We do not want to do this for categories, since they do not have
+ their own ivars. */
+
+ if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
+ return;
+
+ /* First, determine if we even need a constructor and/or destructor. */
+
+ for (ivar = CLASS_IVARS (implementation_template); ivar;
+ ivar = TREE_CHAIN (ivar))
+ {
+ if (TREE_CODE (ivar) == FIELD_DECL)
+ {
+ tree type = TREE_TYPE (ivar);
+
+ if (IS_AGGR_TYPE (type))
+ {
+ if (TYPE_NEEDS_CONSTRUCTING (type)
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
+ /* NB: If a default constructor is not available, we will not
+ be able to initialize this ivar; the add_instance_variable()
+ routine will already have warned about this. */
+ need_ctor = true;
+
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && (!TYPE_NEEDS_CONSTRUCTING (type)
+ || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
+ /* NB: If a default constructor is not available, we will not
+ call the destructor either, for symmetry. */
+ need_dtor = true;
+ }
+ }
+ }
+
+ /* Generate '- .cxx_construct' if needed. */
+
+ if (need_ctor)
+ objc_generate_cxx_ctor_or_dtor (false);
+
+ /* Generate '- .cxx_destruct' if needed. */
+
+ if (need_dtor)
+ objc_generate_cxx_ctor_or_dtor (true);
+
+ /* The 'imp_list' variable points at an imp_entry record for the current
+ @implementation. Record the existence of '- .cxx_construct' and/or
+ '- .cxx_destruct' methods therein; it will be included in the
+ metadata for the class. */
+ if (flag_next_runtime)
+ imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
+}
+#endif
+