aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-11-30 21:46:02 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-11-30 22:08:11 -0500
commitb62e2fd8703129fcf0dc80675800f005e84ee724 (patch)
treec70341d5db1c79901ce58d86c1aa24f5c972d57d /src/analyze.cpp
parent5786df933d37d52d57fef9c28acb9c2c23128d31 (diff)
downloadzig-b62e2fd8703129fcf0dc80675800f005e84ee724.tar.gz
zig-b62e2fd8703129fcf0dc80675800f005e84ee724.zip
ability to specify tag type of enums
see #305
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index a12934f2b2..33d6ccdc39 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1267,7 +1267,7 @@ TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, Type
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag);
buf_resize(&entry->name, 0);
- buf_appendf(&entry->name, "@enumTagType(%s)", buf_ptr(&enum_type->name));
+ buf_appendf(&entry->name, "@EnumTagType(%s)", buf_ptr(&enum_type->name));
entry->is_copyable = true;
entry->data.enum_tag.enum_type = enum_type;
@@ -1391,6 +1391,25 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
}
TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
+ if (decl_node->data.container_decl.init_arg_expr != nullptr) {
+ TypeTableEntry *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
+ if (type_is_invalid(wanted_tag_int_type)) {
+ enum_type->data.enumeration.is_invalid = true;
+ } else if (wanted_tag_int_type->id != TypeTableEntryIdInt) {
+ enum_type->data.enumeration.is_invalid = true;
+ add_node_error(g, decl_node->data.container_decl.init_arg_expr,
+ buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
+ } else if (wanted_tag_int_type->data.integral.bit_count < tag_int_type->data.integral.bit_count) {
+ enum_type->data.enumeration.is_invalid = true;
+ add_node_error(g, decl_node->data.container_decl.init_arg_expr,
+ buf_sprintf("'%s' too small to hold all bits; must be at least '%s'",
+ buf_ptr(&wanted_tag_int_type->name), buf_ptr(&tag_int_type->name)));
+ } else {
+ tag_int_type = wanted_tag_int_type;
+ }
+ }
+
+
TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
enum_type->data.enumeration.tag_type = tag_type_entry;