Skip to content

Commit 6deb75c

Browse files
committed
Compute and assign automatic values to the enumerators
Fixes #567 Signed-off-by: Roberto Raggi <[email protected]>
1 parent 7919e3f commit 6deb75c

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

src/parser/cxx/parser.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6599,6 +6599,16 @@ void Parser::parse_enumerator_list(List<EnumeratorAST*>*& yyast,
65996599
*it = make_list_node(pool_, enumerator);
66006600
it = &(*it)->next;
66016601

6602+
std::optional<ConstValue> lastValue;
6603+
ASTInterpreter interp{unit};
6604+
6605+
if (enumerator->expression) {
6606+
lastValue = enumerator->symbol->value();
6607+
} else {
6608+
lastValue = std::intmax_t{0};
6609+
enumerator->symbol->setValue(*lastValue);
6610+
}
6611+
66026612
SourceLocation commaLoc;
66036613

66046614
while (match(TokenKind::T_COMMA, commaLoc)) {
@@ -6610,6 +6620,27 @@ void Parser::parse_enumerator_list(List<EnumeratorAST*>*& yyast,
66106620
EnumeratorAST* enumerator = nullptr;
66116621
parse_enumerator(enumerator, type);
66126622

6623+
if (!enumerator->expression) {
6624+
if (lastValue.has_value()) {
6625+
if (control_->is_unsigned(type)) {
6626+
if (auto v = interp.toUInt(lastValue.value())) {
6627+
lastValue = v.value() + 1;
6628+
} else {
6629+
lastValue = std::nullopt;
6630+
}
6631+
} else {
6632+
if (auto v = interp.toInt(lastValue.value())) {
6633+
lastValue = v.value() + 1;
6634+
} else {
6635+
lastValue = std::nullopt;
6636+
}
6637+
}
6638+
}
6639+
enumerator->symbol->setValue(*lastValue);
6640+
} else {
6641+
lastValue = enumerator->symbol->value();
6642+
}
6643+
66136644
*it = make_list_node(pool_, enumerator);
66146645
it = &(*it)->next;
66156646
}

tests/unit_tests/sema/enum_c_01.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@
22

33
enum X {
44
A,
5-
B,
6-
C,
5+
B = 1,
6+
C = B,
7+
D,
78
};
89

10+
static_assert(A == 0);
11+
static_assert(B == 1);
12+
static_assert(C == 1);
13+
static_assert(D == 2);
14+
915
enum X x;
1016

1117
// CHECK:namespace
1218
// CHECK-NEXT:enum X : int
1319
// CHECK-NEXT:enumerator X A
1420
// CHECK-NEXT:enumerator X B
1521
// CHECK-NEXT:enumerator X C
22+
// CHECK-NEXT:enumerator X D
1623
// CHECK-NEXT:variable X x

0 commit comments

Comments
 (0)