diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 546 |
1 files changed, 384 insertions, 162 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 48f8d8c55fd..be5561835c8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -51,6 +51,8 @@ Boston, MA 02111-1307, USA. */ #include "debug.h" #include "timevar.h" #include "tree-flow.h" +/* APPLE LOCAL optimization pragmas 3124235/3420242 */ +#include "opts.h" static tree grokparms (cp_parameter_declarator *, tree *); static const char *redeclaration_error_message (tree, tree); @@ -229,10 +231,17 @@ int function_depth; with __attribute__((deprecated)). An object declared as __attribute__((deprecated)) suppresses warnings of uses of other deprecated items. */ +/* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */ +/* An object declared as __attribute__((unavailable)) suppresses + any reports of being declared with unavailable or deprecated + items. */ +/* APPLE LOCAL end "unavailable" attribute (radar 2809697) */ enum deprecated_states { DEPRECATED_NORMAL, DEPRECATED_SUPPRESS + /* APPLE LOCAL "unavailable" attribute (radar 2809697) */ + , DEPRECATED_UNAVAILABLE_SUPPRESS }; static enum deprecated_states deprecated_state = DEPRECATED_NORMAL; @@ -419,19 +428,20 @@ objc_mark_locals_volatile (void *enclosing_blk) struct cp_binding_level *scope; for (scope = current_binding_level; - scope && scope != enclosing_blk && scope->kind == sk_block; + /* APPLE LOCAL mainline */ + scope && scope != enclosing_blk; scope = scope->level_chain) { tree decl; + /* APPLE LOCAL begin mainline */ for (decl = scope->names; decl; decl = TREE_CHAIN (decl)) - { - if (TREE_CODE (decl) == VAR_DECL) - { - DECL_REGISTER (decl) = 0; - TREE_THIS_VOLATILE (decl) = 1; - } - } + objc_volatilize_decl (decl); + + /* Do not climb up past the current function. */ + if (scope->kind == sk_function_parms) + break; + /* APPLE LOCAL end mainline */ } } @@ -948,6 +958,12 @@ decls_match (tree newdecl, tree olddecl) } else { + /* Need to check scope for variable declaration (VAR_DECL). + For typedef (TYPE_DECL), scope is ignored. */ + if (TREE_CODE (newdecl) == VAR_DECL + && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)) + return 0; + if (TREE_TYPE (newdecl) == error_mark_node) types_match = TREE_TYPE (olddecl) == error_mark_node; else if (TREE_TYPE (olddecl) == NULL_TREE) @@ -1920,7 +1936,8 @@ redeclaration_error_message (tree newdecl, tree olddecl) /* If both functions come from different namespaces, this is not a redeclaration - this is a conflict with a used function. */ if (DECL_NAMESPACE_SCOPE_P (olddecl) - && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) + && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl) + && ! decls_match (olddecl, newdecl)) return "%qD conflicts with used function"; /* We'll complain about linkage mismatches in @@ -2846,6 +2863,45 @@ initialize_predefined_identifiers (void) if (pid->ctor_or_dtor_p) IDENTIFIER_CTOR_OR_DTOR_P (*pid->node) = 1; } + /* APPLE LOCAL begin KEXT 2.95-ptmf-compatibility --turly */ + if (flag_apple_kext) + { + /* This is snarfed from the 2.95 cp-tree.h. The mechanism is + completely different from gcc3 (see cp-tree.h, and read the + comment just above 'enum ptrmemfunc_vbit_where_t'. Sigh. + + A 2.95 pointer-to-function member type looks like: + + struct { + short __delta; + short __index; + union { + P __pfn; + short __delta2; + } __pfn_or_delta2; + }; + + where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the + pointer to member. The fields are used as follows: + + If __INDEX is -1, then the function to call is non-virtual, and + is located at the address given by __PFN. + + If __INDEX is zero, then this a NULL pointer-to-member. + + Otherwise, the function to call is virtual. Then, __DELTA2 gives + the offset from an instance of the object to the virtual function + table, and __INDEX - 1 is the index into the vtable to use to + find the function. + + The value to use for the THIS parameter is the address of the + object plus __DELTA. */ + + delta2_identifier = get_identifier ("__delta2"); + index_identifier = get_identifier ("__index"); + pfn_or_delta2_identifier = get_identifier ("__pfn_or_delta2"); + } + /* APPLE LOCAL end KEXT 2.95-ptmf-compatibility --turly */ } /* Create the predefined scalar types of C, @@ -2930,6 +2986,11 @@ cxx_init_decl_processing (void) record_builtin_type (RID_MAX, NULL, string_type_node); #endif + /* APPLE LOCAL begin KEXT 2.95-ptmf-compatibility --turly */ + if (flag_apple_kext) + delta_type_node = short_integer_type_node; + else + /* APPLE LOCAL end KEXT 2.95-ptmf-compatibility --turly */ delta_type_node = ptrdiff_type_node; vtable_index_type = ptrdiff_type_node; @@ -3037,6 +3098,13 @@ cxx_init_decl_processing (void) /* Show we use EH for cleanups. */ if (flag_exceptions) using_eh_for_cleanups (); + + /* APPLE LOCAL begin fwritable strings. */ + /* Maintain consistency. Perhaps we should just complain if they + say -fwritable-strings? */ + if (flag_writable_strings) + flag_const_strings = 0; + /* APPLE LOCAL end fwritable strings. */ } /* Generate an initializer for a function naming variable from @@ -3150,8 +3218,18 @@ builtin_function_1 (const char* name, /* Warn if a function in the namespace for users is used without an occasion to consider it declared. */ - if (name[0] != '_' || name[1] != '_') + /* APPLE LOCAL begin AltiVec */ + if ((name[0] != '_' || name[1] != '_') +#ifdef TARGET_POWERPC + /* AltiVec PIM builtins, even though they do not begin with + underscores, need not be declared either. */ + && !(class == BUILT_IN_MD + && code >= ALTIVEC_PIM__FIRST + && code <= ALTIVEC_PIM__LAST) +#endif /* TARGET_POWERPC */ + ) DECL_ANTICIPATED (decl) = 1; + /* APPLE LOCAL end AltiVec */ /* Possibly apply some default attributes to this built-in function. */ if (attrs) @@ -3188,7 +3266,10 @@ builtin_function (const char* name, { /* All builtins that don't begin with an '_' should additionally go in the 'std' namespace. */ - if (name[0] != '_') + /* APPLE LOCAL begin alloca not in std */ + /* Don't use `std' namespace for alloca. */ + if (name[0] != '_' && strcmp (name, "alloca")) + /* APPLE LOCAL end alloca not in std */ { push_namespace (std_identifier); builtin_function_1 (name, type, std_node, code, cl, libname, attrs); @@ -3216,6 +3297,11 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type) external shared object. */ DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; DECL_VISIBILITY_SPECIFIED (fn) = 1; + /* APPLE LOCAL begin optimization pragmas 3124235/3420242 */ + /* Build a mapping between this decl and the per-function options in + effect at this point. */ + record_func_cl_pf_opts_mapping (fn); + /* APPLE LOCAL end optimization pragmas 3124235/3420242 */ return fn; } @@ -3566,6 +3652,8 @@ start_decl (const cp_declarator *declarator, tree decl; tree type, tem; tree context; + /* APPLE LOCAL "unavailable" attribute (radar 2809697) */ + tree a; *pushed_scope_p = NULL_TREE; @@ -3576,10 +3664,34 @@ start_decl (const cp_declarator *declarator, have_extern_spec = false; } - /* An object declared as __attribute__((deprecated)) suppresses - warnings of uses of other deprecated items. */ + /* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */ + /* An object declared as __attribute__((unavailable)) suppresses + any reports of being declared with unavailable or deprecated + items. An object declared as __attribute__((deprecated)) + suppresses warnings of uses of other deprecated items. */ +#ifdef A_LESS_INEFFICENT_WAY /* which I really don't want to do! */ if (lookup_attribute ("deprecated", attributes)) deprecated_state = DEPRECATED_SUPPRESS; + else if (lookup_attribute ("unavailable", attributes)) + deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS; +#else /* a more efficient way doing what lookup_attribute would do */ + for (a = attributes; a; a = TREE_CHAIN (a)) + { + tree name = TREE_PURPOSE (a); + if (TREE_CODE (name) == IDENTIFIER_NODE) + if (is_attribute_p ("deprecated", name)) + { + deprecated_state = DEPRECATED_SUPPRESS; + break; + } + if (is_attribute_p ("unavailable", name)) + { + deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS; + break; + } + } +#endif + /* APPLE LOCAL end "unavailable" attribute (radar 2809697) */ attributes = chainon (attributes, prefix_attributes); @@ -3647,8 +3759,7 @@ start_decl (const cp_declarator *declarator, cplus_decl_attributes (&decl, attributes, 0); /* If #pragma weak was used, mark the decl weak now. */ - if (global_scope_p (current_binding_level)) - maybe_apply_pragma_weak (decl); + maybe_apply_pragma_weak (decl); if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) @@ -3906,7 +4017,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init) But let's leave it here to ease the eventual merge. */ int do_default = !DECL_EXTERNAL (decl); tree initializer = init ? init : DECL_INITIAL (decl); - int failure = complete_array_type (type, initializer, do_default); + int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer, + do_default); if (failure == 1) error ("initializer fails to determine size of %qD", decl); @@ -3923,9 +4035,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init) DECL_EXTERNAL (decl) = 1; } - if (pedantic && TYPE_DOMAIN (type) != NULL_TREE - && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), - integer_zero_node)) + if (failure == 3) error ("zero-size array %qD", decl); layout_decl (decl, 0); @@ -4103,13 +4213,18 @@ reshape_init_array (tree elt_type, tree max_index, tree *initp, tree new_init) { bool sized_array_p = (max_index != NULL_TREE); - HOST_WIDE_INT max_index_cst = 0; - HOST_WIDE_INT index; + unsigned HOST_WIDE_INT max_index_cst = 0; + unsigned HOST_WIDE_INT index; if (sized_array_p) - /* HWI is either 32bit or 64bit, so it must be enough to represent the - array size. */ - max_index_cst = tree_low_cst (max_index, 1); + { + if (host_integerp (max_index, 1)) + max_index_cst = tree_low_cst (max_index, 1); + /* sizetype is sign extended, not zero extended. */ + else + max_index_cst = tree_low_cst (fold_convert (size_type_node, max_index), + 1); + } /* Loop until there are no more initializers. */ for (index = 0; @@ -4126,27 +4241,16 @@ reshape_init_array (tree elt_type, tree max_index, CONSTRUCTOR_ELTS (new_init) = element_init; designated_index = TREE_PURPOSE (element_init); if (designated_index) - { + { /* Handle array designated initializers (GNU extension). */ if (TREE_CODE (designated_index) == IDENTIFIER_NODE) { error ("name %qD used in a GNU-style designated " - "initializer for an array", designated_index); + "initializer for an array", designated_index); TREE_PURPOSE (element_init) = NULL_TREE; } else - { - gcc_assert (TREE_CODE (designated_index) == INTEGER_CST); - if (sized_array_p - && tree_int_cst_lt (max_index, designated_index)) - { - error ("Designated initializer %qE larger than array " - "size", designated_index); - TREE_PURPOSE (element_init) = NULL_TREE; - } - else - index = tree_low_cst (designated_index, 1); - } + gcc_unreachable (); } } @@ -4176,6 +4280,7 @@ reshape_init (tree type, tree *initp) tree old_init_value; tree new_init; bool brace_enclosed_p; + bool string_init_p; old_init = *initp; old_init_value = (TREE_CODE (*initp) == TREE_LIST @@ -4239,6 +4344,7 @@ reshape_init (tree type, tree *initp) return old_init; } + string_init_p = false; if (TREE_CODE (old_init_value) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))) @@ -4253,6 +4359,7 @@ reshape_init (tree type, tree *initp) /* Move past the initializer. */ *initp = TREE_CHAIN (old_init); TREE_CHAIN (old_init) = NULL_TREE; + string_init_p = true; } else { @@ -4359,7 +4466,7 @@ reshape_init (tree type, tree *initp) { if (brace_enclosed_p) error ("too many initializers for %qT", type); - else if (warn_missing_braces) + else if (warn_missing_braces && !string_init_p) warning ("missing braces around initializer"); } @@ -4610,7 +4717,19 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) && DECL_IMPLICIT_INSTANTIATION (decl)) defer_p = 1; - /* If we're not deferring, go ahead and assemble the variable. */ + + /* APPLE LOCAL begin static const members 20020110 --turly */ + /* Static const members which require runtime initialisation should + not be placed in readonly memory. Avoid this by temporarily + whacking the TREE_READONLY bit. */ + if (!defer_p && init != NULL_TREE && TREE_READONLY (decl) && toplev) + { + TREE_READONLY (decl) = 0; + rest_of_decl_compilation (decl, toplev, at_eof); + TREE_READONLY (decl) = 1; + } + else + /* APPLE LOCAL end static const members 20020110 --turly */ if (!defer_p) rest_of_decl_compilation (decl, toplev, at_eof); } @@ -4749,9 +4868,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (type == error_mark_node) goto finish_end; - if (TYPE_HAS_MUTABLE_P (type)) - TREE_READONLY (decl) = 0; - if (processing_template_decl) { /* Add this declaration to the statement-tree. */ @@ -4798,16 +4914,13 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ttype = target_type (type); - /* Currently, GNU C++ puts constants in text space, making them - impossible to initialize. In the future, one would hope for - an operating system which understood the difference between - initialization and the running of a program. */ - if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)) + /* A reference will be modified here, as it is initialized. */ + if (! DECL_EXTERNAL (decl) + && TREE_READONLY (decl) + && TREE_CODE (type) == REFERENCE_TYPE) { was_readonly = 1; - if (TYPE_NEEDS_CONSTRUCTING (type) - || TREE_CODE (type) == REFERENCE_TYPE) - TREE_READONLY (decl) = 0; + TREE_READONLY (decl) = 0; } if (TREE_CODE (decl) == VAR_DECL) @@ -5342,99 +5455,41 @@ expand_static_init (tree decl, tree init) 2 if there was no information (in which case assume 0 if DO_DEFAULT). */ int -complete_array_type (tree type, tree initial_value, int do_default) +cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) { - tree maxindex = NULL_TREE; - int value = 0; + int failure; + tree type, elt_type; if (initial_value) { /* An array of character type can be initialized from a brace-enclosed string constant. */ - if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))) + if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype))) && TREE_CODE (initial_value) == CONSTRUCTOR && CONSTRUCTOR_ELTS (initial_value) && (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value))) == STRING_CST) && TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE) initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)); - - /* Note MAXINDEX is really the maximum index, one less than the - size. */ - if (TREE_CODE (initial_value) == STRING_CST) - { - int eltsize - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); - maxindex = build_int_cst (NULL_TREE, - (TREE_STRING_LENGTH (initial_value) - / eltsize) - 1); - } - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - tree elts = CONSTRUCTOR_ELTS (initial_value); - - maxindex = ssize_int (-1); - for (; elts; elts = TREE_CHAIN (elts)) - { - if (TREE_PURPOSE (elts)) - maxindex = TREE_PURPOSE (elts); - else - maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1)); - } - } - else - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - else - initial_value = NULL_TREE; - - /* Prevent further error messages. */ - maxindex = build_int_cst (NULL_TREE, 0); - } - } - - if (!maxindex) - { - if (do_default) - maxindex = build_int_cst (NULL_TREE, 0); - value = 2; } - - if (maxindex) + + failure = complete_array_type (ptype, initial_value, do_default); + + /* We can create the array before the element type is complete, which + means that we didn't have these two bits set in the original type + either. In completing the type, we are expected to propagate these + bits. See also complete_type which does the same thing for arrays + of fixed size. */ + type = *ptype; + if (TYPE_DOMAIN (type)) { - tree itype; - tree domain; - tree elt_type; - - domain = build_index_type (maxindex); - TYPE_DOMAIN (type) = domain; - - if (initial_value) - itype = TREE_TYPE (initial_value); - else - itype = NULL; - if (itype && !TYPE_DOMAIN (itype)) - TYPE_DOMAIN (itype) = domain; - /* The type of the main variant should never be used for arrays - of different sizes. It should only ever be completed with the - size of the array. */ - if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type))) - TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain; - elt_type = TREE_TYPE (type); - TYPE_NEEDS_CONSTRUCTING (type) - = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); + TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type); TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) - = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); + = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type); } - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; + return failure; } /* Return zero if something is declared to be a member of type @@ -5930,8 +5985,7 @@ grokvardecl (tree type, declare an entity with linkage. Only check this for public decls for now. */ - tree t1 = TREE_TYPE (decl); - tree t = no_linkage_check (t1, /*relaxed_p=*/false); + tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false); if (t) { if (TYPE_ANONYMOUS_P (t)) @@ -5939,31 +5993,26 @@ grokvardecl (tree type, if (DECL_EXTERN_C_P (decl)) /* Allow this; it's pretty common in C. */ ; - else if (same_type_ignoring_top_level_qualifiers_p(t1, t)) - /* This is something like "enum { a = 3 } x;", which is - well formed. The enum doesn't have "a name with no - linkage", because it has no name. See closed CWG issue - 132. - - Note that while this construct is well formed in C++03 - it is likely to become ill formed in C++0x. See open - CWG issue 389 and related issues. */ - ; else { - /* It's a typedef referring to an anonymous type. */ - pedwarn ("non-local variable %q#D uses anonymous type", + /* DRs 132, 319 and 389 seem to indicate types with + no linkage can only be used to declare extern "C" + entities. Since it's not always an error in the + ISO C++ 90 Standard, we only issue a warning. */ + warning ("non-local variable %q#D uses anonymous type", decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) - cp_pedwarn_at ("%q#D does not refer to the unqualified " - "type, so it is not used for linkage", + cp_warning_at ("%q#D does not refer to the unqualified " + "type, so it is not used for linkage", TYPE_NAME (t)); } } else - pedwarn ("non-local variable %q#D uses local type %qT", decl, t); + warning ("non-local variable %q#D uses local type %qT", decl, t); } } + else + DECL_INTERFACE_KNOWN (decl) = 1; return decl; } @@ -5994,6 +6043,37 @@ build_ptrmemfunc_type (tree type) unqualified_variant = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type)); + /* APPLE LOCAL begin KEXT 2.95-ptmf-compatibility --turly */ + if (flag_apple_kext) + { + tree u = make_aggr_type (UNION_TYPE); + SET_IS_AGGR_TYPE (u, 0); + xref_basetypes (u, NULL_TREE); + fields = build_decl (FIELD_DECL, delta2_identifier, delta_type_node); + TREE_CHAIN (fields) + = build_decl (FIELD_DECL, pfn_identifier, type); + finish_builtin_struct (u, "__ptrmemfunc_type", fields, ptr_type_node); + TYPE_NAME (u) = NULL_TREE; + + t = make_aggr_type (RECORD_TYPE); + xref_basetypes (t, NULL_TREE); + + /* Let the front-end know this is a pointer to member function... */ + TYPE_PTRMEMFUNC_FLAG (t) = 1; + /* ... and not really an aggregate. */ + SET_IS_AGGR_TYPE (t, 0); + + fields = build_decl (FIELD_DECL, pfn_or_delta2_identifier, u); + TREE_CHAIN (fields) = + build_decl (FIELD_DECL, index_identifier, delta_type_node); + TREE_CHAIN (TREE_CHAIN (fields)) = + build_decl (FIELD_DECL, delta_identifier, delta_type_node); + finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node); + } + else + { + /* APPLE LOCAL end KEXT 2.95-ptmf-compatibility --turly */ + t = make_aggr_type (RECORD_TYPE); xref_basetypes (t, NULL_TREE); @@ -6010,6 +6090,8 @@ build_ptrmemfunc_type (tree type) fields = field; finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node); + /* APPLE LOCAL KEXT 2.95-ptmf-compatibility --turly */ + } /* Zap out the name so that the back-end will give us the debugging information for this anonymous RECORD_TYPE. */ @@ -6491,6 +6573,8 @@ grokdeclarator (const cp_declarator *declarator, cp_decl_spec ds; cp_storage_class storage_class; bool unsigned_p, signed_p, short_p, long_p, thread_p; + /* APPLE LOCAL CW asm blocks */ + bool cw_asm_p; bool type_was_error_mark_node = false; signed_p = declspecs->specs[(int)ds_signed]; @@ -6498,6 +6582,8 @@ grokdeclarator (const cp_declarator *declarator, short_p = declspecs->specs[(int)ds_short]; long_p = declspecs->specs[(int)ds_long]; thread_p = declspecs->specs[(int)ds_thread]; + /* APPLE LOCAL CW asm blocks */ + cw_asm_p = declspecs->specs[(int)ds_cw_asm]; if (decl_context == FUNCDEF) funcdef_flag = 1, decl_context = NORMAL; @@ -6696,6 +6782,19 @@ grokdeclarator (const cp_declarator *declarator, type = NULL_TREE; type_was_error_mark_node = true; } + + /* APPLE LOCAL begin unavailable attribute (radar 2809697) --bowdidge */ + /* If the entire declaration is itself tagged as unavailable then + suppress reports of unavailable/deprecated items. If the + entire declaration is tagged as only deprecated we still + report unavailable uses. */ + if (type && TREE_DEPRECATED (type) && TREE_UNAVAILABLE (type)) + { + if (deprecated_state != DEPRECATED_UNAVAILABLE_SUPPRESS) + warn_deprecated_use (type); + } + else + /* APPLE LOCAL end unavailable attribute (radar 2809697) --bowdidge */ /* If the entire declaration is itself tagged as deprecated then suppress reports of deprecated items. */ if (type && TREE_DEPRECATED (type) @@ -6752,6 +6851,8 @@ grokdeclarator (const cp_declarator *declarator, "typedef", "__complex", "__thread" + /* APPLE LOCAL CW asm blocks. */ + , "asm" }; error ("duplicate %qs", decl_spec_names[(int)ds]); } @@ -6931,6 +7032,20 @@ grokdeclarator (const cp_declarator *declarator, error ("qualifiers are not allowed on declaration of %<operator %T%>", ctor_return_type); + if (TREE_CODE (type) == FUNCTION_TYPE + && type_quals != TYPE_UNQUALIFIED) + { + /* This was an error in C++98 (cv-qualifiers cannot be added to + a function type), but DR 295 makes the code well-formed by + dropping the extra qualifiers. */ + if (pedantic) + { + tree bad_type = build_qualified_type (type, type_quals); + pedwarn ("ignoring %qV qualifiers added to function type %qT", + bad_type, type); + } + type_quals = TYPE_UNQUALIFIED; + } type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) @@ -7119,9 +7234,7 @@ grokdeclarator (const cp_declarator *declarator, /* Determine the type of the entity declared by recurring on the declarator. */ - for (; - declarator && declarator->kind != cdk_id; - declarator = declarator->declarator) + for (; declarator; declarator = declarator->declarator) { const cp_declarator *inner_declarator; tree attrs; @@ -7129,8 +7242,6 @@ grokdeclarator (const cp_declarator *declarator, if (type == error_mark_node) return error_mark_node; - inner_declarator = declarator->declarator; - attrs = declarator->attributes; if (attrs) { @@ -7148,6 +7259,11 @@ grokdeclarator (const cp_declarator *declarator, attr_flags); } + if (declarator->kind == cdk_id) + break; + + inner_declarator = declarator->declarator; + switch (declarator->kind) { case cdk_array: @@ -7292,6 +7408,7 @@ grokdeclarator (const cp_declarator *declarator, } type = build_function_type (type, arg_types); + type = cp_build_qualified_type (type, quals); } break; @@ -7324,7 +7441,15 @@ grokdeclarator (const cp_declarator *declarator, && (TREE_CODE (type) == FUNCTION_TYPE || (quals && TREE_CODE (type) == METHOD_TYPE))) { - tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); + tree dummy; + + /* If the type is a FUNCTION_TYPE, pick up the + qualifiers from that function type. No other + qualifiers may be supplied. */ + if (TREE_CODE (type) == FUNCTION_TYPE) + quals = cp_type_quals (type); + + dummy = build_decl (TYPE_DECL, NULL_TREE, type); grok_method_quals (declarator->u.pointer.class_type, dummy, quals); type = TREE_TYPE (dummy); @@ -7621,11 +7746,12 @@ grokdeclarator (const cp_declarator *declarator, { if (ctype == NULL_TREE) { - if (TREE_CODE (type) != METHOD_TYPE) - error ("%Jinvalid type qualifier for non-member function type", - decl); - else + if (TREE_CODE (type) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (type); + /* Any qualifiers on a function type typedef have + already been dealt with. */ + else if (TREE_CODE (type) == FUNCTION_TYPE) + quals = TYPE_UNQUALIFIED; } if (ctype != NULL_TREE) grok_method_quals (ctype, decl, quals); @@ -7668,6 +7794,23 @@ grokdeclarator (const cp_declarator *declarator, } parms = nreverse (decls); + + if (decl_context != TYPENAME) + { + /* A cv-qualifier-seq shall only be part of the function type + for a non-static member function. [8.3.5/4 dcl.fct] */ + if (cp_type_quals (type) != TYPE_UNQUALIFIED + && (current_class_type == NULL_TREE || staticp) ) + { + error ("qualified function types cannot be used to declare %s functions", + (staticp? "static member" : "free")); + type = TYPE_MAIN_VARIANT (type); + } + + /* The qualifiers on the function type become the qualifiers on + the non-static member function. */ + quals |= cp_type_quals (type); + } } /* If this is a type name (such as, in a cast or sizeof), @@ -8199,11 +8342,26 @@ grokdeclarator (const cp_declarator *declarator, else if (storage_class == sc_static) DECL_THIS_STATIC (decl) = 1; + /* APPLE LOCAL begin CW asm blocks */ + if (cw_asm_p) + { + /* Record that this is a decl of a CW-style asm function. */ + if (flag_cw_asm_blocks) + { + DECL_CW_ASM_FUNCTION (decl) = 1; + DECL_CW_ASM_NORETURN (decl) = 0; + DECL_CW_ASM_FRAME_SIZE (decl) = -2; + } + else + error ("asm functions not enabled, use `-fasm-blocks'"); + } + /* APPLE LOCAL end CW asm blocks */ + /* Record constancy and volatility. There's no need to do this when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ if (!processing_template_decl) - c_apply_type_quals_to_decl (type_quals, decl); + cp_apply_type_quals_to_decl (type_quals, decl); return decl; } @@ -9959,7 +10117,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags) class scope, current_class_type will be NULL_TREE until set above by push_nested_class.) */ if (processing_template_decl) - decl1 = push_template_decl (decl1); + { + /* FIXME: Handle error_mark_node more gracefully. */ + tree newdecl1 = push_template_decl (decl1); + if (newdecl1 != error_mark_node) + decl1 = newdecl1; + } /* We are now in the scope of the function being defined. */ current_function_decl = decl1; @@ -9987,7 +10150,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_IGNORED_P (resdecl) = 1; DECL_RESULT (decl1) = resdecl; - c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); + cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); } /* Initialize RTL machinery. We cannot do this until @@ -10029,9 +10192,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags) parsing the body of the function. */ ; else - /* Otherwise, OLDDECL is either a previous declaration of - the same function or DECL1 itself. */ - decl1 = olddecl; + /* APPLE LOCAL begin optimization pragmas 3124235/3420242 */ + { + /* Otherwise, OLDDECL is either a previous declaration of + the same function or DECL1 itself. */ + copy_func_cl_pf_opts_mapping (decl1, olddecl); + decl1 = olddecl; + } + /* APPLE LOCAL end optimization pragmas 3124235/3420242 */ } else { @@ -10173,6 +10341,17 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_CONTEXT (cdtor_label) = current_function_decl; } + /* APPLE LOCAL begin CW asm blocks */ + /* If this was a function declared as an assembly function, change + the state to expect to see C++ decls, possibly followed by assembly + code. */ + if (DECL_CW_ASM_FUNCTION (current_function_decl)) + { + cw_asm_state = cw_asm_decls; + cw_asm_in_decl = 0; + } + /* APPLE LOCAL end CW asm blocks */ + start_fname_decls (); store_parm_decls (current_function_parms); @@ -10210,6 +10389,12 @@ start_function (cp_decl_specifier_seq *declspecs, if (global_scope_p (current_binding_level)) maybe_apply_pragma_weak (decl1); + /* APPLE LOCAL begin optimization pragmas 3124235/3420242 */ + /* Build a mapping between this decl and the per-function options in + effect at this point. */ + record_func_cl_pf_opts_mapping (decl1); + /* APPLE LOCAL end optimization pragmas 3124235/3420242 */ + if (DECL_MAIN_P (decl1)) /* main must return int. grokfndecl should have corrected it (and issued a diagnostic) if the user got it wrong. */ @@ -10910,9 +11095,11 @@ complete_vars (tree type) if (same_type_p (type, TREE_PURPOSE (*list))) { tree var = TREE_VALUE (*list); + tree type = TREE_TYPE (var); /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ - complete_type (TREE_TYPE (var)); + complete_type (type); + cp_apply_type_quals_to_decl (cp_type_quals (type), var); /* Remove this entry from the list. */ *list = TREE_CHAIN (*list); } @@ -10938,6 +11125,25 @@ cxx_maybe_build_cleanup (tree decl) tree rval; bool has_vbases = (TREE_CODE (type) == RECORD_TYPE && CLASSTYPE_VBASECLASSES (type)); + /* APPLE LOCAL begin KEXT double destructor */ + special_function_kind dtor = sfk_complete_destructor; + if (flag_apple_kext + && has_apple_kext_compatibility_attr_p (type)) + { + /* If we have a trivial operator delete (), we can go ahead and + just use the deleting destructor, sfk_deleting_destructor. */ + + if (! has_empty_operator_delete_p (type) || pedantic) + { + cp_warning_at ("'%D' is an instance of a class which does " + "not allow global or stack-based objects; it " + "does not have an empty `operator delete', and " + "so it will ** NOT ** be destructed.", decl); + return NULL_TREE; + } + dtor = sfk_deleting_destructor; + } + /* APPLE LOCAL end KEXT double destructor */ if (TREE_CODE (type) == ARRAY_TYPE) rval = decl; @@ -10952,7 +11158,8 @@ cxx_maybe_build_cleanup (tree decl) flags |= LOOKUP_NONVIRTUAL; rval = build_delete (TREE_TYPE (rval), rval, - sfk_complete_destructor, flags, 0); + /* APPLE LOCAL KEXT double destructor */ + dtor, flags, 0); return rval; } @@ -11081,7 +11288,22 @@ cxx_comdat_group (tree decl) /* For all other DECLs, the COMDAT group is the mangled name of the declaration itself. */ else - name = DECL_ASSEMBLER_NAME (decl); + { + while (DECL_THUNK_P (decl)) + { + /* If TARGET_USE_LOCAL_THUNK_ALIAS_P, use_thunk puts the thunk + into the same section as the target function. In that case + we must return target's name. */ + tree target = THUNK_TARGET (decl); + if (TARGET_USE_LOCAL_THUNK_ALIAS_P (target) + && DECL_SECTION_NAME (target) != NULL + && DECL_ONE_ONLY (target)) + decl = target; + else + break; + } + name = DECL_ASSEMBLER_NAME (decl); + } return IDENTIFIER_POINTER (name); } |