diff options
Diffstat (limited to 'contrib/gcc/cp/decl.c')
-rw-r--r-- | contrib/gcc/cp/decl.c | 585 |
1 files changed, 576 insertions, 9 deletions
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index d716ac7..9a58994 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -52,7 +52,8 @@ Boston, MA 02110-1301, USA. */ #include "timevar.h" #include "tree-flow.h" -static tree grokparms (cp_parameter_declarator *, tree *); +/* APPLE LOCAL blocks 6040305 (ce) */ +tree grokparms (cp_parameter_declarator *, tree *); static const char *redeclaration_error_message (tree, tree); static int decl_jump_unsafe (tree); @@ -3800,7 +3801,26 @@ shadow_tag (cp_decl_specifier_seq *declspecs) return t; } - + +/* APPLE LOCAL begin blocks 6339747 */ +/* Decode a block literal type, such as "int **", returning a ...FUNCTION_DECL node. */ + +tree +grokblockdecl (cp_decl_specifier_seq *type_specifiers, + const cp_declarator *declarator) +{ + tree decl; + tree attrs = type_specifiers->attributes; + + type_specifiers->attributes = NULL_TREE; + + decl = grokdeclarator (declarator, type_specifiers, BLOCKDEF, 0, &attrs); + if (attrs) + cplus_decl_attributes (&decl, attrs, 0); + return decl; +} +/* APPLE LOCAL end blocks 6339747 */ + /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ tree @@ -5002,10 +5022,15 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl)) { gcc_assert (TREE_STATIC (decl)); + /* APPLE LOCAL begin templated static data 6298605 */ /* An in-class declaration of a static data member should be - external; it is only a declaration, and not a definition. */ - if (init == NULL_TREE) - gcc_assert (DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl)); + external if the decl is accessible from outside this + translation unit (eg something not in an anonymous + namespace); it is only a declaration, and not a + definition. */ + if (init == NULL_TREE && TREE_PUBLIC (decl)) + gcc_assert (DECL_EXTERNAL (decl)); + /* APPLE LOCAL end templated static data 6298605 */ } /* We don't create any RTL for local variables. */ @@ -5160,6 +5185,367 @@ value_dependent_init_p (tree init) return false; } +/* APPLE LOCAL begin blocks 6040305 (cr) */ +#define BLOCK_ALIGN_MAX 18 +static tree block_byref_id_object_copy[BLOCK_BYREF_CURRENT_MAX*(BLOCK_ALIGN_MAX+1)]; +static tree block_byref_id_object_dispose[BLOCK_BYREF_CURRENT_MAX*(BLOCK_ALIGN_MAX+1)]; + +/** + This routine builds: + + void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, + struct Block_byref_id_object *src) { + _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_OBJECT[|BLOCK_FIELD_IS_WEAK]) // objects + _Block_object_assign(&_dest->object, _src->object, BLOCK_FIELD_IS_BLOCK[|BLOCK_FIELD_IS_WEAK]) // blocks + } */ +static void +synth_block_byref_id_object_copy_func (int flag, int kind) +{ + tree stmt; + tree dst_arg, src_arg; + tree dst_obj, src_obj; + tree call_exp; + + gcc_assert (block_byref_id_object_copy[kind]); + /* Set up: (void* _dest, void*_src) parameters. */ + dst_arg = build_decl (PARM_DECL, get_identifier ("_dst"), + ptr_type_node); + TREE_USED (dst_arg) = 1; + DECL_ARG_TYPE (dst_arg) = ptr_type_node; + src_arg = build_decl (PARM_DECL, get_identifier ("_src"), + ptr_type_node); + TREE_USED (src_arg) = 1; + DECL_ARG_TYPE (src_arg) = ptr_type_node; + /* arg_info = xcalloc (1, sizeof (struct c_arg_info)); */ + TREE_CHAIN (dst_arg) = src_arg; + /* arg_info->parms = dst_arg; */ + /* arg_info->types = tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, + ptr_type_node, + NULL_TREE)); */ + DECL_ARGUMENTS (block_byref_id_object_copy[kind]) = dst_arg; + /* function header synthesis. */ + push_function_context (); + /* start_block_helper_function (block_byref_id_object_copy[kind], true); */ + /* store_parm_decls_from (arg_info); */ + start_preparsed_function (block_byref_id_object_copy[kind], + /*attrs*/NULL_TREE, + SF_PRE_PARSED); + + /* Body of the function. */ + stmt = begin_compound_stmt (BCS_FN_BODY); + /* Build dst->object */ + dst_obj = build_indirect_object_id_exp (dst_arg); + + + /* src_obj is: _src->object. */ + src_obj = build_indirect_object_id_exp (src_arg); + /* APPLE LOCAL begin radar 6180456 */ + /* _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_OBJECT) or: + _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_BLOCK) */ + /* APPLE LOCAL begin radar 6573923 */ + /* Also add the new flag when calling _Block_object_dispose + from byref dispose helper. */ + flag |= BLOCK_BYREF_CALLER; + /* APPLE LOCAL end radar 6573923 */ + call_exp = build_block_object_assign_call_exp (build_fold_addr_expr (dst_obj), src_obj, flag); + add_stmt (call_exp); + /* APPLE LOCAL end radar 6180456 */ + + finish_compound_stmt (stmt); + /* APPLE LOCAL radar 6169580 */ + finish_function (4); + pop_function_context (); +} + +/** + This routine builds: + + void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_OBJECT[|BLOCK_FIELD_IS_WEAK]) // objects + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_BLOCK[|BLOCK_FIELD_IS_WEAK]) // blocks + } */ +static void synth_block_byref_id_object_dispose_func (int flag, int kind) +{ + tree stmt; + tree src_arg, src_obj, rel_exp; + + gcc_assert (block_byref_id_object_dispose[kind]); + /* Set up: (void *_src) parameter. */ + src_arg = build_decl (PARM_DECL, get_identifier ("_src"), + ptr_type_node); + TREE_USED (src_arg) = 1; + DECL_ARG_TYPE (src_arg) = ptr_type_node; + /* arg_info = xcalloc (1, sizeof (struct c_arg_info)); + arg_info->parms = src_arg; + arg_info->types = tree_cons (NULL_TREE, ptr_type_node, + NULL_TREE); */ + DECL_ARGUMENTS (block_byref_id_object_dispose[kind]) = src_arg; + /* function header synthesis. */ + push_function_context (); + /* start_block_helper_function (block_byref_id_object_dispose[kind], true); */ + /* store_parm_decls_from (arg_info); */ + start_preparsed_function (block_byref_id_object_dispose[kind], + /*attrs*/NULL_TREE, + SF_PRE_PARSED); + + /* Body of the function. */ + stmt = begin_compound_stmt (BCS_FN_BODY); + src_obj = build_indirect_object_id_exp (src_arg); + + /* APPLE LOCAL begin radar 6180456 */ + /* _Block_object_dispose(_src->object, BLOCK_FIELD_IS_OBJECT) or: + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_BLOCK) */ + /* APPLE LOCAL begin radar 6573923 */ + /* Also add the new flag when calling _Block_object_dispose + from byref dispose helper. */ + flag |= BLOCK_BYREF_CALLER; + /* APPLE LOCAL end radar 6573923 */ + rel_exp = build_block_object_dispose_call_exp (src_obj, flag); + /* APPLE LOCAL end radar 6180456 */ + add_stmt (rel_exp); + + finish_compound_stmt (stmt); + /* APPLE LOCAL radar 6169580 */ + finish_function (4); + pop_function_context (); +} + +static tree +block_start_struct (tree name) +{ + tree s; + /* The idea here is to mimic the actions that the C++ parser takes when + constructing 'extern "C" struct NAME {'. */ + push_lang_context (lang_name_c); + + s = xref_tag (record_type, name, ts_global, 0); + CLASSTYPE_DECLARED_CLASS (s) = 0; /* this is a 'struct', not a 'class'. */ + xref_basetypes (s, NULL_TREE); /* no base classes here! */ + + return begin_class_definition (s, NULL_TREE); +} + +static tree +block_finish_struct (tree t, tree fieldlist) +{ + tree field, next_field; + + for (field = fieldlist; field; field = next_field) + { + next_field = TREE_CHAIN (field); /* insert one field at a time; */ + TREE_CHAIN (field) = NULL_TREE; /* otherwise, grokfield croaks. */ + finish_member_declaration (field); + } + t = finish_struct (t, NULL); + pop_lang_context (); + + return t; +} + +/* new_block_byref_decl - This routine changes a 'typex x' declared variable into: + + struct __Block_byref_x { + // APPLE LOCAL radar 6244520 + void *__isa; // NULL for everything except __weak pointers + struct Block_byref_x *__forwarding; + int32_t __flags; + int32_t __size; + void *__ByrefKeepFuncPtr; // Only if variable is __block ObjC object + void *__ByrefDestroyFuncPtr; // Only if variable is __block ObjC object + typex x; + } x; +*/ + +static tree +new_block_byref_decl (tree decl) +{ + static int unique_count; + /* APPLE LOCAL radar 5847976 */ + int save_flag_objc_gc; + tree Block_byref_type; + tree fields = NULL_TREE, field; + const char *prefix = "__Block_byref_"; + char *string = (char*)alloca (strlen (IDENTIFIER_POINTER (DECL_NAME (decl))) + + strlen (prefix) + 8 /* to hold the count */); + + sprintf (string, "%s%d_%s", prefix, ++unique_count, + IDENTIFIER_POINTER (DECL_NAME (decl))); + + push_to_top_level (); + + /* Block_byref_type = start_struct (RECORD_TYPE, get_identifier (string)); */ + Block_byref_type = block_start_struct (get_identifier (string)); + + /* APPLE LOCAL begin radar 6244520 */ + /* void *__isa; */ + field = build_decl (FIELD_DECL, get_identifier ("__isa"), ptr_type_node); + fields = field; + /* APPLE LOCAL end radar 6244520 */ + + /* struct Block_byref_x *__forwarding; */ + field = build_decl (FIELD_DECL, get_identifier ("__forwarding"), + build_pointer_type (Block_byref_type)); + /* APPLE LOCAL radar 6244520 */ + chainon (fields, field); + + /* int32_t __flags; */ + field = build_decl (FIELD_DECL, get_identifier ("__flags"), + unsigned_type_node); + chainon (fields, field); + + /* int32_t __size; */ + field = build_decl (FIELD_DECL, get_identifier ("__size"), + unsigned_type_node); + chainon (fields, field); + + if (COPYABLE_BYREF_LOCAL_NONPOD (decl)) + { + /* void *__ByrefKeepFuncPtr; */ + field = build_decl (FIELD_DECL, get_identifier ("__ByrefKeepFuncPtr"), + ptr_type_node); + chainon (fields, field); + + /* void *__ByrefDestroyFuncPtr; */ + field = build_decl (FIELD_DECL, get_identifier ("__ByrefDestroyFuncPtr"), + ptr_type_node); + chainon (fields, field); + } + + /* typex x; */ + field = build_decl (FIELD_DECL, DECL_NAME (decl), TREE_TYPE (decl)); + chainon (fields, field); + + /* APPLE LOCAL begin radar 5847976 */ + /* Hack so we don't issue warning on a field_decl having __weak attribute */ + save_flag_objc_gc = flag_objc_gc; + flag_objc_gc = 0; + /* finish_struct (Block_byref_type, field_decl_chain, NULL_TREE); */ + block_finish_struct (Block_byref_type, fields); + flag_objc_gc = save_flag_objc_gc; + /* APPLE LOCAL end radar 5847976 */ + pop_from_top_level (); + + TREE_TYPE (decl) = Block_byref_type; + /* Force layout_decl to recompute these fields. */ + DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0; + layout_decl (decl, 0); + return decl; +} + +/* init_byref_decl - This routine builds the initializer for the __Block_byref_x + type in the form of: + { NULL, &x, 0, sizeof(struct __Block_byref_x), initializer-expr}; + + or: + { NULL, &x, 0, sizeof(struct __Block_byref_x)}; + when INIT is NULL_TREE + + For __block ObjC objects, it also adds "byref_keep" and "byref_destroy" + Funtion pointers. So the most general initializers would be: + + { NULL, &x, 0, sizeof(struct __Block_byref_x), &byref_keep, &byref_destroy, + &initializer-expr}; + */ +static tree +init_byref_decl (tree decl, tree init, int flag) +{ + tree initlist; + tree block_byref_type = TREE_TYPE (decl); + int size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (block_byref_type)); + unsigned flags = 0; + tree fields; + + if (COPYABLE_BYREF_LOCAL_NONPOD (decl)) + flags = BLOCK_HAS_COPY_DISPOSE; + + fields = TYPE_FIELDS (block_byref_type); + /* APPLE LOCAL begin radar 6244520 */ + initlist = tree_cons (fields, fold_convert (ptr_type_node, ((flag & BLOCK_FIELD_IS_WEAK) != 0) ? integer_one_node + : integer_zero_node), + 0); + fields = TREE_CHAIN (fields); + + initlist = tree_cons (fields, + build_unary_op (ADDR_EXPR, decl, 0), initlist); + /* APPLE LOCAL end radar 6244520 */ + fields = TREE_CHAIN (fields); + + initlist = tree_cons (fields, build_int_cst (TREE_TYPE (fields), flags), + initlist); + fields = TREE_CHAIN (fields); + initlist = tree_cons (fields, build_int_cst (TREE_TYPE (fields), size), + initlist); + fields = TREE_CHAIN (fields); + + if (COPYABLE_BYREF_LOCAL_NONPOD (decl)) + { + char name[64]; + int align = exact_log2 ((DECL_ALIGN (decl)+TYPE_ALIGN (ptr_type_node)-1) / TYPE_ALIGN (ptr_type_node)); + int kind; + if (align == -1 || align > BLOCK_ALIGN_MAX) { + error ("invalid alignment for __block variable"); + kind = 0; + } else + kind = align*BLOCK_BYREF_CURRENT_MAX + flag; + /* Add &__Block_byref_id_object_copy, &__Block_byref_id_object_dispose + initializers. */ + if (!block_byref_id_object_copy[kind]) + { + tree func_type; + push_lang_context (lang_name_c); + /* Build a void __Block_byref_id_object_copy(void*, void*) type. */ + func_type = + build_function_type (void_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, + void_list_node))); + sprintf (name, "__Block_byref_id_object_copy%d", kind); + block_byref_id_object_copy[kind] = build_helper_func_decl (get_identifier (name), + func_type); + DECL_CONTEXT (block_byref_id_object_copy[kind]) = current_function_decl; + /* Synthesize function definition. */ + synth_block_byref_id_object_copy_func (flag, kind); + pop_lang_context (); + } + initlist = tree_cons (fields, + build_fold_addr_expr (block_byref_id_object_copy[kind]), + initlist); + fields = TREE_CHAIN (fields); + + if (!block_byref_id_object_dispose[kind]) + { + tree func_type; + push_lang_context (lang_name_c); + /* Synthesize void __Block_byref_id_object_dispose (void*) and + build &__Block_byref_id_object_dispose. */ + func_type = + build_function_type (void_type_node, + tree_cons (NULL_TREE, ptr_type_node, void_list_node)); + sprintf (name, "__Block_byref_id_object_dispose%d", kind); + block_byref_id_object_dispose[kind] = build_helper_func_decl (get_identifier (name), + func_type); + DECL_CONTEXT (block_byref_id_object_dispose[kind]) = current_function_decl; + /* Synthesize function definition. */ + synth_block_byref_id_object_dispose_func (flag, kind); + pop_lang_context (); + } + initlist = tree_cons (fields, + build_fold_addr_expr (block_byref_id_object_dispose[kind]), + initlist); + fields = TREE_CHAIN (fields); + } + + if (init) + { + init = digest_init (TREE_TYPE (fields), init); + initlist = tree_cons (fields, init, initlist); + } + init = build_constructor_from_list (block_byref_type, nreverse (initlist)); + return init; +} +/* APPLE LOCAL end blocks 6040305 (cr) */ + /* Finish processing of a declaration; install its line number and initial value. If the length of an array type is not known before, @@ -5295,6 +5681,17 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl))) error ("%qD cannot be thread-local because it has non-POD type %qT", decl, TREE_TYPE (decl)); + /* APPLE LOCAL begin blocks 6040305 (cq) */ + if (COPYABLE_BYREF_LOCAL_VAR (decl)) { + if (DECL_EXTERNAL (decl) || TREE_STATIC (decl)) + { + error ("__block attribute on %q+D not allowed, only allowed on local variables", decl); + COPYABLE_BYREF_LOCAL_VAR (decl) = 0; + COPYABLE_BYREF_LOCAL_NONPOD (decl) = 0; + } + } + /* APPLE LOCAL end blocks 6040305 (cq) */ + /* If this is a local variable that will need a mangled name, register it now. We must do this before processing the initializer for the variable, since the initialization might @@ -5760,6 +6157,16 @@ expand_static_init (tree decl, tree init) && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) return; + /* APPLE LOCAL begin radar 5733674 */ + if (c_dialect_objc () && flag_objc_gc && init && TREE_CODE (init) == INIT_EXPR) + { + tree result = objc_generate_write_barrier (TREE_OPERAND (init, 0), + INIT_EXPR, TREE_OPERAND (init, 1)); + if (result) + init = result; + } + /* APPLE LOCAL end radar 5733674 */ + if (DECL_FUNCTION_SCOPE_P (decl)) { /* Emit code to perform this initialization but once. */ @@ -7235,6 +7642,8 @@ grokdeclarator (const cp_declarator *declarator, case cdk_pointer: case cdk_reference: case cdk_ptrmem: + /* APPLE LOCAL blocks 6040305 */ + case cdk_block_pointer: break; case cdk_error: @@ -7930,6 +8339,33 @@ grokdeclarator (const cp_declarator *declarator, ctype = NULL_TREE; break; + /* APPLE LOCAL begin blocks 6040305 (cj) */ + case cdk_block_pointer: + if (TREE_CODE (type) != FUNCTION_TYPE) + { + error ("block pointer to non-function type is invalid"); + type = error_mark_node; + } + else + { + /* We now know that the TYPE_QUALS don't apply to the decl, + but to the target of the pointer. */ + type_quals = TYPE_UNQUALIFIED; + + type = build_block_pointer_type (type); + + if (declarator->u.pointer.qualifiers) + { + type + = cp_build_qualified_type (type, + declarator->u.pointer.qualifiers); + type_quals = cp_type_quals (type); + } + } + ctype = NULL_TREE; + break; + /* APPLE LOCAL end blocks 6040305 (cj) */ + case cdk_error: break; @@ -8121,6 +8557,38 @@ grokdeclarator (const cp_declarator *declarator, } } + /* APPLE LOCAL begin blocks 6339747 */ + if (decl_context == BLOCKDEF) + { + tree decl; + + if (type == error_mark_node) + return error_mark_node; + + if (TREE_CODE (type) != FUNCTION_TYPE) + { + tree t = make_node (FUNCTION_TYPE); + + if (TREE_CODE (type) == ARRAY_TYPE) + { + error ("block declared as returning an array"); + return error_mark_node; + } + + TYPE_ARG_TYPES (t) = void_list_node; + TREE_TYPE (t) = type; + type = t; + parms = NULL_TREE; + } + + if (raises) + type = build_exception_variant (type, raises); + decl = build_lang_decl (FUNCTION_DECL, NULL_TREE, type); + DECL_ARGUMENTS (decl) = parms; + return decl; + } + /* APPLE LOCAL end blocks 6339747 */ + /* If this is declaring a typedef name, return a TYPE_DECL. */ if (declspecs->specs[(int)ds_typedef] && decl_context != TYPENAME) { @@ -8973,7 +9441,8 @@ check_default_argument (tree decl, tree arg) *PARMS is set to the chain of PARM_DECLs created. */ -static tree +/* APPLE LOCAL blocks 6040305 (ce) */ +tree grokparms (cp_parameter_declarator *first_parm, tree *parms) { tree result = NULL_TREE; @@ -10915,6 +11384,82 @@ start_preparsed_function (tree decl1, tree attrs, int flags) } +/* APPLE LOCAL begin warn missing prototype 6261539 */ +static bool +fn_previously_found (tree decl, tree olddecl) +{ + int types_match; + + if (olddecl == 0) + return false; + + if (TREE_CODE (olddecl) == OVERLOAD) + { + if (OVL_CHAIN (olddecl) == NULL_TREE) + olddecl = OVL_CURRENT (olddecl); + else + { + tree match; + for (match = olddecl; match; match = OVL_NEXT (match)) + { + if (fn_previously_found (decl, OVL_CURRENT (match))) + return true; + } + return false; + } + } + + /* Don't warn about previously erroneous things that have the same + name. */ + if (TREE_TYPE (olddecl) == error_mark_node) + return true; + + /* Internally defined things still need a prototype to escape the + warning. */ + if (DECL_ARTIFICIAL (olddecl)) + return false; + + if (TREE_CODE (olddecl) != FUNCTION_DECL) + return false; + + /* These will match or error, don't also spew prototype warnings. */ + if (DECL_EXTERN_C_P (olddecl) + && DECL_EXTERN_C_P (decl)) + return true; + + /* These will match or error, don't also spew prototype warnings. */ + if (compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)), + TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) + return true; + + types_match = decls_match (decl, olddecl); + + if (types_match) + return true; + + return false; +} + +inline static void +check_missing_prototype (tree decl) +{ + if (warn_missing_prototypes + && namespace_bindings_p () + && TREE_PUBLIC (decl) + && !DECL_MAIN_P (decl) + && DECL_NON_THUNK_FUNCTION_P (decl) + && ! DECL_FUNCTION_MEMBER_P (decl) + && DECL_NAMESPACE_SCOPE_P (decl) + && ! decl_anon_ns_mem_p (decl) + && ! DECL_DECLARED_INLINE_P (decl)) + { + tree olddecl = namespace_binding (DECL_NAME (decl), DECL_CONTEXT (decl)); + if (!fn_previously_found (decl, olddecl)) + warning (OPT_Wmissing_prototypes, "no previous prototype for %q+D", decl); + } +} +/* APPLE LOCAL end warn missing prototype 6261539 */ + /* Like start_preparsed_function, except that instead of a FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR. @@ -11259,6 +11804,8 @@ finish_function (int flags) tree fndecl = current_function_decl; tree fntype, ctype = NULL_TREE; int inclass_inline = (flags & 2) != 0; + /* APPLE LOCAL radar 6169580 */ + int in_blocks_helper_function = (flags & 4) != 0; int nested; /* When we get some parse errors, we can end up without a @@ -11452,7 +11999,8 @@ finish_function (int flags) maybe_end_member_template_processing (); /* Leave the scope of the class. */ - if (ctype) + /* APPLE LOCAL radar 6169580 */ + if (ctype && !in_blocks_helper_function) pop_nested_class (); --function_depth; @@ -11678,13 +12226,32 @@ cxx_maybe_build_cleanup (tree decl) { tree type = TREE_TYPE (decl); - if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) + /* APPLE LOCAL begin omit calls to empty destructors 5559195 */ + tree dtor = NULL_TREE; + bool build_cleanup = false; + + if (TREE_CODE (type) == RECORD_TYPE) + dtor = CLASSTYPE_DESTRUCTORS (type); + + if (type != error_mark_node) { + if (TREE_CODE (type) == RECORD_TYPE) + /* For RECORD_TYPEs, we can refer to more precise flags than + TYPE_HAS_NONTRIVIAL_DESTRUCTOR. */ + build_cleanup = (dtor && TREE_PRIVATE (dtor)) + || CLASSTYPE_HAS_NONTRIVIAL_DESTRUCTOR_BODY (type) + || CLASSTYPE_DESTRUCTOR_NONTRIVIAL_BECAUSE_OF_BASE (type); + else + build_cleanup = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type); + } + + if (build_cleanup) + { + /* APPLE LOCAL end omit calls to empty destructors 5559195 */ int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; tree rval; bool has_vbases = (TREE_CODE (type) == RECORD_TYPE && CLASSTYPE_VBASECLASSES (type)); - if (TREE_CODE (type) == ARRAY_TYPE) rval = decl; else |