aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-02-04 16:09:06 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-02-04 16:09:06 -0700
commita4cba900e53154abd5595bacf709fe8fdcc86b27 (patch)
tree906b7b238f5f5d3797d04180c137f9829ca43944 /src
parent5490f907fe4b5c8323eaf917b1ead8760c9eca34 (diff)
downloadzig-a4cba900e53154abd5595bacf709fe8fdcc86b27.tar.gz
zig-a4cba900e53154abd5595bacf709fe8fdcc86b27.zip
no namespace required when switching on enum
See #43
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp1
-rw-r--r--src/analyze.cpp28
-rw-r--r--src/codegen.cpp21
3 files changed, 33 insertions, 17 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 70919f67e7..2576d345e7 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -673,6 +673,7 @@ struct AstNodeSymbolExpr {
FnTableEntry *fn_entry;
// set this to instead of analyzing the node, pretend it's a type entry and it's this one.
TypeTableEntry *override_type_entry;
+ TypeEnumField *enum_field;
};
struct AstNodeBoolLiteral {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 3ab41409bb..4b09c850fa 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -4508,10 +4508,30 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import,
if (item_node->type == NodeTypeSwitchRange) {
zig_panic("TODO range in switch statement");
}
- analyze_expression(g, import, context, expr_type, item_node);
- ConstExprValue *const_val = &get_resolved_expr(item_node)->const_val;
- if (!const_val->ok) {
- add_node_error(g, item_node, buf_sprintf("unable to resolve constant expression"));
+
+ if (expr_type->id == TypeTableEntryIdEnum) {
+ if (item_node->type == NodeTypeSymbol) {
+ Buf *field_name = &item_node->data.symbol_expr.symbol;
+ TypeEnumField *type_enum_field = get_enum_field(expr_type, field_name);
+ if (type_enum_field) {
+ item_node->data.symbol_expr.enum_field = type_enum_field;
+ } else {
+ add_node_error(g, item_node,
+ buf_sprintf("enum '%s' has no field '%s'",
+ buf_ptr(&expr_type->name), buf_ptr(field_name)));
+ }
+ } else {
+ add_node_error(g, item_node, buf_sprintf("expected enum tag name"));
+ }
+ } else {
+ TypeTableEntry *item_type = analyze_expression(g, import, context, expr_type, item_node);
+ if (item_type->id != TypeTableEntryIdInvalid) {
+ ConstExprValue *const_val = &get_resolved_expr(item_node)->const_val;
+ if (!const_val->ok) {
+ add_node_error(g, item_node,
+ buf_sprintf("unable to resolve constant expression"));
+ }
+ }
}
}
var_type = expr_type;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 90ff4947d3..17e781fd02 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2357,21 +2357,16 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
for (int item_i = 0; item_i < prong_node->data.switch_prong.items.length; item_i += 1) {
AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
assert(item_node->type != NodeTypeSwitchRange);
- assert(get_resolved_expr(item_node)->const_val.ok);
- LLVMValueRef val_handle = gen_expr(g, item_node);
LLVMValueRef val;
- if (handle_is_ptr(target_type)) {
- if (target_type->id == TypeTableEntryIdEnum) {
- ConstExprValue *item_const_val = &get_resolved_expr(item_node)->const_val;
- assert(item_const_val->ok);
- assert(get_expr_type(item_node)->id == TypeTableEntryIdEnum);
- val = LLVMConstInt(target_type->data.enumeration.tag_type->type_ref,
- item_const_val->data.x_enum.tag, false);
- } else {
- zig_unreachable();
- }
+ if (target_type->id == TypeTableEntryIdEnum) {
+ assert(item_node->type == NodeTypeSymbol);
+ TypeEnumField *enum_field = item_node->data.symbol_expr.enum_field;
+ assert(enum_field);
+ val = LLVMConstInt(target_type->data.enumeration.tag_type->type_ref,
+ enum_field->value, false);
} else {
- val = val_handle;
+ assert(get_resolved_expr(item_node)->const_val.ok);
+ val = gen_expr(g, item_node);
}
LLVMAddCase(switch_instr, val, prong_block);
}