Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support unnamed/anonymous structs and unions #5

Merged
merged 4 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 15 additions & 57 deletions gcc/c-decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,6 @@ static tree lookup_tag_reverse PROTO((tree));
static tree grokdeclarator PROTO((tree, tree, enum decl_context,
int));
static tree grokparms PROTO((tree, int));
static int field_decl_cmp PROTO((const GENERIC_PTR, const GENERIC_PTR));
static void layout_array_type PROTO((tree));

/* C-specific option variables. */
Expand Down Expand Up @@ -5691,6 +5690,21 @@ grokfield (filename, line, declarator, declspecs, width)
{
tree value;

if (declarator == NULL_TREE && width == NULL_TREE)
{
/* This is an unnamed decl. We only support unnamed
structs/unions, so check for other things and refuse them. */
tree type = TREE_VALUE (declspecs);

if (TREE_CODE (type) == TYPE_DECL)
type = TREE_TYPE (type);
if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE)
{
error ("unnamed fields of type other than struct or union are not allowed");
return NULL_TREE;
}
}

/* The corresponding pop_obstacks is in finish_decl. */
push_obstacks_nochange ();

Expand All @@ -5703,25 +5717,6 @@ grokfield (filename, line, declarator, declspecs, width)
return value;
}

/* Function to help qsort sort FIELD_DECLs by name order. */

static int
field_decl_cmp (xp, yp)
const GENERIC_PTR xp;
const GENERIC_PTR yp;
{
tree *x = (tree *)xp, *y = (tree *)yp;

if (DECL_NAME (*x) == DECL_NAME (*y))
return 0;
if (DECL_NAME (*x) == NULL)
return -1;
if (DECL_NAME (*y) == NULL)
return 1;
if (DECL_NAME (*x) < DECL_NAME (*y))
return -1;
return 1;
}

/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
Expand Down Expand Up @@ -5958,43 +5953,6 @@ finish_struct (t, fieldlist, attributes)

TYPE_FIELDS (t) = fieldlist;

/* If there are lots of fields, sort so we can look through them fast.
We arbitrarily consider 16 or more elts to be "a lot". */
{
int len = 0;

for (x = fieldlist; x; x = TREE_CHAIN (x))
{
if (len > 15)
break;
len += 1;
}
if (len > 15)
{
tree *field_array;
char *space;

len += list_length (x);
/* Use the same allocation policy here that make_node uses, to
ensure that this lives as long as the rest of the struct decl.
All decls in an inline function need to be saved. */
if (allocation_temporary_p ())
space = savealloc (sizeof (struct lang_type) + len * sizeof (tree));
else
space = oballoc (sizeof (struct lang_type) + len * sizeof (tree));

TYPE_LANG_SPECIFIC (t) = (struct lang_type *) space;
TYPE_LANG_SPECIFIC (t)->len = len;

field_array = &TYPE_LANG_SPECIFIC (t)->elts[0];
len = 0;
for (x = fieldlist; x; x = TREE_CHAIN (x))
field_array[len++] = x;

qsort (field_array, len, sizeof (tree), field_decl_cmp);
}
}

for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
TYPE_FIELDS (x) = TYPE_FIELDS (t);
Expand Down
Loading