aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c378
1 files changed, 263 insertions, 115 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 0b7b97ede23..2e20d5e4c0c 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -225,17 +225,8 @@ struct c_binding GTY((chain_next ("%h.prev")))
#define I_LABEL_DECL(node) \
(I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
-/* Each C symbol points to three linked lists of c_binding structures.
- These describe the values of the identifier in the three different
- namespaces defined by the language. */
-
-struct lang_identifier GTY(())
-{
- struct c_common_identifier common_id;
- struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */
- struct c_binding *tag_binding; /* struct/union/enum tags */
- struct c_binding *label_binding; /* labels */
-};
+/* APPLE LOCAL mainline */
+/* Definition of 'struct lang_identifier' moved to c-tree.h. */
/* Validate c-lang.c's assumptions. */
extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
@@ -414,10 +405,17 @@ static void layout_array_type (tree);
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
deprecated items. */
+/* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */
+/* Also add an __attribute__((unavailable)). 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;
@@ -529,7 +527,7 @@ c_finish_incomplete_decl (tree decl)
{
warning ("%Jarray %qD assumed to have one element", decl, decl);
- complete_array_type (type, NULL_TREE, 1);
+ complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
layout_decl (decl, 0);
}
@@ -558,15 +556,8 @@ objc_mark_locals_volatile (void *enclosing_blk)
scope = scope->outer)
{
for (b = scope->bindings; b; b = b->prev)
- {
- if (TREE_CODE (b->decl) == VAR_DECL
- || TREE_CODE (b->decl) == PARM_DECL)
- {
- C_DECL_REGISTER (b->decl) = 0;
- DECL_REGISTER (b->decl) = 0;
- TREE_THIS_VOLATILE (b->decl) = 1;
- }
- }
+ /* APPLE LOCAL mainline */
+ objc_volatilize_decl (b->decl);
/* Do not climb up past the current function. */
if (scope->function_body)
@@ -1043,8 +1034,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
tree newargs, oldargs;
int i;
- /* ??? Elsewhere TYPE_MAIN_VARIANT is not used in this context. */
-#define END_OF_ARGLIST(t) (TYPE_MAIN_VARIANT (t) == void_type_node)
+#define END_OF_ARGLIST(t) ((t) == void_type_node)
oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype);
newargs = TYPE_ARG_TYPES (newtype);
@@ -1052,8 +1042,8 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
for (;;)
{
- tree oldargtype = TREE_VALUE (oldargs);
- tree newargtype = TREE_VALUE (newargs);
+ tree oldargtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs));
+ tree newargtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs));
if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype))
break;
@@ -1228,12 +1218,68 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
}
else
{
+ /* APPLE LOCAL begin disable typechecking for SPEC --dbj */
+ /* Accept incompatible function declarations, and incompatible
+ global variables provided they are in different files.
+ (Would be nice to check this for functions also, but
+ context is not set for them.) */
+ void (*err) (const char*, ...);
+ if (disable_typechecking_for_spec_flag
+ && TREE_PUBLIC (olddecl)
+ && TREE_PUBLIC (newdecl)
+ && ((TREE_CODE (olddecl) == VAR_DECL
+ && TREE_CODE (newdecl) == VAR_DECL
+ && !same_translation_unit_p (olddecl, newdecl))
+ || (TREE_CODE (olddecl) == FUNCTION_DECL
+ && TREE_CODE (newdecl) == FUNCTION_DECL)))
+ err = warning;
+ else
+ err = error;
if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype))
- error ("%J conflicting type qualifiers for %qD", newdecl, newdecl);
+ err ("%J conflicting type qualifiers for %qD", newdecl, newdecl);
else
- error ("%Jconflicting types for %qD", newdecl, newdecl);
+ err ("%Jconflicting types for %qD", newdecl, newdecl);
diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
- locate_old_decl (olddecl, error);
+ locate_old_decl (olddecl, *err);
+ /* In the case where we're being lenient, two trees will
+ continue to exist, which represent the same variable.
+ These are currently never used in the same function, but
+ watch out for inlining. */
+ if (err == warning
+ && TREE_CODE (olddecl) == VAR_DECL)
+ {
+ HOST_WIDE_INT newalias;
+ /* To prevent aliasing problems,
+ make both of them have the same alias class right now. */
+ if (TYPE_ALIAS_SET_KNOWN_P (oldtype))
+ {
+ newalias = TYPE_ALIAS_SET (oldtype);
+ if (TYPE_ALIAS_SET_KNOWN_P (newtype)
+ && newalias != TYPE_ALIAS_SET (oldtype))
+ internal_error ("%Jalias set conflict for '%D'",
+ newdecl, newdecl);
+ }
+ else if (TYPE_ALIAS_SET_KNOWN_P (newtype))
+ newalias = TYPE_ALIAS_SET (newtype);
+ else
+ newalias = new_alias_set ();
+ TYPE_ALIAS_SET (oldtype) = newalias;
+ TYPE_ALIAS_SET (newtype) = newalias;
+ /* Set a marker bit so that only one of them gets emitted
+ to the output file. I think this only matters if the
+ sizes are different, in which case we must emit the larger.
+ If a size is unknown, we can mark that one. */
+ if (!DECL_SIZE (newdecl))
+ DECL_DUPLICATE_DECL (newdecl) = 1;
+ else if (!DECL_SIZE (olddecl))
+ DECL_DUPLICATE_DECL (olddecl) = 1;
+ else if (tree_int_cst_lt (DECL_SIZE (newdecl),
+ DECL_SIZE (olddecl)))
+ DECL_DUPLICATE_DECL (newdecl) = 1;
+ else
+ DECL_DUPLICATE_DECL (olddecl) = 1;
+ }
+ /* APPLE LOCAL end disable typechecking for SPEC --dbj */
return false;
}
}
@@ -1646,6 +1692,12 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
if (TREE_DEPRECATED (newdecl))
TREE_DEPRECATED (olddecl) = 1;
+ /* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */
+ /* Merge unavailableness. */
+ if (TREE_UNAVAILABLE (newdecl))
+ TREE_UNAVAILABLE (olddecl) = 1;
+ /* APPLE LOCAL end "unavailable" attribute (radar 2809697) */
+
/* Keep source location of definition rather than declaration. */
if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
@@ -2252,7 +2304,8 @@ implicitly_declare (tree functionid)
implicit_decl_warning (functionid, decl);
C_DECL_IMPLICIT (decl) = 1;
}
- if (DECL_BUILT_IN (decl))
+ /* APPLE LOCAL disable typechecking for SPEC --dbj */
+ if (DECL_BUILT_IN (decl) || disable_typechecking_for_spec_flag)
{
newtype = build_type_attribute_variant (newtype,
TYPE_ATTRIBUTES
@@ -2440,6 +2493,7 @@ define_label (location_t location, tree name)
if there is a containing function with a declared label with
the same name. */
tree label = I_LABEL_DECL (name);
+ struct c_label_list *nlist;
if (label
&& ((DECL_CONTEXT (label) == current_function_decl
@@ -2456,6 +2510,8 @@ define_label (location_t location, tree name)
/* The label has been used or declared already in this function,
but not defined. Update its location to point to this
definition. */
+ if (C_DECL_UNDEFINABLE_STMT_EXPR (label))
+ error ("%Jjump into statement expression", label);
DECL_SOURCE_LOCATION (label) = location;
}
else
@@ -2473,6 +2529,11 @@ define_label (location_t location, tree name)
"identifier %qs conflicts", &location,
IDENTIFIER_POINTER (name));
+ nlist = XOBNEW (&parser_obstack, struct c_label_list);
+ nlist->next = label_context_stack->labels_def;
+ nlist->label = label;
+ label_context_stack->labels_def = nlist;
+
/* Mark label as having been defined. */
DECL_INITIAL (label) = error_mark_node;
return label;
@@ -2703,7 +2764,17 @@ builtin_function (const char *name, tree type, int function_code,
/* Builtins in the implementation namespace are made visible without
needing to be explicitly declared. See push_file_scope. */
- if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
+ /* APPLE LOCAL begin AltiVec */
+ if ((name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
+#ifdef TARGET_POWERPC
+ /* AltiVec PIM builtins, even though they do not begin with
+ underscores, need not be declared either. */
+ || (cl == BUILT_IN_MD
+ && function_code >= ALTIVEC_PIM__FIRST
+ && function_code <= ALTIVEC_PIM__LAST)
+#endif /* TARGET_POWERPC */
+ )
+ /* APPLE LOCAL end AltiVec */
{
TREE_CHAIN (decl) = visible_builtins;
visible_builtins = decl;
@@ -2990,8 +3061,37 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
/* 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 */
+ tree a;
+
+ 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) */
decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized, NULL);
@@ -3178,14 +3278,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
&& TYPE_DOMAIN (type) == 0
&& TREE_CODE (decl) != TYPE_DECL)
{
- int do_default
+ bool do_default
= (TREE_STATIC (decl)
/* Even if pedantic, an external linkage array
may have incomplete type at first. */
? pedantic && !TREE_PUBLIC (decl)
: !DECL_EXTERNAL (decl));
int failure
- = complete_array_type (type, DECL_INITIAL (decl), do_default);
+ = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl),
+ do_default);
/* Get the completed type made by complete_array_type. */
type = TREE_TYPE (decl);
@@ -3206,14 +3307,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
}
-
- /* TYPE_MAX_VALUE is always one less than the number of elements
- in the array, because we start counting at zero. Therefore,
- warn only if the value is less than zero. */
- else if (pedantic && TYPE_DOMAIN (type) != 0
- && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+ else if (failure == 3)
error ("%Jzero or negative size array %qD", decl, decl);
+ if (DECL_INITIAL (decl))
+ TREE_TYPE (DECL_INITIAL (decl)) = type;
+
layout_decl (decl, 0);
}
@@ -3266,8 +3365,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
}
/* If #pragma weak was used, mark the decl weak now. */
- if (current_scope == file_scope)
- maybe_apply_pragma_weak (decl);
+ maybe_apply_pragma_weak (decl);
/* If this is a variable definition, determine its ELF visibility. */
if (TREE_CODE (decl) == VAR_DECL
@@ -3501,17 +3599,19 @@ build_compound_literal (tree type, tree init)
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
{
- int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
-
+ int failure = complete_array_type (&TREE_TYPE (decl),
+ DECL_INITIAL (decl), true);
gcc_assert (!failure);
+
+ type = TREE_TYPE (decl);
+ TREE_TYPE (DECL_INITIAL (decl)) = type;
}
- type = TREE_TYPE (decl);
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
return error_mark_node;
stmt = build_stmt (DECL_EXPR, decl);
- complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+ complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
TREE_SIDE_EFFECTS (complit) = 1;
layout_decl (decl, 0);
@@ -3537,73 +3637,6 @@ build_compound_literal (tree type, tree init)
return complit;
}
-/* Make TYPE a complete type based on INITIAL_VALUE.
- Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
- 2 if there was no information (in which case assume 1 if DO_DEFAULT). */
-
-int
-complete_array_type (tree type, tree initial_value, int do_default)
-{
- tree maxindex = NULL_TREE;
- int value = 0;
-
- if (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 = build_int_cst (NULL_TREE, -1);
- for (; elts; elts = TREE_CHAIN (elts))
- {
- if (TREE_PURPOSE (elts))
- maxindex = TREE_PURPOSE (elts);
- else
- maxindex = fold (build2 (PLUS_EXPR, integer_type_node,
- maxindex, integer_one_node));
- }
- }
- else
- {
- /* Make an error message unless that happened already. */
- if (initial_value != error_mark_node)
- value = 1;
-
- /* 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)
- {
- TYPE_DOMAIN (type) = build_index_type (maxindex);
-
- gcc_assert (TREE_TYPE (maxindex));
- }
-
- /* Lay out the type now that we can get the real answer. */
-
- layout_type (type);
-
- return value;
-}
-
/* Determine whether TYPE is a structure with a flexible array member,
or a union containing such a structure (possibly recursively). */
@@ -3652,7 +3685,8 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
/* Detect and ignore out of range field width and process valid
field widths. */
- if (TREE_CODE (*width) != INTEGER_CST)
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (*width))
+ || TREE_CODE (*width) != INTEGER_CST)
{
error ("bit-field %qs width not an integer constant", name);
*width = integer_one_node;
@@ -3816,6 +3850,11 @@ grokdeclarator (const struct c_declarator *declarator,
if (decl_context == NORMAL && !funcdef_flag && current_scope->parm_flag)
decl_context = PARM;
+ /* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */
+ if (declspecs->unavailable_p)
+ warn_unavailable_use (declspecs->type);
+ else
+ /* APPLE LOCAL end "unavailable" attribute (radar 2809697) */
if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS)
warn_deprecated_use (declspecs->type);
@@ -3922,6 +3961,8 @@ grokdeclarator (const struct c_declarator *declarator,
}
else if (storage_class == csc_extern
&& initialized
+ /* APPLE LOCAL private extern */
+ && !declspecs->private_extern_p
&& !funcdef_flag)
{
/* 'extern' with initialization is invalid if not at file scope. */
@@ -4528,6 +4569,14 @@ grokdeclarator (const struct c_declarator *declarator,
if (declspecs->default_int_p)
C_FUNCTION_IMPLICIT_INT (decl) = 1;
+ /* APPLE LOCAL begin private extern */
+ if (declspecs->private_extern_p)
+ {
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ /* APPLE LOCAL end private extern */
+
/* Record presence of `inline', if it is reasonable. */
if (flag_hosted && MAIN_NAME_P (declarator->u.id))
{
@@ -4595,6 +4644,14 @@ grokdeclarator (const struct c_declarator *declarator,
reset later in start_decl. */
DECL_EXTERNAL (decl) = (storage_class == csc_extern);
+ /* APPLE LOCAL begin private extern */
+ if (declspecs->private_extern_p)
+ {
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ /* APPLE LOCAL end private extern */
+
/* At file scope, the presence of a `static' or `register' storage
class specifier, or the absence of all storage class specifiers
makes this declaration a definition (perhaps tentative). Also,
@@ -4632,6 +4689,21 @@ grokdeclarator (const struct c_declarator *declarator,
DECL_REGISTER (decl) = 1;
}
+ /* APPLE LOCAL begin CW asm blocks */
+ if (declspecs->cw_asm_specbit)
+ {
+ /* 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. */
c_apply_type_quals_to_decl (type_quals, decl);
@@ -5644,7 +5716,8 @@ build_enumerator (tree name, tree value)
undeclared identifier) - just ignore the value expression. */
if (value == error_mark_node)
value = 0;
- else if (TREE_CODE (value) != INTEGER_CST)
+ else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))
+ || TREE_CODE (value) != INTEGER_CST)
{
error ("enumerator value for %qE is not an integer constant", name);
value = 0;
@@ -5713,6 +5786,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
tree decl1, old_decl;
tree restype, resdecl;
+ struct c_label_context *nstack;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -5721,6 +5795,12 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
current_extern_inline = 0;
c_switch_stack = NULL;
+ nstack = XOBNEW (&parser_obstack, struct c_label_context);
+ nstack->labels_def = NULL;
+ nstack->labels_used = NULL;
+ nstack->next = label_context_stack;
+ label_context_stack = nstack;
+
/* Indicate no valid break/continue context by setting these variables
to some non-null, non-label value. We'll notice and emit the proper
error message in c_finish_bc_stmt. */
@@ -5773,11 +5853,13 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
/* Optionally warn of old-fashioned def with no previous prototype. */
if (warn_strict_prototypes
+ && old_decl != error_mark_node
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
&& C_DECL_ISNT_PROTOTYPE (old_decl))
warning ("function declaration isn%'t a prototype");
/* Optionally warn of any global def with no previous prototype. */
else if (warn_missing_prototypes
+ && old_decl != error_mark_node
&& TREE_PUBLIC (decl1)
&& !MAIN_NAME_P (DECL_NAME (decl1))
&& C_DECL_ISNT_PROTOTYPE (old_decl))
@@ -5785,7 +5867,9 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
/* Optionally warn of any def with no previous prototype
if the function has already been used. */
else if (warn_missing_prototypes
- && old_decl != 0 && TREE_USED (old_decl)
+ && old_decl != 0
+ && old_decl != error_mark_node
+ && TREE_USED (old_decl)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
warning ("%J%qD was used with no prototype before its definition",
decl1, decl1);
@@ -5798,7 +5882,9 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
else if (warn_missing_declarations
- && old_decl != 0 && TREE_USED (old_decl)
+ && old_decl != 0
+ && old_decl != error_mark_node
+ && TREE_USED (old_decl)
&& C_DECL_IMPLICIT (old_decl))
warning ("%J%qD was used with no declaration before its definition",
decl1, decl1);
@@ -5888,6 +5974,13 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
current_function_decl = pushdecl (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 (current_function_decl);
+ /* APPLE LOCAL end optimization pragmas 3124235/3420242 */
+
push_scope ();
declare_parm_level ();
@@ -5909,6 +6002,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (current_function_decl) = resdecl;
+ /* 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 ();
return 1;
@@ -6296,6 +6399,8 @@ finish_function (void)
{
tree fndecl = current_function_decl;
+ label_context_stack = label_context_stack->next;
+
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
{
@@ -6751,6 +6856,8 @@ build_null_declspecs (void)
ret->tag_defined_p = false;
ret->explicit_signed_p = false;
ret->deprecated_p = false;
+ /* APPLE LOCAL "unavailable" attribute (radar 2809697) */
+ ret->unavailable_p = false;
ret->default_int_p = false;
ret->long_p = false;
ret->long_long_p = false;
@@ -6763,6 +6870,10 @@ build_null_declspecs (void)
ret->const_p = false;
ret->volatile_p = false;
ret->restrict_p = false;
+ /* APPLE LOCAL CW asm blocks */
+ ret->cw_asm_specbit = false;
+ /* APPLE LOCAL private extern */
+ ret->private_extern_p = false;
return ret;
}
@@ -6811,6 +6922,11 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
if (TREE_DEPRECATED (type))
specs->deprecated_p = true;
+ /* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */
+ if (TREE_UNAVAILABLE (type))
+ specs->unavailable_p = true;
+ /* APPLE LOCAL end "unavailable" attribute (radar 2809697) */
+
/* Handle type specifier keywords. */
if (TREE_CODE (type) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (type))
{
@@ -7110,6 +7226,12 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
IDENTIFIER_POINTER (scspec));
switch (i)
{
+ /* APPLE LOCAL begin CW asm blocks */
+ case RID_ASM:
+ dupe = specs->cw_asm_specbit;
+ specs->cw_asm_specbit = true;
+ break;
+ /* APPLE LOCAL end CW asm blocks */
case RID_INLINE:
/* C99 permits duplicate inline. Although of doubtful utility,
it seems simplest to permit it in gnu89 mode as well, as
@@ -7138,6 +7260,15 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
if (specs->thread_p)
error ("%<__thread%> before %<extern%>");
break;
+ /* APPLE LOCAL begin private extern */
+ case RID_PRIVATE_EXTERN:
+ specs->private_extern_p = true;
+ n = csc_extern;
+ /* Diagnose "__thread extern". */
+ if (specs->thread_p)
+ error ("%<__thread%> before %<private_extern%>");
+ break;
+ /* APPLE LOCAL end private extern */
case RID_REGISTER:
n = csc_register;
break;
@@ -7415,4 +7546,21 @@ c_write_global_declarations (void)
cgraph_optimize ();
}
+/* APPLE LOCAL begin CW asm blocks */
+/* Look for a struct or union tag, but quietly; don't complain if neither
+ is found, and don't autocreate. Used to identify struct/union tags
+ mentioned in CW asm operands. */
+tree
+lookup_struct_or_union_tag (tree typename)
+{
+ tree rslt = lookup_tag (RECORD_TYPE, typename, 0);
+
+ pending_invalid_xref = 0;
+ if (!rslt)
+ rslt = lookup_tag (UNION_TYPE, typename, 0);
+ pending_invalid_xref = 0;
+ return rslt;
+}
+/* APPLE LOCAL end CW asm blocks */
+
#include "gt-c-decl.h"