Skip to content

Commit 29807c8

Browse files
committed
Update grammar rule for enums to allow specifying an underlying type
1 parent 0022844 commit 29807c8

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

src/ansi-c/c_typecheck_type.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,12 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type)
11601160
throw 0;
11611161
}
11621162

1163+
if(as_expr.find(ID_underlying_type).is_not_nil())
1164+
{
1165+
warning().source_location = source_location;
1166+
warning() << "ignoring specification of underlying type for enum" << eom;
1167+
}
1168+
11631169
// enums start at zero;
11641170
// we also track min and max to find a nice base type
11651171
mp_integer value=0, min_value=0, max_value=0;

src/ansi-c/parser.y

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ extern char *yyansi_ctext;
267267

268268
%start grammar
269269

270-
%expect 1 /* the famous "dangling `else'" ambiguity */
270+
%expect 2 /* the famous "dangling `else'" ambiguity */
271271
/* results in one shift/reduce conflict */
272272
/* that we don't want to be reported */
273273

@@ -1790,38 +1790,70 @@ bit_field_size:
17901790
enum_name:
17911791
enum_key
17921792
gcc_type_attribute_opt
1793+
enum_underlying_type_opt
17931794
{
17941795
// an anon enum
1796+
if(parser_stack($3).is_not_nil())
1797+
{
1798+
parser_stack($1).set(ID_underlying_type, parser_stack($3));
1799+
}
17951800
}
17961801
'{' enumerator_list_opt '}'
17971802
gcc_type_attribute_opt
17981803
{
1799-
parser_stack($1).operands().swap(parser_stack($5).operands());
1800-
$$=merge($1, merge($2, $7)); // throw in the gcc attributes
1804+
parser_stack($1).operands().swap(parser_stack($6).operands());
1805+
$$=merge($1, merge($2, $8)); // throw in the gcc attributes
18011806
}
18021807
| enum_key
18031808
gcc_type_attribute_opt
18041809
identifier_or_typedef_name
1810+
enum_underlying_type_opt
18051811
{
18061812
// an enum with tag
18071813
parser_stack($1).set(ID_tag, parser_stack($3));
1814+
1815+
if(parser_stack($4).is_not_nil())
1816+
{
1817+
parser_stack($1).set(ID_underlying_type, parser_stack($4));
1818+
}
18081819
}
1809-
'{' enumerator_list_opt '}'
1820+
braced_enumerator_list_opt
18101821
gcc_type_attribute_opt
18111822
{
1812-
parser_stack($1).operands().swap(parser_stack($6).operands());
1813-
$$=merge($1, merge($2, $8)); // throw in the gcc attributes
1823+
if(parser_stack($6).is_not_nil())
1824+
{
1825+
parser_stack($1).operands().swap(parser_stack($6).operands());
1826+
}
1827+
else
1828+
{
1829+
parser_stack($1).id(ID_c_enum_tag);
1830+
}
1831+
1832+
$$=merge($1, merge($2, $7)); // throw in the gcc attributes
18141833
}
1815-
| enum_key
1816-
gcc_type_attribute_opt
1817-
identifier_or_typedef_name
1818-
gcc_type_attribute_opt
1834+
;
1835+
1836+
enum_underlying_type_opt:
1837+
/* empty */
18191838
{
1820-
parser_stack($1).id(ID_c_enum_tag); // tag only
1821-
parser_stack($1).set(ID_tag, parser_stack($3));
1822-
$$=merge($1, merge($2, $4)); // throw in the gcc attributes
1839+
init($$);
1840+
parser_stack($$).make_nil();
1841+
}
1842+
| ':' basic_type_name
1843+
{
1844+
$$=$2;
1845+
}
1846+
1847+
braced_enumerator_list_opt:
1848+
/* empty */
1849+
{
1850+
init($$);
1851+
parser_stack($$).make_nil();
1852+
}
1853+
| '{' enumerator_list_opt '}'
1854+
{
1855+
$$=$2;
18231856
}
1824-
;
18251857

18261858
enum_key: TOK_ENUM
18271859
{

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ IREP_ID_ONE(NULL)
212212
IREP_ID_ONE(null)
213213
IREP_ID_ONE(nullptr)
214214
IREP_ID_ONE(c_enum)
215+
IREP_ID_ONE(underlying_type)
215216
IREP_ID_ONE(enumeration)
216217
IREP_ID_ONE(elements)
217218
IREP_ID_ONE(unknown)

0 commit comments

Comments
 (0)