summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/decl.c')
-rw-r--r--contrib/gcc/cp/decl.c585
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
OpenPOWER on IntegriCloud