summaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-08 18:33:42 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-08 18:33:42 +0000
commit292237f3c109f2e0d2752ad1e73181689f7d0d53 (patch)
treecf927ff52a6d5ba28290472db09363fe67a835d6 /gcc/c-family/c-common.c
parentb4a4c5fa93f829b83d5ffd2efbbeb2c5e0b45dd7 (diff)
downloadgcc-292237f3c109f2e0d2752ad1e73181689f7d0d53.tar.gz
Merge of the scalar-storage-order branch.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229965 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c65
1 files changed, 62 insertions, 3 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index bdcb5b25401..53c1d81c0c8 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -339,6 +339,8 @@ static tree handle_no_reorder_attribute (tree *, tree, tree, int,
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
static tree handle_transparent_union_attribute (tree *, tree, tree,
int, bool *);
+static tree handle_scalar_storage_order_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 *);
@@ -693,6 +695,8 @@ const struct attribute_spec c_common_attribute_table[] =
/* The same comments as for noreturn attributes apply to const ones. */
{ "const", 0, 0, true, false, false,
handle_const_attribute, false },
+ { "scalar_storage_order", 1, 1, false, false, false,
+ handle_scalar_storage_order_attribute, false },
{ "transparent_union", 0, 0, false, false, false,
handle_transparent_union_attribute, false },
{ "constructor", 0, 1, true, false, false,
@@ -7668,6 +7672,62 @@ handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
+/* Handle a "scalar_storage_order" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+{
+ tree id = TREE_VALUE (args);
+ tree type;
+
+ if (TREE_CODE (*node) == TYPE_DECL
+ && ! (flags & ATTR_FLAG_CXX11))
+ node = &TREE_TYPE (*node);
+ type = *node;
+
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ {
+ error ("scalar_storage_order is not supported because endianness "
+ "is not uniform");
+ return NULL_TREE;
+ }
+
+ if (RECORD_OR_UNION_TYPE_P (type) && !c_dialect_cxx ())
+ {
+ bool reverse = false;
+
+ if (TREE_CODE (id) == STRING_CST
+ && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
+ reverse = !BYTES_BIG_ENDIAN;
+ else if (TREE_CODE (id) == STRING_CST
+ && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
+ reverse = BYTES_BIG_ENDIAN;
+ else
+ {
+ error ("scalar_storage_order argument must be one of \"big-endian\""
+ " or \"little-endian\"");
+ return NULL_TREE;
+ }
+
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ {
+ if (reverse)
+ /* A type variant isn't good enough, since we don't want a cast
+ to such a type to be removed as a no-op. */
+ *node = type = build_duplicate_type (type);
+ }
+
+ TYPE_REVERSE_STORAGE_ORDER (type) = reverse;
+ return NULL_TREE;
+ }
+
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
/* Handle a "transparent_union" attribute; arguments as in
struct attribute_spec.handler. */
@@ -7680,7 +7740,6 @@ handle_transparent_union_attribute (tree *node, tree name,
*no_add_attrs = true;
-
if (TREE_CODE (*node) == TYPE_DECL
&& ! (flags & ATTR_FLAG_CXX11))
node = &TREE_TYPE (*node);
@@ -7711,8 +7770,8 @@ handle_transparent_union_attribute (tree *node, tree name,
if (c_dialect_cxx ())
goto ignored;
- /* A type variant isn't good enough, since we don't a cast
- to such a type removed as a no-op. */
+ /* A type variant isn't good enough, since we don't want a cast
+ to such a type to be removed as a no-op. */
*node = type = build_duplicate_type (type);
}