authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-22 14:46:26-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-22 14:46:26-04:00
log26b79ac90ee8cf17f28b0584c773be759e0e49bd
tree78fc31e987e4d1ef8ee56d2da775ef1cea9b52d9
parent0d6a6c76eabcd020c5f58dc4667766b0e2756dfa
signature Commit is signed but in an unrecognized format.

simple self-referential struct is working now


2 files changed, 182 insertions(+), 36 deletions(-)

src/analyze.cpp+169-31
...@@ -955,6 +955,126 @@ ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, Zig...@@ -955,6 +955,126 @@ ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, Zig
955 return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false);955 return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false);
956}956}
957957
958static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type,
959 bool *is_zero_bits)
960{
961 Error err;
962 if (type_val->special != ConstValSpecialLazy) {
963 assert(type_val->special == ConstValSpecialStatic);
964 if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown)))
965 return err;
966 *is_zero_bits = (type_val->data.x_type->abi_size == 0);
967 return ErrorNone;
968 }
969 switch (type_val->data.x_lazy->id) {
970 case LazyValueIdInvalid:
971 case LazyValueIdAlignOf:
972 zig_unreachable();
973 case LazyValueIdPtrType: {
974 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
975 if (lazy_ptr_type->elem_type == parent_type) {
976 // Does a struct which contains a pointer field to itself have bits? Yes.
977 *is_zero_bits = false;
978 return ErrorNone;
979 } else {
980 if ((err = type_resolve(g, lazy_ptr_type->elem_type, ResolveStatusZeroBitsKnown)))
981 return err;
982 *is_zero_bits = type_has_bits(lazy_ptr_type->elem_type);
983 return ErrorNone;
984 }
985 }
986 case LazyValueIdSliceType:
987 *is_zero_bits = false;
988 return ErrorNone;
989 }
990 zig_unreachable();
991}
992
993static Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool *is_opaque_type) {
994 if (type_val->special != ConstValSpecialLazy) {
995 assert(type_val->special == ConstValSpecialStatic);
996 *is_opaque_type = (type_val->data.x_type->id == ZigTypeIdOpaque);
997 return ErrorNone;
998 }
999 switch (type_val->data.x_lazy->id) {
1000 case LazyValueIdInvalid:
1001 case LazyValueIdAlignOf:
1002 zig_unreachable();
1003 case LazyValueIdSliceType:
1004 case LazyValueIdPtrType:
1005 *is_opaque_type = false;
1006 return ErrorNone;
1007 }
1008 zig_unreachable();
1009}
1010
1011static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type) {
1012 if (type_val->special != ConstValSpecialLazy) {
1013 return type_requires_comptime(g, type_val->data.x_type, parent_type);
1014 }
1015 switch (type_val->data.x_lazy->id) {
1016 case LazyValueIdInvalid:
1017 case LazyValueIdAlignOf:
1018 zig_unreachable();
1019 case LazyValueIdSliceType: {
1020 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
1021 return type_requires_comptime(g, lazy_slice_type->elem_type, parent_type);
1022 }
1023 case LazyValueIdPtrType: {
1024 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1025 return type_requires_comptime(g, lazy_ptr_type->elem_type, parent_type);
1026 }
1027 }
1028 zig_unreachable();
1029}
1030
1031static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, size_t *abi_align) {
1032 Error err;
1033 if (type_val->special != ConstValSpecialLazy) {
1034 assert(type_val->special == ConstValSpecialStatic);
1035 if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusAlignmentKnown)))
1036 return err;
1037 *abi_align = type_val->data.x_type->abi_align;
1038 return ErrorNone;
1039 }
1040 switch (type_val->data.x_lazy->id) {
1041 case LazyValueIdInvalid:
1042 case LazyValueIdAlignOf:
1043 zig_unreachable();
1044 case LazyValueIdSliceType:
1045 case LazyValueIdPtrType:
1046 *abi_align = g->builtin_types.entry_usize->abi_align;
1047 return ErrorNone;
1048 }
1049 zig_unreachable();
1050}
1051
1052static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ConstExprValue *type_val) {
1053 if (type_val->special != ConstValSpecialLazy) {
1054 return type_has_one_possible_value(g, type_val->data.x_type);
1055 }
1056 switch (type_val->data.x_lazy->id) {
1057 case LazyValueIdInvalid:
1058 case LazyValueIdAlignOf:
1059 zig_unreachable();
1060 case LazyValueIdSliceType:
1061 return OnePossibleValueNo; // it has the len field
1062 case LazyValueIdPtrType: {
1063 Error err;
1064 bool zero_bits;
1065 if ((err = type_val_resolve_zero_bits(g, type_val, nullptr, &zero_bits))) {
1066 return OnePossibleValueInvalid;
1067 }
1068 if (zero_bits) {
1069 return OnePossibleValueYes;
1070 } else {
1071 return OnePossibleValueNo;
1072 }
1073 }
1074 }
1075 zig_unreachable();
1076}
1077
958ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {1078ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
959 ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr);1079 ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr);
960 if (type_is_invalid(result->type))1080 if (type_is_invalid(result->type))
...@@ -1604,14 +1724,38 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -1604,14 +1724,38 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
16041724
1605 uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr;1725 uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr;
16061726
1607 // Resolve sizes of all the field types. Done before the offset loop because the offset1727 // Resolve types for fields and then resolve sizes of all the field types.
1608 // loop has to look ahead.1728 // This is done before the offset loop because the offset loop has to look ahead.
1609 for (size_t i = 0; i < field_count; i += 1) {1729 for (size_t i = 0; i < field_count; i += 1) {
1730 AstNode *field_source_node = decl_node->data.container_decl.fields.at(i);
1610 TypeStructField *field = &struct_type->data.structure.fields[i];1731 TypeStructField *field = &struct_type->data.structure.fields[i];
1732
1733 if ((err = ir_resolve_lazy(g, field_source_node, field->type_val))) {
1734 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1735 return err;
1736 }
1737 field->type_entry = field->type_val->data.x_type;
1738
1611 if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) {1739 if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) {
1612 struct_type->data.structure.resolve_status = ResolveStatusInvalid;1740 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1741 return err;
1742 }
1743
1744 if (struct_type->data.structure.layout == ContainerLayoutExtern &&
1745 !type_allowed_in_extern(g, field->type_entry))
1746 {
1747 add_node_error(g, field_source_node,
1748 buf_sprintf("extern structs cannot contain fields of type '%s'",
1749 buf_ptr(&field->type_entry->name)));
1750 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1613 return ErrorSemanticAnalyzeFail;1751 return ErrorSemanticAnalyzeFail;
1752 } else if (packed) {
1753 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field_source_node))) {
1754 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1755 return err;
1756 }
1614 }1757 }
1758
1615 }1759 }
16161760
1617 size_t packed_bits_offset = 0;1761 size_t packed_bits_offset = 0;
...@@ -2133,40 +2277,33 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2133,40 +2277,33 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2133 return ErrorSemanticAnalyzeFail;2277 return ErrorSemanticAnalyzeFail;
2134 }2278 }
21352279
2136 ZigType *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);2280 ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope,
2137 type_struct_field->type_entry = field_type;2281 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true);
2138 if (type_is_invalid(field_type)) {2282 if (type_is_invalid(field_type_val->type)) {
2139 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2283 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2140 return ErrorSemanticAnalyzeFail;2284 return ErrorSemanticAnalyzeFail;
2141 }2285 }
2286 assert(field_type_val->special != ConstValSpecialRuntime);
2287 type_struct_field->type_val = field_type_val;
2142 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)2288 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2143 return ErrorSemanticAnalyzeFail;2289 return ErrorSemanticAnalyzeFail;
21442290
2145 if (struct_type->data.structure.layout == ContainerLayoutExtern &&2291 bool field_is_opaque_type;
2146 !type_allowed_in_extern(g, field_type))2292 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
2147 {
2148 add_node_error(g, field_node,
2149 buf_sprintf("extern structs cannot contain fields of type '%s'",
2150 buf_ptr(&field_type->name)));
2151 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2293 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2152 return ErrorSemanticAnalyzeFail;2294 return ErrorSemanticAnalyzeFail;
2153 } else if (struct_type->data.structure.layout == ContainerLayoutPacked) {
2154 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_node))) {
2155 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2156 return ErrorSemanticAnalyzeFail;
2157 }
2158 }2295 }
21592296 if (field_is_opaque_type) {
2160 type_struct_field->src_index = i;
2161 type_struct_field->gen_index = SIZE_MAX;
2162
2163 if (field_type->id == ZigTypeIdOpaque) {
2164 add_node_error(g, field_node->data.struct_field.type,2297 add_node_error(g, field_node->data.struct_field.type,
2165 buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));2298 buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));
2166 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2299 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2167 return ErrorSemanticAnalyzeFail;2300 return ErrorSemanticAnalyzeFail;
2168 }2301 }
2169 switch (type_requires_comptime(g, field_type, struct_type)) {2302
2303 type_struct_field->src_index = i;
2304 type_struct_field->gen_index = SIZE_MAX;
2305
2306 switch (type_val_resolve_requires_comptime(g, field_type_val, struct_type)) {
2170 case ReqCompTimeYes:2307 case ReqCompTimeYes:
2171 struct_type->data.structure.requires_comptime = true;2308 struct_type->data.structure.requires_comptime = true;
2172 break;2309 break;
...@@ -2177,7 +2314,12 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2177,7 +2314,12 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2177 break;2314 break;
2178 }2315 }
21792316
2180 if (!type_has_bits(field_type))2317 bool field_is_zero_bits;
2318 if ((err = type_val_resolve_zero_bits(g, field_type_val, struct_type, &field_is_zero_bits))) {
2319 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2320 return ErrorSemanticAnalyzeFail;
2321 }
2322 if (field_is_zero_bits)
2181 continue;2323 continue;
21822324
2183 type_struct_field->gen_index = gen_field_index;2325 type_struct_field->gen_index = gen_field_index;
...@@ -2234,21 +2376,17 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2234,21 +2376,17 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2234 if (field->gen_index == SIZE_MAX)2376 if (field->gen_index == SIZE_MAX)
2235 continue;2377 continue;
22362378
2237 src_assert(field->type_entry != nullptr, decl_node);2379 // TODO: https://github.com/ziglang/zig/issues/1512
2238
2239 size_t this_field_align;2380 size_t this_field_align;
2240 if (packed) {2381 if (packed) {
2241 // TODO: https://github.com/ziglang/zig/issues/1512
2242 this_field_align = 1;2382 this_field_align = 1;
2243 } else {2383 } else {
2244 if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {2384 if ((err = type_val_resolve_abi_align(g, field->type_val, &this_field_align))) {
2245 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2385 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2246 return ErrorSemanticAnalyzeFail;2386 return err;
2247 }2387 }
2248 this_field_align = field->type_entry->abi_align;
2249 }2388 }
22502389
2251 // TODO: https://github.com/ziglang/zig/issues/1512
2252 if (this_field_align > struct_type->abi_align) {2390 if (this_field_align > struct_type->abi_align) {
2253 struct_type->abi_align = this_field_align;2391 struct_type->abi_align = this_field_align;
2254 }2392 }
...@@ -4725,7 +4863,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -4725,7 +4863,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
4725 case ZigTypeIdStruct:4863 case ZigTypeIdStruct:
4726 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {4864 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
4727 TypeStructField *field = &type_entry->data.structure.fields[i];4865 TypeStructField *field = &type_entry->data.structure.fields[i];
4728 switch (type_has_one_possible_value(g, field->type_entry)) {4866 switch (type_val_resolve_has_one_possible_value(g, field->type_val)) {
4729 case OnePossibleValueInvalid:4867 case OnePossibleValueInvalid:
4730 return OnePossibleValueInvalid;4868 return OnePossibleValueInvalid;
4731 case OnePossibleValueNo:4869 case OnePossibleValueNo:
src/ir.cpp+13-5
...@@ -10814,10 +10814,6 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod...@@ -10814,10 +10814,6 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
1081410814
10815 if (!allow_lazy) {10815 if (!allow_lazy) {
10816 if ((err = ir_resolve_lazy(codegen, node, result))) {10816 if ((err = ir_resolve_lazy(codegen, node, result))) {
10817 if (codegen->trace_err != nullptr) {
10818 codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node,
10819 buf_create_from_str("referenced here"));
10820 }
10821 return &codegen->invalid_instruction->value;10817 return &codegen->invalid_instruction->value;
10822 }10818 }
10823 }10819 }
...@@ -25429,7 +25425,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -25429,7 +25425,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
25429 zig_unreachable();25425 zig_unreachable();
25430}25426}
2543125427
25432Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) {25428static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) {
25433 Error err;25429 Error err;
25434 if (val->special != ConstValSpecialLazy)25430 if (val->special != ConstValSpecialLazy)
25435 return ErrorNone;25431 return ErrorNone;
...@@ -25491,3 +25487,15 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *va...@@ -25491,3 +25487,15 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *va
25491 }25487 }
25492 zig_unreachable();25488 zig_unreachable();
25493}25489}
25490
25491Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) {
25492 Error err;
25493 if ((err = ir_resolve_lazy_raw(codegen, source_node, val))) {
25494 if (codegen->trace_err != nullptr) {
25495 codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node,
25496 buf_create_from_str("referenced here"));
25497 }
25498 return err;
25499 }
25500 return ErrorNone;
25501}