diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-12-08 12:13:34 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-12-08 12:26:20 -0500 |
| commit | fe8d65556dc49bb0da7ee621597c3b24f0e879f6 (patch) | |
| tree | 18af2a2e0e21b1dbec889564f9e49b7992ed20b2 /src/ir.cpp | |
| parent | 119ed128c05e95a4779a00cd87d3e2d5b01f9f17 (diff) | |
| download | zig-fe8d65556dc49bb0da7ee621597c3b24f0e879f6.tar.gz zig-fe8d65556dc49bb0da7ee621597c3b24f0e879f6.zip | |
add syntax for comptime struct fields
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 5f398bb11a..cd9d895fd4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19514,6 +19514,18 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, return ira->codegen->invalid_instruction; } +static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field) { + if (field->init_val != nullptr) return; + if (field->decl_node->type != NodeTypeStructField) return; + AstNode *init_node = field->decl_node->data.struct_field.value; + if (init_node == nullptr) return; + // scope is not the scope of the struct init, it's the scope of the struct type decl + Scope *analyze_scope = &get_container_scope(container_type)->base; + // memoize it + field->init_val = analyze_const_value(codegen, analyze_scope, init_node, + field->type_entry, nullptr, UndefOk); +} + static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) { @@ -19523,6 +19535,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction return ira->codegen->invalid_instruction; if (field->is_comptime) { IrInstruction *elem = ir_const(ira, source_instr, field_type); + memoize_field_init_val(ira->codegen, struct_type, field); copy_const_val(elem->value, field->init_val); return ir_get_ref(ira, source_instr, elem, true, false); } @@ -21556,25 +21569,12 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc // look for a default field value TypeStructField *field = container_type->data.structure.fields[i]; + memoize_field_init_val(ira->codegen, container_type, field); if (field->init_val == nullptr) { - // it's not memoized. time to go analyze it - AstNode *init_node; - if (field->decl_node->type == NodeTypeStructField) { - init_node = field->decl_node->data.struct_field.value; - } else { - init_node = nullptr; - } - if (init_node == nullptr) { - ir_add_error_node(ira, instruction->source_node, - buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name))); - any_missing = true; - continue; - } - // scope is not the scope of the struct init, it's the scope of the struct type decl - Scope *analyze_scope = &get_container_scope(container_type)->base; - // memoize it - field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, - field->type_entry, nullptr, UndefOk); + ir_add_error_node(ira, instruction->source_node, + buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name))); + any_missing = true; + continue; } if (type_is_invalid(field->init_val->type)) return ira->codegen->invalid_instruction; |
