Skip to content

Commit 7d6b1b4

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

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
lines changed

src/ansi-c/c_typecheck_type.cpp

Lines changed: 12 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_enum_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;
@@ -1352,6 +1358,12 @@ void c_typecheck_baset::typecheck_c_enum_tag_type(c_enum_tag_typet &type)
13521358
throw 0;
13531359
}
13541360

1361+
if(type.find(ID_enum_underlying_type).is_not_nil())
1362+
{
1363+
warning().source_location = type.source_location();
1364+
warning() << "ignoring specification of underlying type for enum" << eom;
1365+
}
1366+
13551367
source_locationt source_location=type.source_location();
13561368

13571369
irept &tag=type.add(ID_tag);

src/ansi-c/parser.y

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,14 @@ 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

274+
/* a second shift/reduce conflict arises due to enum underlying */
275+
/* type specifications and bitfield specifications, which are both */
276+
/* introduced by a ':' and follow a type */
277+
274278
%{
275279
/************************************************************************/
276280
/*** rules **************************************************************/
@@ -1790,38 +1794,70 @@ bit_field_size:
17901794
enum_name:
17911795
enum_key
17921796
gcc_type_attribute_opt
1797+
enum_underlying_type_opt
17931798
{
17941799
// an anon enum
1800+
if(parser_stack($3).is_not_nil())
1801+
{
1802+
parser_stack($1).set(ID_enum_underlying_type, parser_stack($3));
1803+
}
17951804
}
17961805
'{' enumerator_list_opt '}'
17971806
gcc_type_attribute_opt
17981807
{
1799-
parser_stack($1).operands().swap(parser_stack($5).operands());
1800-
$$=merge($1, merge($2, $7)); // throw in the gcc attributes
1808+
parser_stack($1).operands().swap(parser_stack($6).operands());
1809+
$$=merge($1, merge($2, $8)); // throw in the gcc attributes
18011810
}
18021811
| enum_key
18031812
gcc_type_attribute_opt
18041813
identifier_or_typedef_name
1814+
enum_underlying_type_opt
18051815
{
18061816
// an enum with tag
18071817
parser_stack($1).set(ID_tag, parser_stack($3));
1818+
1819+
if(parser_stack($4).is_not_nil())
1820+
{
1821+
parser_stack($1).set(ID_enum_underlying_type, parser_stack($4));
1822+
}
18081823
}
1809-
'{' enumerator_list_opt '}'
1824+
braced_enumerator_list_opt
18101825
gcc_type_attribute_opt
18111826
{
1812-
parser_stack($1).operands().swap(parser_stack($6).operands());
1813-
$$=merge($1, merge($2, $8)); // throw in the gcc attributes
1827+
if(parser_stack($6).is_not_nil())
1828+
{
1829+
parser_stack($1).operands().swap(parser_stack($6).operands());
1830+
}
1831+
else
1832+
{
1833+
parser_stack($1).id(ID_c_enum_tag);
1834+
}
1835+
1836+
$$=merge($1, merge($2, $7)); // throw in the gcc attributes
18141837
}
1815-
| enum_key
1816-
gcc_type_attribute_opt
1817-
identifier_or_typedef_name
1818-
gcc_type_attribute_opt
1838+
;
1839+
1840+
enum_underlying_type_opt:
1841+
/* empty */
18191842
{
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
1843+
init($$);
1844+
parser_stack($$).make_nil();
1845+
}
1846+
| ':' basic_type_name
1847+
{
1848+
$$=$2;
1849+
}
1850+
1851+
braced_enumerator_list_opt:
1852+
/* empty */
1853+
{
1854+
init($$);
1855+
parser_stack($$).make_nil();
1856+
}
1857+
| '{' enumerator_list_opt '}'
1858+
{
1859+
$$=$2;
18231860
}
1824-
;
18251861

18261862
enum_key: TOK_ENUM
18271863
{

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(enum_underlying_type)
215216
IREP_ID_ONE(enumeration)
216217
IREP_ID_ONE(elements)
217218
IREP_ID_ONE(unknown)

0 commit comments

Comments
 (0)