Skip to content

Commit d0c26fb

Browse files
committed
Print enumerator values
Signed-off-by: Roberto Raggi <[email protected]>
1 parent f4588d8 commit d0c26fb

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

src/parser/cxx/binder.cc

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void Binder::bind(EnumSpecifierAST* ast, const DeclSpecs& underlyingTypeSpecs) {
123123

124124
auto enumName = get_name(control(), ast->unqualifiedId);
125125

126-
if (ast->classLoc) {
126+
if (ast->classLoc && is_parsing_cxx()) {
127127
auto enumSymbol = control()->newScopedEnumSymbol(scope(), location);
128128
ast->symbol = enumSymbol;
129129

@@ -133,6 +133,10 @@ void Binder::bind(EnumSpecifierAST* ast, const DeclSpecs& underlyingTypeSpecs) {
133133

134134
setScope(enumSymbol);
135135
} else {
136+
if (is_parsing_c() && ast->classLoc) {
137+
error(ast->classLoc, "scoped enums are not allowed in C");
138+
}
139+
136140
auto enumSymbol = control()->newEnumSymbol(scope(), location);
137141

138142
if (ast->typeSpecifierList) {
@@ -360,21 +364,34 @@ void Binder::bind(EnumeratorAST* ast, const Type* type,
360364
symbol->setType(type);
361365
ast->symbol->setValue(value);
362366
scope()->addSymbol(symbol);
367+
368+
if (auto enumSymbol = symbol_cast<EnumSymbol>(scope()->owner())) {
369+
auto parentScope = enumSymbol->enclosingScope();
370+
371+
auto u =
372+
control()->newUsingDeclarationSymbol(parentScope, ast->identifierLoc);
373+
u->setName(ast->identifier);
374+
u->setTarget(symbol);
375+
parentScope->addSymbol(u);
376+
}
377+
378+
return;
363379
}
364380

381+
// in C mode
382+
365383
if (auto enumSymbol = symbol_cast<EnumSymbol>(scope()->owner())) {
384+
auto parentScope = enumSymbol->enclosingScope();
385+
366386
auto enumeratorSymbol =
367-
control()->newEnumeratorSymbol(scope(), ast->identifierLoc);
387+
control()->newEnumeratorSymbol(parentScope, ast->identifierLoc);
388+
ast->symbol = enumeratorSymbol;
389+
368390
enumeratorSymbol->setName(ast->identifier);
369391
enumeratorSymbol->setType(type);
370392
enumeratorSymbol->setValue(value);
371393

372-
auto parentScope = enumSymbol->enclosingScope();
373394
parentScope->addSymbol(enumeratorSymbol);
374-
375-
if (!is_parsing_cxx()) {
376-
ast->symbol = enumeratorSymbol;
377-
}
378395
}
379396
}
380397

src/parser/cxx/symbol_printer.cc

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ namespace cxx {
3333

3434
namespace {
3535

36+
struct GetEnumeratorValue {
37+
auto operator()(bool value) const -> std::string {
38+
return value ? "true" : "false";
39+
}
40+
auto operator()(std::intmax_t value) const -> std::string {
41+
return std::to_string(value);
42+
}
43+
44+
auto operator()(std::uintmax_t value) const -> std::string {
45+
return std::to_string(value);
46+
}
47+
48+
auto operator()(auto x) const -> std::string { return {}; }
49+
};
50+
3651
struct DumpSymbols {
3752
std::ostream& out;
3853
int depth = 0;
@@ -316,8 +331,21 @@ struct DumpSymbols {
316331

317332
void operator()(EnumeratorSymbol* symbol) {
318333
indent();
319-
out << std::format("enumerator {}\n",
334+
335+
auto get_value = [](auto value) {
336+
return std::visit(GetEnumeratorValue{}, value);
337+
};
338+
339+
const auto value = symbol->value().transform(get_value);
340+
341+
out << std::format("enumerator {}",
320342
to_string(symbol->type(), symbol->name()));
343+
344+
if (value.has_value() && !value->empty()) {
345+
out << std::format(" = {}", *value);
346+
}
347+
348+
out << "\n";
321349
}
322350

323351
void operator()(UsingDeclarationSymbol* symbol) {

tests/unit_tests/sema/struct_c_01.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ int main() {
2626
// clang-format off
2727
// CHECK:namespace
2828
// CHECK-NEXT: enum E : int
29-
// CHECK-NEXT: enumerator E v
29+
// CHECK-NEXT: enumerator E v = 0
3030
// CHECK-NEXT: class A
3131
// CHECK-NEXT: field E e
3232
// CHECK-NEXT: field int x
3333
// CHECK-NEXT: function int main()
3434
// CHECK-NEXT: block
3535
// CHECK-NEXT: enum K : int
36-
// CHECK-NEXT: enumerator K w
36+
// CHECK-NEXT: enumerator K w = 0
3737
// CHECK-NEXT: class B
3838
// CHECK-NEXT: field K k
3939
// CHECK-NEXT: field E e

0 commit comments

Comments
 (0)