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.c245
1 files changed, 224 insertions, 21 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 0b7b97ede23..c3270885191 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 objc speedup --dpatel */
+/* 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;
@@ -559,12 +557,24 @@ objc_mark_locals_volatile (void *enclosing_blk)
{
for (b = scope->bindings; b; b = b->prev)
{
- if (TREE_CODE (b->decl) == VAR_DECL
- || TREE_CODE (b->decl) == PARM_DECL)
+ /* APPLE LOCAL begin Objective-C */
+ tree decl = b->decl;
+
+ /* Do not mess with variables that are 'static' or (already)
+ 'volatile'. */
+ if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
+ && (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == PARM_DECL))
{
- C_DECL_REGISTER (b->decl) = 0;
- DECL_REGISTER (b->decl) = 0;
- TREE_THIS_VOLATILE (b->decl) = 1;
+ TREE_TYPE (decl)
+ = build_qualified_type (TREE_TYPE (decl),
+ (TYPE_QUALS (TREE_TYPE (decl))
+ | TYPE_QUAL_VOLATILE));
+ TREE_THIS_VOLATILE (decl) = 1;
+ TREE_SIDE_EFFECTS (decl) = 1;
+ DECL_REGISTER (decl) = 0;
+ C_DECL_REGISTER (decl) = 0;
+ /* APPLE LOCAL end Objective-C */
}
}
@@ -1228,12 +1238,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 +1712,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 +2324,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
@@ -2703,7 +2776,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 +3073,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);
@@ -3816,6 +3928,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 +4039,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 +4647,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 +4722,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 +4767,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);
@@ -5909,6 +6059,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;
@@ -6751,6 +6911,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 +6925,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 +6977,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 +7281,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 +7315,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 +7601,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"