aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c627
1 files changed, 355 insertions, 272 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 6ce48a05698..13b891f5886 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -308,7 +308,8 @@ static tree check_case_value (location_t, tree);
static bool check_case_bounds (location_t, tree, tree, tree *, tree *,
bool *);
-static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
+static tree handle_packed_decl_attribute (tree *, tree, tree, int, bool *);
+static tree handle_packed_type_attribute (tree *, tree, tree, int, bool *);
static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
static tree handle_common_attribute (tree *, tree, tree, int, bool *);
static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
@@ -332,27 +333,33 @@ static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
static tree handle_error_attribute (tree *, tree, tree, int, bool *);
static tree handle_used_attribute (tree *, tree, tree, int, bool *);
-static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+static tree handle_unused_decl_attribute (tree *, tree, tree, int, bool *);
+static tree handle_unused_type_attribute (tree *, tree, tree, int, bool *);
static tree handle_externally_visible_attribute (tree *, tree, tree, int,
bool *);
static tree handle_no_reorder_attribute (tree *, tree, tree, int,
bool *);
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
-static tree handle_transparent_union_attribute (tree *, tree, tree,
- int, bool *);
+static tree handle_transparent_union_decl_attribute (tree *, tree, tree,
+ int, bool *);
+static tree handle_transparent_union_type_attribute (tree *, tree, tree,
+ int, bool *);
static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
static tree handle_section_attribute (tree *, tree, tree, int, bool *);
-static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
+static tree handle_aligned_type_attribute (tree *, tree, tree, int, bool *);
+static tree handle_aligned_decl_attribute (tree *, tree, tree, int, bool *);
static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
-static tree handle_visibility_attribute (tree *, tree, tree, int,
- bool *);
+static tree handle_visibility_decl_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_visibility_type_attribute (tree *, tree, tree, int,
+ bool *);
static tree handle_tls_model_attribute (tree *, tree, tree, int,
bool *);
static tree handle_no_instrument_function_attribute (tree *, tree,
@@ -365,8 +372,10 @@ static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
-static tree handle_deprecated_attribute (tree *, tree, tree, int,
- bool *);
+static tree handle_deprecated_type_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_deprecated_decl_attribute (tree *, tree, tree, int,
+ bool *);
static tree handle_vector_size_attribute (tree *, tree, tree, int,
bool *);
static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
@@ -385,7 +394,8 @@ static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static tree ignore_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
-static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
+static tree handle_warn_unused_decl_attribute (tree *, tree, tree, int, bool *);
+static tree handle_warn_unused_type_attribute (tree *, tree, tree, int, bool *);
static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
bool *);
@@ -649,189 +659,198 @@ const unsigned int num_c_common_reswords =
const struct attribute_spec c_common_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- affects_type_identity } */
+ type_hander, affects_type_identity } */
{ "packed", 0, 0, false, false, false,
- handle_packed_attribute , false},
+ handle_packed_decl_attribute,
+ handle_packed_type_attribute, false},
{ "nocommon", 0, 0, true, false, false,
- handle_nocommon_attribute, false},
+ handle_nocommon_attribute, NULL, false},
{ "common", 0, 0, true, false, false,
- handle_common_attribute, false },
+ handle_common_attribute, NULL, false },
/* FIXME: logically, noreturn attributes should be listed as
"false, true, true" and apply to function types. But implementing this
would require all the places in the compiler that use TREE_THIS_VOLATILE
on a decl to identify non-returning functions to be located and fixed
to check the function type instead. */
{ "noreturn", 0, 0, true, false, false,
- handle_noreturn_attribute, false },
+ handle_noreturn_attribute, NULL, false },
{ "volatile", 0, 0, true, false, false,
- handle_noreturn_attribute, false },
+ handle_noreturn_attribute, NULL, false },
{ "stack_protect", 0, 0, true, false, false,
- handle_stack_protect_attribute, false },
+ handle_stack_protect_attribute, NULL, false },
{ "noinline", 0, 0, true, false, false,
- handle_noinline_attribute, false },
+ handle_noinline_attribute, NULL, false },
{ "noclone", 0, 0, true, false, false,
- handle_noclone_attribute, false },
+ handle_noclone_attribute, NULL, false },
{ "no_icf", 0, 0, true, false, false,
- handle_noicf_attribute, false },
+ handle_noicf_attribute, NULL, false },
{ "leaf", 0, 0, true, false, false,
- handle_leaf_attribute, false },
+ handle_leaf_attribute, NULL, false },
{ "always_inline", 0, 0, true, false, false,
- handle_always_inline_attribute, false },
+ handle_always_inline_attribute, NULL, false },
{ "gnu_inline", 0, 0, true, false, false,
- handle_gnu_inline_attribute, false },
+ handle_gnu_inline_attribute, NULL, false },
{ "artificial", 0, 0, true, false, false,
- handle_artificial_attribute, false },
+ handle_artificial_attribute, NULL, false },
{ "flatten", 0, 0, true, false, false,
- handle_flatten_attribute, false },
+ handle_flatten_attribute, NULL, false },
{ "used", 0, 0, true, false, false,
- handle_used_attribute, false },
+ handle_used_attribute, NULL, false },
{ "unused", 0, 0, false, false, false,
- handle_unused_attribute, false },
+ handle_unused_decl_attribute,
+ handle_unused_type_attribute, false },
{ "externally_visible", 0, 0, true, false, false,
- handle_externally_visible_attribute, false },
+ handle_externally_visible_attribute, NULL,
+ false },
{ "no_reorder", 0, 0, true, false, false,
- handle_no_reorder_attribute, false },
+ handle_no_reorder_attribute, NULL, false },
/* The same comments as for noreturn attributes apply to const ones. */
{ "const", 0, 0, true, false, false,
- handle_const_attribute, false },
+ handle_const_attribute, NULL, false },
{ "transparent_union", 0, 0, false, false, false,
- handle_transparent_union_attribute, false },
+ handle_transparent_union_decl_attribute,
+ handle_transparent_union_type_attribute, false },
{ "constructor", 0, 1, true, false, false,
- handle_constructor_attribute, false },
+ handle_constructor_attribute, NULL, false },
{ "destructor", 0, 1, true, false, false,
- handle_destructor_attribute, false },
- { "mode", 1, 1, false, true, false,
+ handle_destructor_attribute, NULL, false },
+ { "mode", 1, 1, false, true, false, NULL,
handle_mode_attribute, false },
{ "section", 1, 1, true, false, false,
- handle_section_attribute, false },
+ handle_section_attribute, NULL, false },
{ "aligned", 0, 1, false, false, false,
- handle_aligned_attribute, false },
+ handle_aligned_decl_attribute,
+ handle_aligned_type_attribute, false },
{ "weak", 0, 0, true, false, false,
- handle_weak_attribute, false },
+ handle_weak_attribute, NULL, false },
{ "noplt", 0, 0, true, false, false,
- handle_noplt_attribute, false },
+ handle_noplt_attribute, NULL, false },
{ "ifunc", 1, 1, true, false, false,
- handle_ifunc_attribute, false },
+ handle_ifunc_attribute, NULL, false },
{ "alias", 1, 1, true, false, false,
- handle_alias_attribute, false },
+ handle_alias_attribute, NULL, false },
{ "weakref", 0, 1, true, false, false,
- handle_weakref_attribute, false },
+ handle_weakref_attribute, NULL, false },
{ "no_instrument_function", 0, 0, true, false, false,
handle_no_instrument_function_attribute,
- false },
+ NULL, false },
{ "malloc", 0, 0, true, false, false,
- handle_malloc_attribute, false },
+ handle_malloc_attribute, NULL, false },
{ "returns_twice", 0, 0, true, false, false,
- handle_returns_twice_attribute, false },
+ handle_returns_twice_attribute, NULL, false },
{ "no_stack_limit", 0, 0, true, false, false,
- handle_no_limit_stack_attribute, false },
+ handle_no_limit_stack_attribute, NULL, false },
{ "pure", 0, 0, true, false, false,
- handle_pure_attribute, false },
+ handle_pure_attribute, NULL, false },
{ "transaction_callable", 0, 0, false, true, false,
- handle_tm_attribute, false },
+ NULL, handle_tm_attribute, false },
{ "transaction_unsafe", 0, 0, false, true, false,
- handle_tm_attribute, true },
+ NULL, handle_tm_attribute, true },
{ "transaction_safe", 0, 0, false, true, false,
- handle_tm_attribute, true },
+ NULL, handle_tm_attribute, true },
{ "transaction_safe_dynamic", 0, 0, true, false, false,
- handle_tm_attribute, false },
+ NULL, handle_tm_attribute, false },
{ "transaction_may_cancel_outer", 0, 0, false, true, false,
- handle_tm_attribute, false },
+ NULL, handle_tm_attribute, false },
/* ??? These two attributes didn't make the transition from the
Intel language document to the multi-vendor language document. */
{ "transaction_pure", 0, 0, false, true, false,
- handle_tm_attribute, false },
+ NULL, handle_tm_attribute, false },
{ "transaction_wrap", 1, 1, true, false, false,
- handle_tm_wrap_attribute, false },
+ handle_tm_wrap_attribute, NULL, false },
/* For internal use (marking of builtins) only. The name contains space
to prevent its usage in source code. */
{ "no vops", 0, 0, true, false, false,
- handle_novops_attribute, false },
+ handle_novops_attribute, NULL, false },
{ "deprecated", 0, 1, false, false, false,
- handle_deprecated_attribute, false },
+ handle_deprecated_decl_attribute,
+ handle_deprecated_type_attribute, false },
{ "vector_size", 1, 1, false, true, false,
- handle_vector_size_attribute, false },
+ NULL, handle_vector_size_attribute, false },
{ "visibility", 1, 1, false, false, false,
- handle_visibility_attribute, false },
+ handle_visibility_decl_attribute,
+ handle_visibility_type_attribute, false },
{ "tls_model", 1, 1, true, false, false,
- handle_tls_model_attribute, false },
+ handle_tls_model_attribute, NULL, false },
{ "nonnull", 0, -1, false, true, true,
- handle_nonnull_attribute, false },
+ NULL, handle_nonnull_attribute, false },
{ "nothrow", 0, 0, true, false, false,
- handle_nothrow_attribute, false },
- { "may_alias", 0, 0, false, true, false, NULL, false },
+ handle_nothrow_attribute, NULL, false },
+ { "may_alias", 0, 0, false, true, false, NULL, NULL, false },
{ "cleanup", 1, 1, true, false, false,
- handle_cleanup_attribute, false },
- { "warn_unused_result", 0, 0, false, true, true,
+ handle_cleanup_attribute, NULL, false },
+ { "warn_unused_result", 0, 0, false, true, true, NULL,
handle_warn_unused_result_attribute, false },
{ "sentinel", 0, 1, false, true, true,
- handle_sentinel_attribute, false },
+ NULL, handle_sentinel_attribute, false },
/* For internal use (marking of builtins) only. The name contains space
to prevent its usage in source code. */
{ "type generic", 0, 0, false, true, true,
- handle_type_generic_attribute, false },
+ NULL, handle_type_generic_attribute, false },
{ "alloc_size", 1, 2, false, true, true,
- handle_alloc_size_attribute, false },
+ NULL, handle_alloc_size_attribute, false },
{ "cold", 0, 0, true, false, false,
- handle_cold_attribute, false },
+ handle_cold_attribute, NULL, false },
{ "hot", 0, 0, true, false, false,
- handle_hot_attribute, false },
+ handle_hot_attribute, NULL, false },
{ "no_address_safety_analysis",
0, 0, true, false, false,
handle_no_address_safety_analysis_attribute,
- false },
+ NULL, false },
{ "no_sanitize_address", 0, 0, true, false, false,
handle_no_sanitize_address_attribute,
- false },
+ NULL, false },
{ "no_sanitize_thread", 0, 0, true, false, false,
handle_no_sanitize_address_attribute,
- false },
+ NULL, false },
{ "no_sanitize_undefined", 0, 0, true, false, false,
handle_no_sanitize_undefined_attribute,
- false },
+ NULL, false },
{ "warning", 1, 1, true, false, false,
- handle_error_attribute, false },
+ handle_error_attribute, NULL, false },
{ "error", 1, 1, true, false, false,
- handle_error_attribute, false },
+ handle_error_attribute, NULL, false },
{ "target", 1, -1, true, false, false,
- handle_target_attribute, false },
+ handle_target_attribute, NULL, false },
{ "target_clones", 1, -1, true, false, false,
- handle_target_clones_attribute, false },
+ handle_target_clones_attribute, NULL, false },
{ "optimize", 1, -1, true, false, false,
- handle_optimize_attribute, false },
+ handle_optimize_attribute, NULL, false },
/* For internal use only. The leading '*' both prevents its usage in
source code and signals that it may be overridden by machine tables. */
{ "*tm regparm", 0, 0, false, true, true,
- ignore_attribute, false },
+ NULL, ignore_attribute, false },
{ "no_split_stack", 0, 0, true, false, false,
- handle_no_split_stack_attribute, false },
+ handle_no_split_stack_attribute, NULL, false },
/* For internal use (marking of builtins and runtime functions) only.
The name contains space to prevent its usage in source code. */
{ "fn spec", 1, 1, false, true, true,
- handle_fnspec_attribute, false },
+ NULL, handle_fnspec_attribute, false },
{ "warn_unused", 0, 0, false, false, false,
- handle_warn_unused_attribute, false },
+ handle_warn_unused_decl_attribute,
+ handle_warn_unused_type_attribute, false },
{ "returns_nonnull", 0, 0, false, true, true,
- handle_returns_nonnull_attribute, false },
+ NULL, handle_returns_nonnull_attribute, false },
{ "omp declare simd", 0, -1, true, false, false,
- handle_omp_declare_simd_attribute, false },
+ handle_omp_declare_simd_attribute, NULL, false },
{ "cilk simd function", 0, -1, true, false, false,
- handle_omp_declare_simd_attribute, false },
+ handle_omp_declare_simd_attribute, NULL, false },
{ "omp declare target", 0, 0, true, false, false,
- handle_omp_declare_target_attribute, false },
+ handle_omp_declare_target_attribute, NULL,
+ false },
{ "alloc_align", 1, 1, false, true, true,
- handle_alloc_align_attribute, false },
+ NULL, handle_alloc_align_attribute, false },
{ "assume_aligned", 1, 2, false, true, true,
- handle_assume_aligned_attribute, false },
+ NULL, handle_assume_aligned_attribute, false },
{ "designated_init", 0, 0, false, true, false,
- handle_designated_init_attribute, false },
+ NULL, handle_designated_init_attribute, false },
{ "bnd_variable_size", 0, 0, true, false, false,
- handle_bnd_variable_size_attribute, false },
+ handle_bnd_variable_size_attribute, NULL, false },
{ "bnd_legacy", 0, 0, true, false, false,
- handle_bnd_legacy, false },
+ handle_bnd_legacy, NULL, false },
{ "bnd_instrument", 0, 0, true, false, false,
- handle_bnd_instrument, false },
- { NULL, 0, 0, false, false, false, NULL, false }
+ handle_bnd_instrument, NULL, false },
+ { NULL, 0, 0, false, false, false, NULL, NULL, false }
};
/* Give the specifications for the format attributes, used by C and all
@@ -846,10 +865,10 @@ const struct attribute_spec c_common_format_attribute_table[] =
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
affects_type_identity } */
{ "format", 3, 3, false, true, true,
- handle_format_attribute, false },
+ NULL, handle_format_attribute, false },
{ "format_arg", 1, 1, false, true, true,
- handle_format_arg_attribute, false },
- { NULL, 0, 0, false, false, false, NULL, false }
+ NULL, handle_format_arg_attribute, false },
+ { NULL, 0, 0, false, false, false, NULL, NULL, false }
};
/* Return identifier for address space AS. */
@@ -7091,16 +7110,10 @@ attribute_takes_identifier_p (const_tree attr_id)
struct attribute_spec.handler. */
static tree
-handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
- int flags, bool *no_add_attrs)
+handle_packed_decl_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags), bool *no_add_attrs)
{
- if (TYPE_P (*node))
- {
- if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- *node = build_variant_type_copy (*node);
- TYPE_PACKED (*node) = 1;
- }
- else if (TREE_CODE (*node) == FIELD_DECL)
+ if (TREE_CODE (*node) == FIELD_DECL)
{
if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
/* Still pack bitfields. */
@@ -7124,6 +7137,18 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
+static tree
+handle_packed_type_attribute (tree *node, tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args),
+ int flags, bool *ARG_UNUSED (no_add_attrs))
+{
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ *node = build_variant_type_copy (*node);
+ TYPE_PACKED (*node) = 1;
+
+ return NULL_TREE;
+}
+
/* Handle a "nocommon" attribute; arguments as in
struct attribute_spec.handler. */
@@ -7556,38 +7581,42 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
struct attribute_spec.handler. */
static tree
-handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
- int flags, bool *no_add_attrs)
+handle_unused_decl_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags), bool *no_add_attrs)
{
- if (DECL_P (*node))
- {
- tree decl = *node;
+ tree decl = *node;
- if (TREE_CODE (decl) == PARM_DECL
- || VAR_OR_FUNCTION_DECL_P (decl)
- || TREE_CODE (decl) == LABEL_DECL
- || TREE_CODE (decl) == TYPE_DECL)
- {
- TREE_USED (decl) = 1;
- if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
- DECL_READ_P (decl) = 1;
- }
- else
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
- }
+ if (TREE_CODE (decl) == PARM_DECL
+ || VAR_OR_FUNCTION_DECL_P (decl)
+ || TREE_CODE (decl) == LABEL_DECL
+ || TREE_CODE (decl) == TYPE_DECL)
+ {
+ TREE_USED (decl) = 1;
+ if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
+ DECL_READ_P (decl) = 1;
}
else
{
- if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- *node = build_variant_type_copy (*node);
- TREE_USED (*node) = 1;
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
}
return NULL_TREE;
}
+
+static tree
+handle_unused_type_attribute (tree *node, tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args), int flags,
+ bool *ARG_UNUSED (no_add_attrs))
+{
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ *node = build_variant_type_copy (*node);
+ TREE_USED (*node) = 1;
+
+ return NULL_TREE;
+}
+
/* Handle a "externally_visible" attribute; arguments as in
struct attribute_spec.handler. */
@@ -7675,20 +7704,13 @@ handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
struct attribute_spec.handler. */
static tree
-handle_transparent_union_attribute (tree *node, tree name,
- tree ARG_UNUSED (args), int flags,
- bool *no_add_attrs)
+handle_transparent_union_type_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args), int flags,
+ bool *no_add_attrs)
{
- tree type;
-
+ tree type = *node;
*no_add_attrs = true;
-
- if (TREE_CODE (*node) == TYPE_DECL
- && ! (flags & ATTR_FLAG_CXX11))
- node = &TREE_TYPE (*node);
- type = *node;
-
if (TREE_CODE (type) == UNION_TYPE)
{
/* Make sure that the first field will work for a transparent union.
@@ -7728,6 +7750,21 @@ handle_transparent_union_attribute (tree *node, tree name,
return NULL_TREE;
}
+
+static tree
+handle_transparent_union_decl_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+{
+ *no_add_attrs = true;
+
+ if (TREE_CODE (*node) == TYPE_DECL && !(flags & ATTR_FLAG_CXX11))
+ return handle_transparent_union_type_attribute (&TREE_TYPE (*node), name,
+ args, flags, no_add_attrs);
+
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ return NULL_TREE;
+}
+
/* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to
get the requested priority for a constructor or destructor,
possibly issuing diagnostics for invalid or reserved
@@ -8249,18 +8286,12 @@ check_cxx_fundamental_alignment_constraints (tree node,
return !alignment_too_large_p;
}
-/* Handle a "aligned" attribute; arguments as in
- struct attribute_spec.handler. */
+/* Return the alignment expression from tree_list element ARGS. */
static tree
-handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
- int flags, bool *no_add_attrs)
+get_align_expr (tree args)
{
- tree decl = NULL_TREE;
- tree *type = NULL;
- int is_type = 0;
tree align_expr;
- int i;
if (args)
{
@@ -8272,40 +8303,60 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
else
align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
- if (DECL_P (*node))
- {
- decl = *node;
- type = &TREE_TYPE (decl);
- is_type = TREE_CODE (*node) == TYPE_DECL;
- }
- else if (TYPE_P (*node))
- type = node, is_type = 1;
+ return align_expr;
+}
+
+/* Set the type alignment fields of NODE, based on FLAGS to I. */
+
+static void
+handle_aligned_type (tree *node, int flags, int i)
+{
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ *node = build_variant_type_copy (*node);
+
+ TYPE_ALIGN (*node) = (1U << i) * BITS_PER_UNIT;
+ TYPE_USER_ALIGN (*node) = 1;
+}
+
+/* Handle a "aligned" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_aligned_type_attribute (tree *node, tree ARG_UNUSED (name), tree args,
+ int flags, bool *no_add_attrs)
+{
+ tree align_expr;
+ int i;
+
+ align_expr = get_align_expr (args);
if ((i = check_user_alignment (align_expr, false)) == -1
|| !check_cxx_fundamental_alignment_constraints (*node, i, flags))
*no_add_attrs = true;
- else if (is_type)
- {
- if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- /* OK, modify the type in place. */;
- /* If we have a TYPE_DECL, then copy the type, so that we
- don't accidentally modify a builtin type. See pushdecl. */
- else if (decl && TREE_TYPE (decl) != error_mark_node
- && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
- {
- tree tt = TREE_TYPE (decl);
- *type = build_variant_type_copy (*type);
- DECL_ORIGINAL_TYPE (decl) = tt;
- TYPE_NAME (*type) = decl;
- TREE_USED (*type) = TREE_USED (decl);
- TREE_TYPE (decl) = *type;
- }
- else
- *type = build_variant_type_copy (*type);
+ else
+ handle_aligned_type (node, flags, i);
+
+ return NULL_TREE;
+}
- TYPE_ALIGN (*type) = (1U << i) * BITS_PER_UNIT;
- TYPE_USER_ALIGN (*type) = 1;
+
+static tree
+handle_aligned_decl_attribute (tree *node, tree ARG_UNUSED (name), tree args,
+ int flags, bool *no_add_attrs)
+{
+ tree align_expr;
+ tree decl = *node;
+ int i;
+
+ align_expr = get_align_expr (args);
+
+ if ((i = check_user_alignment (align_expr, false)) == -1
+ || !check_cxx_fundamental_alignment_constraints (*node, i, flags))
+ {
+ *no_add_attrs = true;
}
+ else if (TREE_CODE (*node) == TYPE_DECL)
+ handle_aligned_type (&TREE_TYPE (*node), flags, i);
else if (! VAR_OR_FUNCTION_DECL_P (decl)
&& TREE_CODE (decl) != FIELD_DECL)
{
@@ -8564,61 +8615,13 @@ handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
return NULL_TREE;
}
-/* Handle an "visibility" attribute; arguments as in
- struct attribute_spec.handler. */
+/* Process the DECL common parts of handle_visibility_attribute. */
-static tree
-handle_visibility_attribute (tree *node, tree name, tree args,
- int ARG_UNUSED (flags),
- bool *ARG_UNUSED (no_add_attrs))
+static void
+handle_decl_visibility (tree decl, tree id, tree attributes)
{
- tree decl = *node;
- tree id = TREE_VALUE (args);
enum symbol_visibility vis;
- if (TYPE_P (*node))
- {
- if (TREE_CODE (*node) == ENUMERAL_TYPE)
- /* OK */;
- else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
- {
- warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
- name);
- return NULL_TREE;
- }
- else if (TYPE_FIELDS (*node))
- {
- error ("%qE attribute ignored because %qT is already defined",
- name, *node);
- return NULL_TREE;
- }
- }
- else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- return NULL_TREE;
- }
-
- if (TREE_CODE (id) != STRING_CST)
- {
- error ("visibility argument not a string");
- return NULL_TREE;
- }
-
- /* If this is a type, set the visibility on the type decl. */
- if (TYPE_P (decl))
- {
- decl = TYPE_NAME (decl);
- if (!decl)
- return NULL_TREE;
- if (TREE_CODE (decl) == IDENTIFIER_NODE)
- {
- warning (OPT_Wattributes, "%qE attribute ignored on types",
- name);
- return NULL_TREE;
- }
- }
-
if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
vis = VISIBILITY_DEFAULT;
else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
@@ -8636,9 +8639,6 @@ handle_visibility_attribute (tree *node, tree name, tree args,
if (DECL_VISIBILITY_SPECIFIED (decl)
&& vis != DECL_VISIBILITY (decl))
{
- tree attributes = (TYPE_P (*node)
- ? TYPE_ATTRIBUTES (*node)
- : DECL_ATTRIBUTES (decl));
if (lookup_attribute ("visibility", attributes))
error ("%qD redeclared with different visibility", decl);
else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -8653,6 +8653,81 @@ handle_visibility_attribute (tree *node, tree name, tree args,
DECL_VISIBILITY (decl) = vis;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
+}
+
+/* Handle an "visibility" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+handle_visibility_decl_attribute (tree *node, tree name, tree args,
+ int ARG_UNUSED (flags),
+ bool *ARG_UNUSED (no_add_attrs))
+{
+ tree decl = *node;
+ tree id = TREE_VALUE (args);
+
+ if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("visibility argument not a string");
+ return NULL_TREE;
+ }
+
+ handle_decl_visibility (decl, id, DECL_ATTRIBUTES (decl));
+ /* Go ahead and attach the attribute to the node as well. This is needed
+ so we can determine whether we have VISIBILITY_DEFAULT because the
+ visibility was not specified, or because it was explicitly overridden
+ from the containing scope. */
+
+ return NULL_TREE;
+}
+
+
+static tree
+handle_visibility_type_attribute (tree *node, tree name, tree args,
+ int ARG_UNUSED (flags),
+ bool *ARG_UNUSED (no_add_attrs))
+{
+ tree decl;
+ tree id = TREE_VALUE (args);
+
+ if (TREE_CODE (*node) == ENUMERAL_TYPE)
+ /* OK */;
+ else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
+ name);
+ return NULL_TREE;
+ }
+ else if (TYPE_FIELDS (*node))
+ {
+ error ("%qE attribute ignored because %qT is already defined",
+ name, *node);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("visibility argument not a string");
+ return NULL_TREE;
+ }
+
+ decl = TYPE_NAME (*node);
+ if (!decl)
+ return NULL_TREE;
+
+ if (TREE_CODE (decl) == IDENTIFIER_NODE)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored on types",
+ name);
+ return NULL_TREE;
+ }
+
+ handle_decl_visibility (decl, id, TYPE_ATTRIBUTES (*node));
/* Go ahead and attach the attribute to the node as well. This is needed
so we can determine whether we have VISIBILITY_DEFAULT because the
@@ -8876,7 +8951,7 @@ handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
tree args, int ARG_UNUSED (flags),
bool *no_add_attrs ATTRIBUTE_UNUSED)
{
- gcc_assert (args
+ gcc_assert (TYPE_P (*node) && args
&& TREE_CODE (TREE_VALUE (args)) == STRING_CST
&& !TREE_CHAIN (args));
return NULL_TREE;
@@ -8934,20 +9009,26 @@ handle_bnd_instrument (tree *node, tree name, tree ARG_UNUSED (args),
struct attribute_spec.handler. */
static tree
-handle_warn_unused_attribute (tree *node, tree name,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-{
- if (TYPE_P (*node))
- /* Do nothing else, just set the attribute. We'll get at
- it later with lookup_attribute. */
- ;
- else
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
- }
+handle_warn_unused_type_attribute (tree *node ATTRIBUTE_UNUSED,
+ tree name ATTRIBUTE_UNUSED,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs ATTRIBUTE_UNUSED)
+{
+ /* Do nothing else, just set the attribute. We'll get at
+ it later with lookup_attribute. */
+ return NULL_TREE;
+}
+static tree
+handle_warn_unused_decl_attribute (tree *node ATTRIBUTE_UNUSED,
+ tree name ATTRIBUTE_UNUSED,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs ATTRIBUTE_UNUSED)
+{
+ /* Do nothing else, just set the attribute. We'll get at
+ it later with lookup_attribute. */
return NULL_TREE;
}
@@ -9195,7 +9276,7 @@ handle_tm_attribute (tree *node, tree name, tree args,
if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
{
tree fn_tmp = TREE_TYPE (*node);
- decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
+ type_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
*node = build_pointer_type (fn_tmp);
break;
}
@@ -9287,14 +9368,10 @@ handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
struct attribute_spec.handler. */
static tree
-handle_deprecated_attribute (tree *node, tree name,
- tree args, int flags,
- bool *no_add_attrs)
+handle_deprecated_type_attribute (tree *node, tree ARG_UNUSED (name),
+ tree args, int flags,
+ bool *no_add_attrs)
{
- tree type = NULL_TREE;
- int warn = 0;
- tree what = NULL_TREE;
-
if (!args)
*no_add_attrs = true;
else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
@@ -9303,33 +9380,40 @@ handle_deprecated_attribute (tree *node, tree name,
*no_add_attrs = true;
}
- if (DECL_P (*node))
- {
- tree decl = *node;
- type = TREE_TYPE (decl);
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ *node = build_variant_type_copy (*node);
+ TREE_DEPRECATED (*node) = 1;
- if (TREE_CODE (decl) == TYPE_DECL
- || TREE_CODE (decl) == PARM_DECL
- || VAR_OR_FUNCTION_DECL_P (decl)
- || TREE_CODE (decl) == FIELD_DECL
- || TREE_CODE (decl) == CONST_DECL
- || objc_method_decl (TREE_CODE (decl)))
- TREE_DEPRECATED (decl) = 1;
- else
- warn = 1;
- }
- else if (TYPE_P (*node))
+ return NULL_TREE;
+}
+
+
+static tree
+handle_deprecated_decl_attribute (tree *node, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ tree decl = *node;
+ tree what = NULL_TREE;
+
+ if (!args)
+ *no_add_attrs = true;
+ else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
{
- if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- *node = build_variant_type_copy (*node);
- TREE_DEPRECATED (*node) = 1;
- type = *node;
+ error ("deprecated message is not a string");
+ *no_add_attrs = true;
}
- else
- warn = 1;
- if (warn)
+ if (TREE_CODE (decl) == TYPE_DECL
+ || TREE_CODE (decl) == PARM_DECL
+ || VAR_OR_FUNCTION_DECL_P (decl)
+ || TREE_CODE (decl) == FIELD_DECL
+ || TREE_CODE (decl) == CONST_DECL
+ || objc_method_decl (TREE_CODE (decl)))
+ TREE_DEPRECATED (decl) = 1;
+ else
{
+ tree type = TREE_TYPE (decl);
*no_add_attrs = true;
if (type && TYPE_NAME (type))
{
@@ -9347,7 +9431,6 @@ handle_deprecated_attribute (tree *node, tree name,
return NULL_TREE;
}
-
/* Handle a "vector_size" attribute; arguments as in
struct attribute_spec.handler. */