aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-07-18 15:09:24 +0100
committerGinger Bill <bill@gingerbill.org>2017-07-18 15:09:24 +0100
commit277ef1a68f932988cd59b40e496b2b1532907654 (patch)
treef36cac2af780eee688be2515bd020a5be3a18c8d /src
parent193c7c82c83022fa16dff6cc611d5673753ece8f (diff)
Allow undefined --- as a struct field default value.
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp17
-rw-r--r--src/checker.cpp4
-rw-r--r--src/entity.cpp1
-rw-r--r--src/ir.cpp2
-rw-r--r--src/ir_print.cpp24
5 files changed, 34 insertions, 14 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 47944e772..1dad15c22 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -879,15 +879,20 @@ void check_record_field_decl(Checker *c, AstNode *decl, Array<Entity *> *fields,
e->identifier = name;
if (name_field_index < default_values.count) {
- Operand op = default_values[name_field_index++];
- check_init_variable(c, e, &op, str_lit("struct field assignment"));
- if (is_operand_nil(op)) {
+ Operand a = default_values[name_field_index];
+ Operand b = default_values[name_field_index];
+ check_init_variable(c, e, &b, str_lit("struct field assignment"));
+ if (is_operand_nil(a)) {
e->Variable.default_is_nil = true;
- } else if (op.mode != Addressing_Constant) {
- error(op.expr, "Default field parameter must be a constant");
+ } else if (is_operand_undef(a)) {
+ e->Variable.default_is_undef = true;
+ } else if (b.mode != Addressing_Constant) {
+ error(b.expr, "Default field parameter must be a constant");
} else {
- e->Variable.default_value = op.value;
+ e->Variable.default_value = b.value;
}
+
+ name_field_index++;
} else {
GB_ASSERT(type != nullptr);
}
diff --git a/src/checker.cpp b/src/checker.cpp
index 1cbf5db40..cdc9bf3b4 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -166,7 +166,9 @@ bool is_operand_value(Operand o) {
bool is_operand_nil(Operand o) {
return o.mode == Addressing_Value && o.type == t_untyped_nil;
}
-
+bool is_operand_undef(Operand o) {
+ return o.mode == Addressing_Value && o.type == t_untyped_undef;
+}
struct BlockLabel {
String name;
diff --git a/src/entity.cpp b/src/entity.cpp
index a9b083400..d2c29ca98 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -87,6 +87,7 @@ struct Entity {
i32 field_src_index;
ExactValue default_value;
bool default_is_nil;
+ bool default_is_undef;
bool default_is_location;
bool is_immutable;
bool is_thread_local;
diff --git a/src/ir.cpp b/src/ir.cpp
index e87e33559..c525419af 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -671,6 +671,8 @@ bool ir_type_has_default_values(Type *t) {
continue;
} else if (f->Variable.default_value.kind != ExactValue_Invalid) {
return true;
+ } else if (f->Variable.default_is_undef) {
+ return true;
}
}
}
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index d6fa61a10..3a3eaaced 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -648,9 +648,14 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
for (isize i = 0; i < value_count; i++) {
if (i > 0) ir_fprintf(f, ", ");
- Type *elem_type = type->Record.fields[i]->type;
+ Entity *e = type->Record.fields[i];
- ir_print_compound_element(f, m, values[i], elem_type);
+ if (!visited[i] && e->Variable.default_is_undef) {
+ ir_print_type(f, m, e->type);
+ ir_fprintf(f, " undef");
+ } else {
+ ir_print_compound_element(f, m, values[i], e->type);
+ }
}
@@ -682,12 +687,17 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
for (isize i = 0; i < value_count; i++) {
if (i > 0) ir_fprintf(f, ", ");
- Entity *field = type->Record.fields[i];
- ExactValue value = {};
- if (!field->Variable.default_is_nil) {
- value = field->Variable.default_value;
+ Entity *e = type->Record.fields[i];
+ if (e->Variable.default_is_undef) {
+ ir_print_type(f, m, e->type);
+ ir_fprintf(f, " undef");
+ } else {
+ ExactValue value = {};
+ if (!e->Variable.default_is_nil) {
+ value = e->Variable.default_value;
+ }
+ ir_print_compound_element(f, m, value, e->type);
}
- ir_print_compound_element(f, m, value, field->type);
}
ir_fprintf(f, "}");