authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-08 11:40:17-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-08 12:26:20-05:00
log119ed128c05e95a4779a00cd87d3e2d5b01f9f17
treed0623cbce915223027051e9c79495ec25aa0a81b
parent19c1b5a33a21bdddfbbca3c65b1c0e6419c4629f
signature Commit is signed but in an unrecognized format.

implement comptime struct fields


5 files changed, 32 insertions(+), 9 deletions(-)

src/all_types.hpp+1
...@@ -1263,6 +1263,7 @@ struct TypeStructField {...@@ -1263,6 +1263,7 @@ struct TypeStructField {
1263 uint32_t bit_offset_in_host; // offset from the memory at gen_index1263 uint32_t bit_offset_in_host; // offset from the memory at gen_index
1264 uint32_t host_int_bytes; // size of host integer1264 uint32_t host_int_bytes; // size of host integer
1265 uint32_t align;1265 uint32_t align;
1266 bool is_comptime;
1266};1267};
12671268
1268enum ResolveStatus {1269enum ResolveStatus {
src/analyze.cpp+7-3
...@@ -2788,6 +2788,9 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2788,6 +2788,9 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2788 type_struct_field->src_index = i;2788 type_struct_field->src_index = i;
2789 type_struct_field->gen_index = SIZE_MAX;2789 type_struct_field->gen_index = SIZE_MAX;
27902790
2791 if (type_struct_field->is_comptime)
2792 continue;
2793
2791 switch (type_val_resolve_requires_comptime(g, field_type_val)) {2794 switch (type_val_resolve_requires_comptime(g, field_type_val)) {
2792 case ReqCompTimeYes:2795 case ReqCompTimeYes:
2793 struct_type->data.structure.requires_comptime = true;2796 struct_type->data.structure.requires_comptime = true;
...@@ -7987,8 +7990,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7987,8 +7990,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7987 // inserting padding bytes where LLVM would do it automatically.7990 // inserting padding bytes where LLVM would do it automatically.
7988 size_t llvm_struct_abi_align = 0;7991 size_t llvm_struct_abi_align = 0;
7989 for (size_t i = 0; i < field_count; i += 1) {7992 for (size_t i = 0; i < field_count; i += 1) {
7990 ZigType *field_type = struct_type->data.structure.fields[i]->type_entry;7993 TypeStructField *field = struct_type->data.structure.fields[i];
7991 if (!type_has_bits(field_type))7994 ZigType *field_type = field->type_entry;
7995 if (field->is_comptime || !type_has_bits(field_type))
7992 continue;7996 continue;
7993 LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);7997 LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
7994 size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type);7998 size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type);
...@@ -7999,7 +8003,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7999,7 +8003,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7999 TypeStructField *field = struct_type->data.structure.fields[i];8003 TypeStructField *field = struct_type->data.structure.fields[i];
8000 ZigType *field_type = field->type_entry;8004 ZigType *field_type = field->type_entry;
80018005
8002 if (!type_has_bits(field_type)) {8006 if (field->is_comptime || !type_has_bits(field_type)) {
8003 field->gen_index = SIZE_MAX;8007 field->gen_index = SIZE_MAX;
8004 continue;8008 continue;
8005 }8009 }
src/ir.cpp+20
...@@ -655,6 +655,10 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {...@@ -655,6 +655,10 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
655 if (isf != nullptr) {655 if (isf != nullptr) {
656 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);656 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
657 assert(field != nullptr);657 assert(field != nullptr);
658 if (field->is_comptime) {
659 assert(field->init_val != nullptr);
660 return field->init_val;
661 }
658 assert(const_val->data.x_ptr.special == ConstPtrSpecialRef);662 assert(const_val->data.x_ptr.special == ConstPtrSpecialRef);
659 ZigValue *struct_val = const_val->data.x_ptr.data.ref.pointee;663 ZigValue *struct_val = const_val->data.x_ptr.data.ref.pointee;
660 return struct_val->data.x_struct.fields[field->src_index];664 return struct_val->data.x_struct.fields[field->src_index];
...@@ -17373,6 +17377,13 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -17373,6 +17377,13 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
17373 field->type_val = create_const_type(ira->codegen, field->type_entry);17377 field->type_val = create_const_type(ira->codegen, field->type_entry);
17374 field->src_index = old_field_count;17378 field->src_index = old_field_count;
17375 field->decl_node = uncasted_value->source_node;17379 field->decl_node = uncasted_value->source_node;
17380 if (instr_is_comptime(uncasted_value)) {
17381 ZigValue *uncasted_val = ir_resolve_const(ira, uncasted_value, UndefOk);
17382 field->is_comptime = true;
17383 field->init_val = create_const_vals(1);
17384 copy_const_val(field->init_val, uncasted_val);
17385 return ir_const_void(ira, source_instr);
17386 }
1737617387
17377 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);17388 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
17378 IrInstruction *casted_ptr;17389 IrInstruction *casted_ptr;
...@@ -19510,6 +19521,11 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -19510,6 +19521,11 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
19510 ZigType *field_type = resolve_struct_field_type(ira->codegen, field);19521 ZigType *field_type = resolve_struct_field_type(ira->codegen, field);
19511 if (field_type == nullptr)19522 if (field_type == nullptr)
19512 return ira->codegen->invalid_instruction;19523 return ira->codegen->invalid_instruction;
19524 if (field->is_comptime) {
19525 IrInstruction *elem = ir_const(ira, source_instr, field_type);
19526 copy_const_val(elem->value, field->init_val);
19527 return ir_get_ref(ira, source_instr, elem, true, false);
19528 }
19513 switch (type_has_one_possible_value(ira->codegen, field_type)) {19529 switch (type_has_one_possible_value(ira->codegen, field_type)) {
19514 case OnePossibleValueInvalid:19530 case OnePossibleValueInvalid:
19515 return ira->codegen->invalid_instruction;19531 return ira->codegen->invalid_instruction;
...@@ -21716,6 +21732,10 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -21716,6 +21732,10 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
21716 for (size_t i = 0; i < const_ptrs.length; i += 1) {21732 for (size_t i = 0; i < const_ptrs.length; i += 1) {
21717 IrInstruction *elem_result_loc = const_ptrs.at(i);21733 IrInstruction *elem_result_loc = const_ptrs.at(i);
21718 assert(elem_result_loc->value->special == ConstValSpecialStatic);21734 assert(elem_result_loc->value->special == ConstValSpecialStatic);
21735 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) {
21736 // This field will be generated comptime; no need to do this.
21737 continue;
21738 }
21719 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);21739 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);
21720 elem_result_loc->value->special = ConstValSpecialRuntime;21740 elem_result_loc->value->special = ConstValSpecialRuntime;
21721 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false);21741 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false);
test/stage1/behavior/call.zig+4-4
...@@ -37,12 +37,12 @@ test "tuple parameters" {...@@ -37,12 +37,12 @@ test "tuple parameters" {
37 comptime expect(@call(.{}, add, .{ 12, 34 }) == 46);37 comptime expect(@call(.{}, add, .{ 12, 34 }) == 46);
38 {38 {
39 const separate_args0 = .{ a, b };39 const separate_args0 = .{ a, b };
40 //TODO const separate_args1 = .{ a, 34 };40 const separate_args1 = .{ a, 34 };
41 const separate_args2 = .{ 12, 34 };41 const separate_args2 = .{ 12, 34 };
42 //TODO const separate_args3 = .{ 12, b };42 const separate_args3 = .{ 12, b };
43 expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46);43 expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46);
44 // TODO expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46);44 expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46);
45 expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46);45 expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46);
46 // TODO expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);46 expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);
47 }47 }
48}48}
test/stage1/behavior/struct.zig-2
...@@ -775,8 +775,6 @@ test "anonymous struct literal assigned to variable" {...@@ -775,8 +775,6 @@ test "anonymous struct literal assigned to variable" {
775 expect(vec.@"0" == 22);775 expect(vec.@"0" == 22);
776 expect(vec.@"1" == 55);776 expect(vec.@"1" == 55);
777 expect(vec.@"2" == 99);777 expect(vec.@"2" == 99);
778 vec.@"1" += 1;
779 expect(vec.@"1" == 56);
780}778}
781779
782test "struct with var field" {780test "struct with var field" {