authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-08 10:59:24-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-08 10:59:24-05:00
logb57cb04afc1898c3b21ef3486709f0c0aa285433
treee234c061c28a95c35afbb35b80b89e3114ecdeb9
parent73a306e2fa11c146b5f79a41953e0d19a82f17a5
parent2e010c60ae006944ae20ab8b3445598471c9f1e8

Merge remote-tracking branch 'origin/master' into llvm6


22 files changed, 909 insertions(+), 352 deletions(-)

README.md+2-2
......@@ -125,13 +125,13 @@ libc. Create demo games using Zig.
125125
126126 * cmake >= 2.8.5
127127 * gcc >= 5.0.0 or clang >= 3.6.0
128 * LLVM, Clang, LLD libraries == 6.x, compiled with the same gcc or clang version above
128 * LLVM, Clang, LLD development libraries == 6.x, compiled with the same gcc or clang version above
129129
130130##### Windows
131131
132132 * cmake >= 2.8.5
133133 * Microsoft Visual Studio 2015
134 * LLVM, Clang, LLD libraries == 6.x, compiled with the same MSVC version above
134 * LLVM, Clang, LLD development libraries == 6.x, compiled with the same MSVC version above
135135
136136#### Instructions
137137
doc/langref.html.in+3-3
......@@ -5733,19 +5733,19 @@ UseDecl = "use" Expression ";"
57335733
57345734ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"
57355735
5736FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") TypeExpr
5736FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") (TypeExpr | "var")
57375737
57385738FnDef = option("inline" | "export") FnProto Block
57395739
57405740ParamDeclList = "(" list(ParamDecl, ",") ")"
57415741
5742ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")
5742ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "var" | "...")
57435743
57445744Block = option(Symbol ":") "{" many(Statement) "}"
57455745
57465746Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
57475747
5748TypeExpr = ErrorSetExpr | "var"
5748TypeExpr = ErrorSetExpr
57495749
57505750ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
57515751
src/all_types.hpp+5-6
......@@ -16,6 +16,7 @@
1616#include "bigint.hpp"
1717#include "bigfloat.hpp"
1818#include "target.hpp"
19#include "tokenizer.hpp"
1920
2021struct AstNode;
2122struct ImportTableEntry;
......@@ -399,7 +400,6 @@ enum NodeType {
399400 NodeTypeStructValueField,
400401 NodeTypeArrayType,
401402 NodeTypeErrorType,
402 NodeTypeVarLiteral,
403403 NodeTypeIfErrorExpr,
404404 NodeTypeTestExpr,
405405 NodeTypeErrorSetDecl,
......@@ -427,6 +427,7 @@ struct AstNodeFnProto {
427427 Buf *name;
428428 ZigList<AstNode *> params;
429429 AstNode *return_type;
430 Token *return_var_token;
430431 bool is_var_args;
431432 bool is_extern;
432433 bool is_export;
......@@ -456,6 +457,7 @@ struct AstNodeFnDecl {
456457struct AstNodeParamDecl {
457458 Buf *name;
458459 AstNode *type;
460 Token *var_token;
459461 bool is_noalias;
460462 bool is_inline;
461463 bool is_var_args;
......@@ -866,9 +868,6 @@ struct AstNodeUnreachableExpr {
866868struct AstNodeErrorType {
867869};
868870
869struct AstNodeVarLiteral {
870};
871
872871struct AstNodeAwaitExpr {
873872 AstNode *expr;
874873};
......@@ -933,7 +932,6 @@ struct AstNode {
933932 AstNodeUnreachableExpr unreachable_expr;
934933 AstNodeArrayType array_type;
935934 AstNodeErrorType error_type;
936 AstNodeVarLiteral var_literal;
937935 AstNodeErrorSetDecl err_set_decl;
938936 AstNodeCancelExpr cancel_expr;
939937 AstNodeResumeExpr resume_expr;
......@@ -1098,6 +1096,8 @@ struct TypeTableEntryUnion {
10981096 size_t gen_union_index;
10991097 size_t gen_tag_index;
11001098
1099 bool have_explicit_tag_type;
1100
11011101 uint32_t union_size_bytes;
11021102 TypeTableEntry *most_aligned_union_member;
11031103
......@@ -1134,7 +1134,6 @@ struct TypeTableEntryPromise {
11341134
11351135enum TypeTableEntryId {
11361136 TypeTableEntryIdInvalid,
1137 TypeTableEntryIdVar,
11381137 TypeTableEntryIdMetaType,
11391138 TypeTableEntryIdVoid,
11401139 TypeTableEntryIdBool,
src/analyze.cpp+53-39
......@@ -200,7 +200,6 @@ static uint8_t bits_needed_for_unsigned(uint64_t x) {
200200bool type_is_complete(TypeTableEntry *type_entry) {
201201 switch (type_entry->id) {
202202 case TypeTableEntryIdInvalid:
203 case TypeTableEntryIdVar:
204203 zig_unreachable();
205204 case TypeTableEntryIdStruct:
206205 return type_entry->data.structure.complete;
......@@ -239,7 +238,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {
239238bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
240239 switch (type_entry->id) {
241240 case TypeTableEntryIdInvalid:
242 case TypeTableEntryIdVar:
243241 zig_unreachable();
244242 case TypeTableEntryIdStruct:
245243 return type_entry->data.structure.zero_bits_known;
......@@ -466,9 +464,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
466464 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);
467465 const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};
468466 TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};
469 size_t field_count = type_has_bits(result_ptr_type) ? 3 : 1;
470467 Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));
471 TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names, field_types, field_count);
468 TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names, field_types, 3);
472469
473470 return_type->promise_frame_parent = entry;
474471 return entry;
......@@ -1281,7 +1278,6 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
12811278static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
12821279 switch (type_entry->id) {
12831280 case TypeTableEntryIdInvalid:
1284 case TypeTableEntryIdVar:
12851281 zig_unreachable();
12861282 case TypeTableEntryIdMetaType:
12871283 case TypeTableEntryIdUnreachable:
......@@ -1324,7 +1320,6 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
13241320static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
13251321 switch (type_entry->id) {
13261322 case TypeTableEntryIdInvalid:
1327 case TypeTableEntryIdVar:
13281323 zig_unreachable();
13291324 case TypeTableEntryIdMetaType:
13301325 case TypeTableEntryIdNumLitFloat:
......@@ -1428,6 +1423,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
14281423 calling_convention_name(fn_type_id.cc)));
14291424 return g->builtin_types.entry_invalid;
14301425 }
1426 } else if (param_node->data.param_decl.var_token != nullptr) {
1427 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1428 add_node_error(g, param_node->data.param_decl.type,
1429 buf_sprintf("parameter of type 'var' not allowed in function with calling convention '%s'",
1430 calling_convention_name(fn_type_id.cc)));
1431 return g->builtin_types.entry_invalid;
1432 }
1433 return get_generic_fn_type(g, &fn_type_id);
14311434 }
14321435
14331436 TypeTableEntry *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type);
......@@ -1463,14 +1466,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
14631466 add_node_error(g, param_node->data.param_decl.type,
14641467 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
14651468 return g->builtin_types.entry_invalid;
1466 case TypeTableEntryIdVar:
1467 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1468 add_node_error(g, param_node->data.param_decl.type,
1469 buf_sprintf("parameter of type 'var' not allowed in function with calling convention '%s'",
1470 calling_convention_name(fn_type_id.cc)));
1471 return g->builtin_types.entry_invalid;
1472 }
1473 return get_generic_fn_type(g, &fn_type_id);
14741469 case TypeTableEntryIdNumLitFloat:
14751470 case TypeTableEntryIdNumLitInt:
14761471 case TypeTableEntryIdNamespace:
......@@ -1514,6 +1509,19 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
15141509 }
15151510 }
15161511
1512 if (fn_proto->return_var_token != nullptr) {
1513 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1514 add_node_error(g, fn_proto->return_type,
1515 buf_sprintf("return type 'var' not allowed in function with calling convention '%s'",
1516 calling_convention_name(fn_type_id.cc)));
1517 return g->builtin_types.entry_invalid;
1518 }
1519 add_node_error(g, proto_node,
1520 buf_sprintf("TODO implement inferred return types https://github.com/zig-lang/zig/issues/447"));
1521 return g->builtin_types.entry_invalid;
1522 //return get_generic_fn_type(g, &fn_type_id);
1523 }
1524
15171525 TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
15181526 if (type_is_invalid(specified_return_type)) {
15191527 fn_type_id.return_type = g->builtin_types.entry_invalid;
......@@ -1552,7 +1560,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
15521560 case TypeTableEntryIdNamespace:
15531561 case TypeTableEntryIdBlock:
15541562 case TypeTableEntryIdBoundFn:
1555 case TypeTableEntryIdVar:
15561563 case TypeTableEntryIdMetaType:
15571564 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
15581565 add_node_error(g, fn_proto->return_type,
......@@ -1707,7 +1714,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17071714 buf_init_from_str(&struct_type->name, type_name);
17081715
17091716 struct_type->data.structure.src_field_count = field_count;
1710 struct_type->data.structure.gen_field_count = field_count;
1717 struct_type->data.structure.gen_field_count = 0;
17111718 struct_type->data.structure.zero_bits_known = true;
17121719 struct_type->data.structure.complete = true;
17131720 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
......@@ -1716,22 +1723,26 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17161723 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
17171724 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
17181725 for (size_t i = 0; i < field_count; i += 1) {
1719 element_types[i] = field_types[i]->type_ref;
1726 element_types[struct_type->data.structure.gen_field_count] = field_types[i]->type_ref;
17201727
17211728 TypeStructField *field = &struct_type->data.structure.fields[i];
17221729 field->name = buf_create_from_str(field_names[i]);
17231730 field->type_entry = field_types[i];
17241731 field->src_index = i;
1725 field->gen_index = i;
17261732
1727 assert(type_has_bits(field->type_entry));
1733 if (type_has_bits(field->type_entry)) {
1734 field->gen_index = struct_type->data.structure.gen_field_count;
1735 struct_type->data.structure.gen_field_count += 1;
1736 } else {
1737 field->gen_index = SIZE_MAX;
1738 }
17281739
17291740 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
17301741 assert(prev_entry == nullptr);
17311742 }
17321743
17331744 struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name);
1734 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
1745 LLVMStructSetBody(struct_type->type_ref, element_types, struct_type->data.structure.gen_field_count, false);
17351746
17361747 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
17371748 ZigLLVMTag_DW_structure_type(), type_name,
......@@ -1739,11 +1750,14 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17391750
17401751 for (size_t i = 0; i < field_count; i += 1) {
17411752 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1753 if (type_struct_field->gen_index == SIZE_MAX) {
1754 continue;
1755 }
17421756 TypeTableEntry *field_type = type_struct_field->type_entry;
17431757 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
17441758 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
1745 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, i);
1746 di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1759 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, type_struct_field->gen_index);
1760 di_element_types[type_struct_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
17471761 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
17481762 nullptr, 0,
17491763 debug_size_in_bits,
......@@ -1751,7 +1765,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17511765 debug_offset_in_bits,
17521766 0, field_type->di_type);
17531767
1754 assert(di_element_types[i]);
1768 assert(di_element_types[type_struct_field->gen_index]);
17551769 }
17561770
17571771 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref);
......@@ -1762,7 +1776,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17621776 debug_size_in_bits,
17631777 debug_align_in_bits,
17641778 0,
1765 nullptr, di_element_types, field_count, 0, nullptr, "");
1779 nullptr, di_element_types, struct_type->data.structure.gen_field_count, 0, nullptr, "");
17661780
17671781 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
17681782 struct_type->di_type = replacement_di_type;
......@@ -2544,6 +2558,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
25442558 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
25452559
25462560 AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr;
2561 union_type->data.unionation.have_explicit_tag_type = decl_node->data.container_decl.auto_enum ||
2562 enum_type_node != nullptr;
25472563 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
25482564 bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr);
25492565 TypeTableEntry *tag_type;
......@@ -3226,7 +3242,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
32263242 case NodeTypeStructValueField:
32273243 case NodeTypeArrayType:
32283244 case NodeTypeErrorType:
3229 case NodeTypeVarLiteral:
32303245 case NodeTypeIfErrorExpr:
32313246 case NodeTypeTestExpr:
32323247 case NodeTypeErrorSetDecl:
......@@ -3262,7 +3277,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
32623277 case TypeTableEntryIdInvalid:
32633278 return g->builtin_types.entry_invalid;
32643279 case TypeTableEntryIdUnreachable:
3265 case TypeTableEntryIdVar:
32663280 case TypeTableEntryIdNumLitFloat:
32673281 case TypeTableEntryIdNumLitInt:
32683282 case TypeTableEntryIdUndefLit:
......@@ -3641,7 +3655,6 @@ TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *t
36413655static bool is_container(TypeTableEntry *type_entry) {
36423656 switch (type_entry->id) {
36433657 case TypeTableEntryIdInvalid:
3644 case TypeTableEntryIdVar:
36453658 zig_unreachable();
36463659 case TypeTableEntryIdStruct:
36473660 case TypeTableEntryIdEnum:
......@@ -3716,7 +3729,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
37163729 case TypeTableEntryIdBlock:
37173730 case TypeTableEntryIdBoundFn:
37183731 case TypeTableEntryIdInvalid:
3719 case TypeTableEntryIdVar:
37203732 case TypeTableEntryIdArgTuple:
37213733 case TypeTableEntryIdOpaque:
37223734 case TypeTableEntryIdPromise:
......@@ -3753,6 +3765,19 @@ uint32_t get_ptr_align(TypeTableEntry *type) {
37533765 }
37543766}
37553767
3768bool get_ptr_const(TypeTableEntry *type) {
3769 TypeTableEntry *ptr_type = get_codegen_ptr_type(type);
3770 if (ptr_type->id == TypeTableEntryIdPointer) {
3771 return ptr_type->data.pointer.is_const;
3772 } else if (ptr_type->id == TypeTableEntryIdFn) {
3773 return true;
3774 } else if (ptr_type->id == TypeTableEntryIdPromise) {
3775 return true;
3776 } else {
3777 zig_unreachable();
3778 }
3779}
3780
37563781AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) {
37573782 if (fn_entry->param_source_nodes)
37583783 return fn_entry->param_source_nodes[index];
......@@ -4203,7 +4228,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
42034228 case TypeTableEntryIdNamespace:
42044229 case TypeTableEntryIdBlock:
42054230 case TypeTableEntryIdBoundFn:
4206 case TypeTableEntryIdVar:
42074231 case TypeTableEntryIdArgTuple:
42084232 case TypeTableEntryIdOpaque:
42094233 zig_unreachable();
......@@ -4502,7 +4526,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
45024526 case TypeTableEntryIdBoundFn:
45034527 case TypeTableEntryIdInvalid:
45044528 case TypeTableEntryIdUnreachable:
4505 case TypeTableEntryIdVar:
45064529 zig_unreachable();
45074530 }
45084531 zig_unreachable();
......@@ -4600,7 +4623,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {
46004623bool type_requires_comptime(TypeTableEntry *type_entry) {
46014624 switch (type_entry->id) {
46024625 case TypeTableEntryIdInvalid:
4603 case TypeTableEntryIdVar:
46044626 case TypeTableEntryIdOpaque:
46054627 zig_unreachable();
46064628 case TypeTableEntryIdNumLitFloat:
......@@ -5096,7 +5118,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
50965118 case TypeTableEntryIdBoundFn:
50975119 case TypeTableEntryIdInvalid:
50985120 case TypeTableEntryIdUnreachable:
5099 case TypeTableEntryIdVar:
51005121 case TypeTableEntryIdPromise:
51015122 zig_unreachable();
51025123 }
......@@ -5176,9 +5197,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
51765197 case TypeTableEntryIdInvalid:
51775198 buf_appendf(buf, "(invalid)");
51785199 return;
5179 case TypeTableEntryIdVar:
5180 buf_appendf(buf, "(var)");
5181 return;
51825200 case TypeTableEntryIdVoid:
51835201 buf_appendf(buf, "{}");
51845202 return;
......@@ -5414,7 +5432,6 @@ TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits)
54145432uint32_t type_id_hash(TypeId x) {
54155433 switch (x.id) {
54165434 case TypeTableEntryIdInvalid:
5417 case TypeTableEntryIdVar:
54185435 case TypeTableEntryIdOpaque:
54195436 case TypeTableEntryIdMetaType:
54205437 case TypeTableEntryIdVoid:
......@@ -5461,7 +5478,6 @@ bool type_id_eql(TypeId a, TypeId b) {
54615478 return false;
54625479 switch (a.id) {
54635480 case TypeTableEntryIdInvalid:
5464 case TypeTableEntryIdVar:
54655481 case TypeTableEntryIdMetaType:
54665482 case TypeTableEntryIdVoid:
54675483 case TypeTableEntryIdBool:
......@@ -5616,7 +5632,6 @@ size_t type_id_len() {
56165632size_t type_id_index(TypeTableEntryId id) {
56175633 switch (id) {
56185634 case TypeTableEntryIdInvalid:
5619 case TypeTableEntryIdVar:
56205635 zig_unreachable();
56215636 case TypeTableEntryIdMetaType:
56225637 return 0;
......@@ -5675,7 +5690,6 @@ size_t type_id_index(TypeTableEntryId id) {
56755690const char *type_id_name(TypeTableEntryId id) {
56765691 switch (id) {
56775692 case TypeTableEntryIdInvalid:
5678 case TypeTableEntryIdVar:
56795693 zig_unreachable();
56805694 case TypeTableEntryIdMetaType:
56815695 return "Type";
src/analyze.hpp+1
......@@ -55,6 +55,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);
5555
5656TypeTableEntry *get_codegen_ptr_type(TypeTableEntry *type);
5757uint32_t get_ptr_align(TypeTableEntry *type);
58bool get_ptr_const(TypeTableEntry *type);
5859TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
5960TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
6061bool type_is_complete(TypeTableEntry *type_entry);
src/ast_render.cpp+16-12
......@@ -236,8 +236,6 @@ static const char *node_type_str(NodeType node_type) {
236236 return "ArrayType";
237237 case NodeTypeErrorType:
238238 return "ErrorType";
239 case NodeTypeVarLiteral:
240 return "VarLiteral";
241239 case NodeTypeIfErrorExpr:
242240 return "IfErrorExpr";
243241 case NodeTypeTestExpr:
......@@ -436,6 +434,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
436434 }
437435 if (param_decl->data.param_decl.is_var_args) {
438436 fprintf(ar->f, "...");
437 } else if (param_decl->data.param_decl.var_token != nullptr) {
438 fprintf(ar->f, "var");
439439 } else {
440440 render_node_grouped(ar, param_decl->data.param_decl.type);
441441 }
......@@ -456,13 +456,17 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
456456 fprintf(ar->f, ")");
457457 }
458458
459 AstNode *return_type_node = node->data.fn_proto.return_type;
460 assert(return_type_node != nullptr);
461 fprintf(ar->f, " ");
462 if (node->data.fn_proto.auto_err_set) {
463 fprintf(ar->f, "!");
459 if (node->data.fn_proto.return_var_token != nullptr) {
460 fprintf(ar->f, "var");
461 } else {
462 AstNode *return_type_node = node->data.fn_proto.return_type;
463 assert(return_type_node != nullptr);
464 fprintf(ar->f, " ");
465 if (node->data.fn_proto.auto_err_set) {
466 fprintf(ar->f, "!");
467 }
468 render_node_grouped(ar, return_type_node);
464469 }
465 render_node_grouped(ar, return_type_node);
466470 break;
467471 }
468472 case NodeTypeFnDef:
......@@ -486,7 +490,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
486490 AstNode *statement = node->data.block.statements.at(i);
487491 print_indent(ar);
488492 render_node_grouped(ar, statement);
489 fprintf(ar->f, ";");
493
494 if (!statement_terminates_without_semicolon(statement))
495 fprintf(ar->f, ";");
496
490497 fprintf(ar->f, "\n");
491498 }
492499 ar->indent -= ar->indent_size;
......@@ -768,9 +775,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
768775 case NodeTypeErrorType:
769776 fprintf(ar->f, "error");
770777 break;
771 case NodeTypeVarLiteral:
772 fprintf(ar->f, "var");
773 break;
774778 case NodeTypeAsmExpr:
775779 {
776780 AstNodeAsmExpr *asm_expr = &node->data.asm_expr;
src/codegen.cpp-10
......@@ -4508,7 +4508,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
45084508 assert(!type_entry->zero_bits);
45094509 switch (type_entry->id) {
45104510 case TypeTableEntryIdInvalid:
4511 case TypeTableEntryIdVar:
45124511 case TypeTableEntryIdMetaType:
45134512 case TypeTableEntryIdUnreachable:
45144513 case TypeTableEntryIdNumLitFloat:
......@@ -4960,7 +4959,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
49604959 case TypeTableEntryIdNamespace:
49614960 case TypeTableEntryIdBlock:
49624961 case TypeTableEntryIdBoundFn:
4963 case TypeTableEntryIdVar:
49644962 case TypeTableEntryIdArgTuple:
49654963 case TypeTableEntryIdOpaque:
49664964 case TypeTableEntryIdPromise:
......@@ -5611,11 +5609,6 @@ static void define_builtin_types(CodeGen *g) {
56115609 entry->zero_bits = true;
56125610 g->builtin_types.entry_null = entry;
56135611 }
5614 {
5615 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVar);
5616 buf_init_from_str(&entry->name, "(var)");
5617 g->builtin_types.entry_var = entry;
5618 }
56195612 {
56205613 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArgTuple);
56215614 buf_init_from_str(&entry->name, "(args)");
......@@ -6444,7 +6437,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry
64446437
64456438 switch (type_entry->id) {
64466439 case TypeTableEntryIdInvalid:
6447 case TypeTableEntryIdVar:
64486440 case TypeTableEntryIdMetaType:
64496441 case TypeTableEntryIdNumLitFloat:
64506442 case TypeTableEntryIdNumLitInt:
......@@ -6639,7 +6631,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf
66396631 case TypeTableEntryIdNumLitInt:
66406632 case TypeTableEntryIdUndefLit:
66416633 case TypeTableEntryIdNullLit:
6642 case TypeTableEntryIdVar:
66436634 case TypeTableEntryIdArgTuple:
66446635 case TypeTableEntryIdPromise:
66456636 zig_unreachable();
......@@ -6781,7 +6772,6 @@ static void gen_h_file(CodeGen *g) {
67816772 TypeTableEntry *type_entry = gen_h->types_to_declare.at(type_i);
67826773 switch (type_entry->id) {
67836774 case TypeTableEntryIdInvalid:
6784 case TypeTableEntryIdVar:
67856775 case TypeTableEntryIdMetaType:
67866776 case TypeTableEntryIdVoid:
67876777 case TypeTableEntryIdBool:
src/ir.cpp+80-92
......@@ -948,12 +948,10 @@ static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope,
948948 const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;
949949 const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;
950950 const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;
951 if (struct_type->data.structure.src_field_count > 1) {
952 const_instruction->base.value.data.x_struct.fields[1].type = return_type;
953 const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef;
954 const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry;
955 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
956 }
951 const_instruction->base.value.data.x_struct.fields[1].type = return_type;
952 const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef;
953 const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry;
954 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
957955 return &const_instruction->base;
958956}
959957
......@@ -2147,7 +2145,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s
21472145 size_t param_count = source_node->data.fn_proto.params.length;
21482146 if (is_var_args) param_count -= 1;
21492147 for (size_t i = 0; i < param_count; i += 1) {
2150 ir_ref_instruction(param_types[i], irb->current_basic_block);
2148 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);
21512149 }
21522150 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
21532151 ir_ref_instruction(return_type, irb->current_basic_block);
......@@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
27412739 return return_inst;
27422740 }
27432741
2744 if (irb->exec->coro_result_ptr_field_ptr) {
2745 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
2746 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2747 }
2742 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
2743 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
27482744 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,
27492745 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
27502746 // TODO replace replacement_value with @intToPtr(?promise, 0x1) when it doesn't crash zig
......@@ -3305,12 +3301,6 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode
33053301 return ir_build_const_null(irb, scope, node);
33063302}
33073303
3308static IrInstruction *ir_gen_var_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
3309 assert(node->type == NodeTypeVarLiteral);
3310
3311 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var);
3312}
3313
33143304static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
33153305 assert(node->type == NodeTypeSymbol);
33163306
......@@ -5916,11 +5906,15 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
59165906 is_var_args = true;
59175907 break;
59185908 }
5919 AstNode *type_node = param_node->data.param_decl.type;
5920 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope);
5921 if (type_value == irb->codegen->invalid_instruction)
5922 return irb->codegen->invalid_instruction;
5923 param_types[i] = type_value;
5909 if (param_node->data.param_decl.var_token == nullptr) {
5910 AstNode *type_node = param_node->data.param_decl.type;
5911 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope);
5912 if (type_value == irb->codegen->invalid_instruction)
5913 return irb->codegen->invalid_instruction;
5914 param_types[i] = type_value;
5915 } else {
5916 param_types[i] = nullptr;
5917 }
59245918 }
59255919
59265920 IrInstruction *align_value = nullptr;
......@@ -5931,12 +5925,16 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
59315925 }
59325926
59335927 IrInstruction *return_type;
5934 if (node->data.fn_proto.return_type == nullptr) {
5935 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void);
5928 if (node->data.fn_proto.return_var_token == nullptr) {
5929 if (node->data.fn_proto.return_type == nullptr) {
5930 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void);
5931 } else {
5932 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);
5933 if (return_type == irb->codegen->invalid_instruction)
5934 return irb->codegen->invalid_instruction;
5935 }
59365936 } else {
5937 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);
5938 if (return_type == irb->codegen->invalid_instruction)
5939 return irb->codegen->invalid_instruction;
5937 return_type = nullptr;
59405938 }
59415939
59425940 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
......@@ -6189,8 +6187,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
61896187 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval);
61906188 case NodeTypeNullLiteral:
61916189 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval);
6192 case NodeTypeVarLiteral:
6193 return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval);
61946190 case NodeTypeIfErrorExpr:
61956191 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval);
61966192 case NodeTypeTestExpr:
......@@ -6328,14 +6324,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
63286324 Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);
63296325 irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
63306326 awaiter_handle_field_name);
6331 if (type_has_bits(return_type)) {
6332 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6333 coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);
6334 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
6335 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
6336 result_ptr_field_name);
6337 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr);
6338 }
6327 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6328 coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);
6329 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
6330 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name);
6331 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr);
63396332
63406333
63416334 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
......@@ -7515,11 +7508,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
75157508 return ImplicitCastMatchResultReportedError;
75167509 }
75177510
7518 // implicit conversion from anything to var
7519 if (expected_type->id == TypeTableEntryIdVar) {
7520 return ImplicitCastMatchResultYes;
7521 }
7522
75237511 // implicit conversion from non maybe type to maybe type
75247512 if (expected_type->id == TypeTableEntryIdMaybe &&
75257513 ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type, actual_type, value))
......@@ -9341,9 +9329,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
93419329 return ira->codegen->invalid_instruction;
93429330 }
93439331
9344 if (wanted_type->id == TypeTableEntryIdVar)
9345 return value;
9346
93479332 // explicit match or non-const to const
93489333 if (types_match_const_cast_only(ira, wanted_type, actual_type, source_node).id == ConstCastResultIdOk) {
93499334 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
......@@ -10311,9 +10296,6 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
1031110296 ir_add_error_node(ira, source_node,
1031210297 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
1031310298 return ira->codegen->builtin_types.entry_invalid;
10314
10315 case TypeTableEntryIdVar:
10316 zig_unreachable();
1031710299 }
1031810300
1031910301 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type);
......@@ -11106,7 +11088,6 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
1110611088 case TypeTableEntryIdInvalid:
1110711089 zig_unreachable();
1110811090 case TypeTableEntryIdUnreachable:
11109 case TypeTableEntryIdVar:
1111011091 return VarClassRequiredIllegal;
1111111092 case TypeTableEntryIdBool:
1111211093 case TypeTableEntryIdInt:
......@@ -11279,7 +11260,6 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
1127911260
1128011261 switch (target->value.type->id) {
1128111262 case TypeTableEntryIdInvalid:
11282 case TypeTableEntryIdVar:
1128311263 case TypeTableEntryIdUnreachable:
1128411264 zig_unreachable();
1128511265 case TypeTableEntryIdFn: {
......@@ -11332,7 +11312,6 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
1133211312 TypeTableEntry *type_value = target->value.data.x_type;
1133311313 switch (type_value->id) {
1133411314 case TypeTableEntryIdInvalid:
11335 case TypeTableEntryIdVar:
1133611315 zig_unreachable();
1133711316 case TypeTableEntryIdStruct:
1133811317 if (is_slice(type_value)) {
......@@ -11543,14 +11522,20 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
1154311522{
1154411523 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);
1154511524 assert(param_decl_node->type == NodeTypeParamDecl);
11546 AstNode *param_type_node = param_decl_node->data.param_decl.type;
11547 TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node);
11548 if (type_is_invalid(param_type))
11549 return false;
1155011525
11551 IrInstruction *casted_arg = ir_implicit_cast(ira, arg, param_type);
11552 if (type_is_invalid(casted_arg->value.type))
11553 return false;
11526 IrInstruction *casted_arg;
11527 if (param_decl_node->data.param_decl.var_token == nullptr) {
11528 AstNode *param_type_node = param_decl_node->data.param_decl.type;
11529 TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node);
11530 if (type_is_invalid(param_type))
11531 return false;
11532
11533 casted_arg = ir_implicit_cast(ira, arg, param_type);
11534 if (type_is_invalid(casted_arg->value.type))
11535 return false;
11536 } else {
11537 casted_arg = arg;
11538 }
1155411539
1155511540 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad);
1155611541 if (!arg_val)
......@@ -11579,19 +11564,18 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1157911564 arg_part_of_generic_id = true;
1158011565 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
1158111566 } else {
11582 AstNode *param_type_node = param_decl_node->data.param_decl.type;
11583 TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);
11584 if (type_is_invalid(param_type))
11585 return false;
11567 if (param_decl_node->data.param_decl.var_token == nullptr) {
11568 AstNode *param_type_node = param_decl_node->data.param_decl.type;
11569 TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);
11570 if (type_is_invalid(param_type))
11571 return false;
1158611572
11587 bool is_var_type = (param_type->id == TypeTableEntryIdVar);
11588 if (is_var_type) {
11589 arg_part_of_generic_id = true;
11590 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
11591 } else {
1159211573 casted_arg = ir_implicit_cast(ira, arg, param_type);
1159311574 if (type_is_invalid(casted_arg->value.type))
1159411575 return false;
11576 } else {
11577 arg_part_of_generic_id = true;
11578 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
1159511579 }
1159611580 }
1159711581
......@@ -12028,7 +12012,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1202812012 inst_fn_type_id.alignment = align_bytes;
1202912013 }
1203012014
12031 {
12015 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) {
1203212016 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
1203312017 TypeTableEntry *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
1203412018 if (type_is_invalid(specified_return_type))
......@@ -12304,7 +12288,6 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
1230412288 return ira->codegen->builtin_types.entry_invalid;
1230512289 switch (type_entry->id) {
1230612290 case TypeTableEntryIdInvalid:
12307 case TypeTableEntryIdVar:
1230812291 zig_unreachable();
1230912292 case TypeTableEntryIdMetaType:
1231012293 case TypeTableEntryIdVoid:
......@@ -13539,10 +13522,6 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
1353913522 switch (type_entry->id) {
1354013523 case TypeTableEntryIdInvalid:
1354113524 zig_unreachable(); // handled above
13542 case TypeTableEntryIdVar:
13543 ir_add_error_node(ira, expr_value->source_node,
13544 buf_sprintf("type '%s' not eligible for @typeOf", buf_ptr(&type_entry->name)));
13545 return ira->codegen->builtin_types.entry_invalid;
1354613525 case TypeTableEntryIdNumLitFloat:
1354713526 case TypeTableEntryIdNumLitInt:
1354813527 case TypeTableEntryIdUndefLit:
......@@ -13807,7 +13786,6 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1380713786 switch (child_type->id) {
1380813787 case TypeTableEntryIdInvalid: // handled above
1380913788 zig_unreachable();
13810 case TypeTableEntryIdVar:
1381113789 case TypeTableEntryIdUnreachable:
1381213790 case TypeTableEntryIdUndefLit:
1381313791 case TypeTableEntryIdNullLit:
......@@ -13916,7 +13894,6 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
1391613894 switch (child_type->id) {
1391713895 case TypeTableEntryIdInvalid: // handled above
1391813896 zig_unreachable();
13919 case TypeTableEntryIdVar:
1392013897 case TypeTableEntryIdUnreachable:
1392113898 case TypeTableEntryIdUndefLit:
1392213899 case TypeTableEntryIdNullLit:
......@@ -13968,7 +13945,6 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
1396813945 switch (type_entry->id) {
1396913946 case TypeTableEntryIdInvalid: // handled above
1397013947 zig_unreachable();
13971 case TypeTableEntryIdVar:
1397213948 case TypeTableEntryIdUnreachable:
1397313949 case TypeTableEntryIdUndefLit:
1397413950 case TypeTableEntryIdNullLit:
......@@ -14161,6 +14137,14 @@ static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source
1416114137 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name)));
1416214138 return ira->codegen->invalid_instruction;
1416314139 }
14140 if (!value->value.type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) {
14141 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum"));
14142 if (value->value.type->data.unionation.decl_node != nullptr) {
14143 add_error_note(ira->codegen, msg, value->value.type->data.unionation.decl_node,
14144 buf_sprintf("declared here"));
14145 }
14146 return ira->codegen->invalid_instruction;
14147 }
1416414148
1416514149 TypeTableEntry *tag_type = value->value.type->data.unionation.tag_type;
1416614150 assert(tag_type->id == TypeTableEntryIdEnum);
......@@ -14316,7 +14300,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1431614300
1431714301 switch (target_type->id) {
1431814302 case TypeTableEntryIdInvalid:
14319 case TypeTableEntryIdVar:
1432014303 zig_unreachable();
1432114304 case TypeTableEntryIdMetaType:
1432214305 case TypeTableEntryIdVoid:
......@@ -14911,7 +14894,6 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
1491114894 }
1491214895 case TypeTableEntryIdEnum:
1491314896 zig_panic("TODO min/max value for enum type");
14914 case TypeTableEntryIdVar:
1491514897 case TypeTableEntryIdMetaType:
1491614898 case TypeTableEntryIdUnreachable:
1491714899 case TypeTableEntryIdPointer:
......@@ -15821,9 +15803,13 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1582115803 TypeTableEntry *return_type;
1582215804
1582315805 if (array_type->id == TypeTableEntryIdArray) {
15806 uint32_t byte_alignment = ptr_type->data.pointer.alignment;
15807 if (array_type->data.array.len == 0 && byte_alignment == 0) {
15808 byte_alignment = get_abi_alignment(ira->codegen, array_type->data.array.child_type);
15809 }
1582415810 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,
1582515811 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
15826 ptr_type->data.pointer.alignment, 0, 0);
15812 byte_alignment, 0, 0);
1582715813 return_type = get_slice_type(ira->codegen, slice_ptr_type);
1582815814 } else if (array_type->id == TypeTableEntryIdPointer) {
1582915815 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
......@@ -16155,7 +16141,6 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
1615516141
1615616142 switch (type_entry->id) {
1615716143 case TypeTableEntryIdInvalid:
16158 case TypeTableEntryIdVar:
1615916144 zig_unreachable();
1616016145 case TypeTableEntryIdMetaType:
1616116146 case TypeTableEntryIdUnreachable:
......@@ -16457,21 +16442,23 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc
1645716442 zig_unreachable();
1645816443 }
1645916444 }
16460 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other;
16461 if (type_is_invalid(param_type_value->value.type))
16462 return ira->codegen->builtin_types.entry_invalid;
16463
1646416445 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
1646516446 param_info->is_noalias = param_node->data.param_decl.is_noalias;
16466 param_info->type = ir_resolve_type(ira, param_type_value);
16467 if (type_is_invalid(param_info->type))
16468 return ira->codegen->builtin_types.entry_invalid;
1646916447
16470 if (param_info->type->id == TypeTableEntryIdVar) {
16448 if (instruction->param_types[fn_type_id.next_param_index] == nullptr) {
16449 param_info->type = nullptr;
1647116450 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1647216451 out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id);
1647316452 return ira->codegen->builtin_types.entry_type;
16453 } else {
16454 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other;
16455 if (type_is_invalid(param_type_value->value.type))
16456 return ira->codegen->builtin_types.entry_invalid;
16457 param_info->type = ir_resolve_type(ira, param_type_value);
16458 if (type_is_invalid(param_info->type))
16459 return ira->codegen->builtin_types.entry_invalid;
1647416460 }
16461
1647516462 }
1647616463
1647716464 if (instruction->align_value != nullptr) {
......@@ -16816,6 +16803,11 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc
1681616803 return ira->codegen->builtin_types.entry_invalid;
1681716804 }
1681816805
16806 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) {
16807 ir_add_error(ira, &instruction->base, buf_sprintf("cast discards const qualifier"));
16808 return ira->codegen->builtin_types.entry_invalid;
16809 }
16810
1681916811 if (instr_is_comptime(ptr)) {
1682016812 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
1682116813 if (!val)
......@@ -16860,7 +16852,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1686016852 assert(val->special == ConstValSpecialStatic);
1686116853 switch (val->type->id) {
1686216854 case TypeTableEntryIdInvalid:
16863 case TypeTableEntryIdVar:
1686416855 case TypeTableEntryIdMetaType:
1686516856 case TypeTableEntryIdOpaque:
1686616857 case TypeTableEntryIdBoundFn:
......@@ -16928,7 +16919,6 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1692816919 assert(val->special == ConstValSpecialStatic);
1692916920 switch (val->type->id) {
1693016921 case TypeTableEntryIdInvalid:
16931 case TypeTableEntryIdVar:
1693216922 case TypeTableEntryIdMetaType:
1693316923 case TypeTableEntryIdOpaque:
1693416924 case TypeTableEntryIdBoundFn:
......@@ -17005,7 +16995,6 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
1700516995
1700616996 switch (src_type->id) {
1700716997 case TypeTableEntryIdInvalid:
17008 case TypeTableEntryIdVar:
1700916998 case TypeTableEntryIdMetaType:
1701016999 case TypeTableEntryIdOpaque:
1701117000 case TypeTableEntryIdBoundFn:
......@@ -17032,7 +17021,6 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
1703217021
1703317022 switch (dest_type->id) {
1703417023 case TypeTableEntryIdInvalid:
17035 case TypeTableEntryIdVar:
1703617024 case TypeTableEntryIdMetaType:
1703717025 case TypeTableEntryIdOpaque:
1703817026 case TypeTableEntryIdBoundFn:
src/parser.cpp+24-25
......@@ -263,21 +263,14 @@ static AstNode *ast_parse_error_set_expr(ParseContext *pc, size_t *token_index,
263263}
264264
265265/*
266TypeExpr = ErrorSetExpr | "var"
266TypeExpr = ErrorSetExpr
267267*/
268268static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
269 Token *token = &pc->tokens->at(*token_index);
270 if (token->id == TokenIdKeywordVar) {
271 AstNode *node = ast_create_node(pc, NodeTypeVarLiteral, token);
272 *token_index += 1;
273 return node;
274 } else {
275 return ast_parse_error_set_expr(pc, token_index, mandatory);
276 }
269 return ast_parse_error_set_expr(pc, token_index, mandatory);
277270}
278271
279272/*
280ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")
273ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "var" | "...")
281274*/
282275static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
283276 Token *token = &pc->tokens->at(*token_index);
......@@ -308,6 +301,9 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
308301 if (ellipsis_tok->id == TokenIdEllipsis3) {
309302 *token_index += 1;
310303 node->data.param_decl.is_var_args = true;
304 } else if (ellipsis_tok->id == TokenIdKeywordVar) {
305 *token_index += 1;
306 node->data.param_decl.var_token = ellipsis_tok;
311307 } else {
312308 node->data.param_decl.type = ast_parse_type_expr(pc, token_index, true);
313309 }
......@@ -2319,7 +2315,7 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool
23192315 return nullptr;
23202316}
23212317
2322static bool statement_terminates_without_semicolon(AstNode *node) {
2318bool statement_terminates_without_semicolon(AstNode *node) {
23232319 switch (node->type) {
23242320 case NodeTypeIfBoolExpr:
23252321 if (node->data.if_bool_expr.else_node)
......@@ -2421,7 +2417,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
24212417}
24222418
24232419/*
2424FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") TypeExpr
2420FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") (TypeExpr | "var")
24252421*/
24262422static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
24272423 Token *first_token = &pc->tokens->at(*token_index);
......@@ -2507,19 +2503,25 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
25072503 ast_eat_token(pc, token_index, TokenIdRParen);
25082504 next_token = &pc->tokens->at(*token_index);
25092505 }
2510 if (next_token->id == TokenIdKeywordError) {
2511 Token *maybe_lbrace_tok = &pc->tokens->at(*token_index + 1);
2512 if (maybe_lbrace_tok->id == TokenIdLBrace) {
2513 *token_index += 1;
2514 node->data.fn_proto.return_type = ast_create_node(pc, NodeTypeErrorType, next_token);
2515 return node;
2516 }
2517 } else if (next_token->id == TokenIdBang) {
2506 if (next_token->id == TokenIdKeywordVar) {
2507 node->data.fn_proto.return_var_token = next_token;
25182508 *token_index += 1;
2519 node->data.fn_proto.auto_err_set = true;
25202509 next_token = &pc->tokens->at(*token_index);
2510 } else {
2511 if (next_token->id == TokenIdKeywordError) {
2512 Token *maybe_lbrace_tok = &pc->tokens->at(*token_index + 1);
2513 if (maybe_lbrace_tok->id == TokenIdLBrace) {
2514 *token_index += 1;
2515 node->data.fn_proto.return_type = ast_create_node(pc, NodeTypeErrorType, next_token);
2516 return node;
2517 }
2518 } else if (next_token->id == TokenIdBang) {
2519 *token_index += 1;
2520 node->data.fn_proto.auto_err_set = true;
2521 next_token = &pc->tokens->at(*token_index);
2522 }
2523 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
25212524 }
2522 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
25232525
25242526 return node;
25252527}
......@@ -3069,9 +3071,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
30693071 case NodeTypeErrorType:
30703072 // none
30713073 break;
3072 case NodeTypeVarLiteral:
3073 // none
3074 break;
30753074 case NodeTypeAddrOfExpr:
30763075 visit_field(&node->data.addr_of_expr.align_expr, visit, context);
30773076 visit_field(&node->data.addr_of_expr.op_expr, visit, context);
src/parser.hpp+2
......@@ -23,4 +23,6 @@ void ast_print(AstNode *node, int indent);
2323
2424void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);
2525
26bool statement_terminates_without_semicolon(AstNode *node);
27
2628#endif
src/target.cpp+1-1
......@@ -787,7 +787,7 @@ static FloatAbi get_float_abi(ZigTarget *target) {
787787 {
788788 return FloatAbiHard;
789789 } else {
790 zig_panic("TODO: user needs to input if they want hard or soft floating point");
790 return FloatAbiSoft;
791791 }
792792}
793793
src/translate_c.cpp+482-111
......@@ -104,6 +104,7 @@ static TransScopeRoot *trans_scope_root_create(Context *c);
104104static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
105105static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
106106static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);
107static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
107108
108109static TransScopeBlock *trans_scope_block_find(TransScope *scope);
109110
......@@ -118,7 +119,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
118119static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node);
119120static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
120121static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
121
122static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
122123
123124ATTRIBUTE_PRINTF(3, 4)
124125static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
......@@ -466,6 +467,14 @@ static QualType get_expr_qual_type(Context *c, const Expr *expr) {
466467 return expr->getType();
467468}
468469
470static QualType get_expr_qual_type_before_implicit_cast(Context *c, const Expr *expr) {
471 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
472 const ImplicitCastExpr *cast_expr = static_cast<const ImplicitCastExpr *>(expr);
473 return get_expr_qual_type(c, cast_expr->getSubExpr());
474 }
475 return expr->getType();
476}
477
469478static AstNode *get_expr_type(Context *c, const Expr *expr) {
470479 return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());
471480}
......@@ -499,15 +508,31 @@ static bool qual_type_is_ptr(QualType qt) {
499508 return ty->getTypeClass() == Type::Pointer;
500509}
501510
502static bool qual_type_is_fn_ptr(Context *c, QualType qt) {
511static const FunctionProtoType *qual_type_get_fn_proto(QualType qt, bool *is_ptr) {
503512 const Type *ty = qual_type_canon(qt);
504 if (ty->getTypeClass() != Type::Pointer) {
505 return false;
513 *is_ptr = false;
514
515 if (ty->getTypeClass() == Type::Pointer) {
516 *is_ptr = true;
517 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
518 QualType child_qt = pointer_ty->getPointeeType();
519 ty = child_qt.getTypePtr();
520 }
521
522 if (ty->getTypeClass() == Type::FunctionProto) {
523 return static_cast<const FunctionProtoType*>(ty);
506524 }
507 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
508 QualType child_qt = pointer_ty->getPointeeType();
509 const Type *child_ty = child_qt.getTypePtr();
510 return child_ty->getTypeClass() == Type::FunctionProto;
525
526 return nullptr;
527}
528
529static bool qual_type_is_fn_ptr(QualType qt) {
530 bool is_ptr;
531 if (qual_type_get_fn_proto(qt, &is_ptr)) {
532 return is_ptr;
533 }
534
535 return false;
511536}
512537
513538static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {
......@@ -632,7 +657,7 @@ static bool c_is_signed_integer(Context *c, QualType qt) {
632657 case BuiltinType::Int128:
633658 case BuiltinType::WChar_S:
634659 return true;
635 default:
660 default:
636661 return false;
637662 }
638663}
......@@ -653,7 +678,7 @@ static bool c_is_unsigned_integer(Context *c, QualType qt) {
653678 case BuiltinType::UInt128:
654679 case BuiltinType::WChar_U:
655680 return true;
656 default:
681 default:
657682 return false;
658683 }
659684}
......@@ -678,7 +703,7 @@ static bool c_is_float(Context *c, QualType qt) {
678703 case BuiltinType::Float128:
679704 case BuiltinType::LongDouble:
680705 return true;
681 default:
706 default:
682707 return false;
683708 }
684709}
......@@ -1138,6 +1163,22 @@ static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, Bi
11381163 return node;
11391164}
11401165
1166static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, Expr *lhs, BinOpType bin_op, Expr *rhs) {
1167 assert(bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeBoolOr);
1168 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1169 node->data.bin_op_expr.bin_op = bin_op;
1170
1171 node->data.bin_op_expr.op1 = trans_bool_expr(c, ResultUsedYes, scope, lhs, TransRValue);
1172 if (node->data.bin_op_expr.op1 == nullptr)
1173 return nullptr;
1174
1175 node->data.bin_op_expr.op2 = trans_bool_expr(c, ResultUsedYes, scope, rhs, TransRValue);
1176 if (node->data.bin_op_expr.op2 == nullptr)
1177 return nullptr;
1178
1179 return node;
1180}
1181
11411182static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) {
11421183 if (result_used == ResultUsedNo) {
11431184 // common case
......@@ -1282,10 +1323,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
12821323 case BO_Or:
12831324 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
12841325 case BO_LAnd:
1285 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
1326 return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
12861327 case BO_LOr:
1287 // TODO: int vs bool
1288 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1328 return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
12891329 case BO_Assign:
12901330 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());
12911331 case BO_Comma:
......@@ -1395,7 +1435,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
13951435 if (result_used == ResultUsedYes) {
13961436 // break :x *_ref
13971437 child_scope->node->data.block.statements.append(
1398 trans_create_node_break(c, label_name,
1438 trans_create_node_break(c, label_name,
13991439 trans_create_node_prefix_op(c, PrefixOpDereference,
14001440 trans_create_node_symbol(c, tmp_var_name))));
14011441 }
......@@ -1879,7 +1919,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
18791919 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
18801920 if (value_node == nullptr)
18811921 return nullptr;
1882 bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType());
1922 bool is_fn_ptr = qual_type_is_fn_ptr(stmt->getSubExpr()->getType());
18831923 if (is_fn_ptr)
18841924 return value_node;
18851925 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);
......@@ -1922,11 +1962,18 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
19221962 AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
19231963 if (sub_node == nullptr)
19241964 return nullptr;
1965
19251966 return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node);
19261967 }
19271968 case UO_LNot:
1928 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_LNot");
1929 return nullptr;
1969 {
1970 Expr *op_expr = stmt->getSubExpr();
1971 AstNode *sub_node = trans_bool_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
1972 if (sub_node == nullptr)
1973 return nullptr;
1974
1975 return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node);
1976 }
19301977 case UO_Real:
19311978 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Real");
19321979 return nullptr;
......@@ -2206,16 +2253,246 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt
22062253 return ErrorNone;
22072254}
22082255
2256static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type) {
2257 AstNode *tag_type = trans_create_node_builtin_fn_call_str(c, "TagType");
2258 tag_type->data.fn_call_expr.params.append(enum_type);
2259
2260 // @TagType(Enum)(0)
2261 AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);
2262 AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero);
2263
2264 // @bitCast(Enum, @TagType(Enum)(0))
2265 AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");
2266 bitcast->data.fn_call_expr.params.append(enum_type);
2267 bitcast->data.fn_call_expr.params.append(casted_zero);
2268
2269 return trans_create_node_bin_op(c, expr, BinOpTypeCmpNotEq, bitcast);
2270}
2271
2272static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval) {
2273 AstNode *res = trans_expr(c, result_used, scope, expr, lrval);
2274 if (res == nullptr)
2275 return nullptr;
2276
2277 switch (res->type) {
2278 case NodeTypeBinOpExpr:
2279 switch (res->data.bin_op_expr.bin_op) {
2280 case BinOpTypeBoolOr:
2281 case BinOpTypeBoolAnd:
2282 case BinOpTypeCmpEq:
2283 case BinOpTypeCmpNotEq:
2284 case BinOpTypeCmpLessThan:
2285 case BinOpTypeCmpGreaterThan:
2286 case BinOpTypeCmpLessOrEq:
2287 case BinOpTypeCmpGreaterOrEq:
2288 return res;
2289 default:
2290 break;
2291 }
2292
2293 case NodeTypePrefixOpExpr:
2294 switch (res->data.prefix_op_expr.prefix_op) {
2295 case PrefixOpBoolNot:
2296 return res;
2297 default:
2298 break;
2299 }
2300
2301 case NodeTypeBoolLiteral:
2302 return res;
2303
2304 default:
2305 break;
2306 }
2307
2308
2309 const Type *ty = get_expr_qual_type_before_implicit_cast(c, expr).getTypePtr();
2310 auto classs = ty->getTypeClass();
2311 switch (classs) {
2312 case Type::Builtin:
2313 {
2314 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
2315 switch (builtin_ty->getKind()) {
2316 case BuiltinType::Bool:
2317 case BuiltinType::Char_U:
2318 case BuiltinType::UChar:
2319 case BuiltinType::Char_S:
2320 case BuiltinType::SChar:
2321 case BuiltinType::UShort:
2322 case BuiltinType::UInt:
2323 case BuiltinType::ULong:
2324 case BuiltinType::ULongLong:
2325 case BuiltinType::Short:
2326 case BuiltinType::Int:
2327 case BuiltinType::Long:
2328 case BuiltinType::LongLong:
2329 case BuiltinType::UInt128:
2330 case BuiltinType::Int128:
2331 case BuiltinType::Float:
2332 case BuiltinType::Double:
2333 case BuiltinType::Float128:
2334 case BuiltinType::LongDouble:
2335 case BuiltinType::WChar_U:
2336 case BuiltinType::Char16:
2337 case BuiltinType::Char32:
2338 case BuiltinType::WChar_S:
2339 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
2340 case BuiltinType::NullPtr:
2341 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
2342
2343 case BuiltinType::Void:
2344 case BuiltinType::Half:
2345 case BuiltinType::ObjCId:
2346 case BuiltinType::ObjCClass:
2347 case BuiltinType::ObjCSel:
2348 case BuiltinType::OMPArraySection:
2349 case BuiltinType::Dependent:
2350 case BuiltinType::Overload:
2351 case BuiltinType::BoundMember:
2352 case BuiltinType::PseudoObject:
2353 case BuiltinType::UnknownAny:
2354 case BuiltinType::BuiltinFn:
2355 case BuiltinType::ARCUnbridgedCast:
2356 case BuiltinType::OCLImage1dRO:
2357 case BuiltinType::OCLImage1dArrayRO:
2358 case BuiltinType::OCLImage1dBufferRO:
2359 case BuiltinType::OCLImage2dRO:
2360 case BuiltinType::OCLImage2dArrayRO:
2361 case BuiltinType::OCLImage2dDepthRO:
2362 case BuiltinType::OCLImage2dArrayDepthRO:
2363 case BuiltinType::OCLImage2dMSAARO:
2364 case BuiltinType::OCLImage2dArrayMSAARO:
2365 case BuiltinType::OCLImage2dMSAADepthRO:
2366 case BuiltinType::OCLImage2dArrayMSAADepthRO:
2367 case BuiltinType::OCLImage3dRO:
2368 case BuiltinType::OCLImage1dWO:
2369 case BuiltinType::OCLImage1dArrayWO:
2370 case BuiltinType::OCLImage1dBufferWO:
2371 case BuiltinType::OCLImage2dWO:
2372 case BuiltinType::OCLImage2dArrayWO:
2373 case BuiltinType::OCLImage2dDepthWO:
2374 case BuiltinType::OCLImage2dArrayDepthWO:
2375 case BuiltinType::OCLImage2dMSAAWO:
2376 case BuiltinType::OCLImage2dArrayMSAAWO:
2377 case BuiltinType::OCLImage2dMSAADepthWO:
2378 case BuiltinType::OCLImage2dArrayMSAADepthWO:
2379 case BuiltinType::OCLImage3dWO:
2380 case BuiltinType::OCLImage1dRW:
2381 case BuiltinType::OCLImage1dArrayRW:
2382 case BuiltinType::OCLImage1dBufferRW:
2383 case BuiltinType::OCLImage2dRW:
2384 case BuiltinType::OCLImage2dArrayRW:
2385 case BuiltinType::OCLImage2dDepthRW:
2386 case BuiltinType::OCLImage2dArrayDepthRW:
2387 case BuiltinType::OCLImage2dMSAARW:
2388 case BuiltinType::OCLImage2dArrayMSAARW:
2389 case BuiltinType::OCLImage2dMSAADepthRW:
2390 case BuiltinType::OCLImage2dArrayMSAADepthRW:
2391 case BuiltinType::OCLImage3dRW:
2392 case BuiltinType::OCLSampler:
2393 case BuiltinType::OCLEvent:
2394 case BuiltinType::OCLClkEvent:
2395 case BuiltinType::OCLQueue:
2396 case BuiltinType::OCLReserveID:
2397 return res;
2398 }
2399 break;
2400 }
2401 case Type::Pointer:
2402 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
2403
2404 case Type::Typedef:
2405 {
2406 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
2407 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
2408 auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl());
2409 if (existing_entry) {
2410 return existing_entry->value;
2411 }
2412
2413 return res;
2414 }
2415
2416 case Type::Enum:
2417 {
2418 const EnumType *enum_ty = static_cast<const EnumType*>(ty);
2419 AstNode *enum_type = resolve_enum_decl(c, enum_ty->getDecl());
2420 return to_enum_zero_cmp(c, res, enum_type);
2421 }
2422
2423 case Type::Elaborated:
2424 {
2425 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
2426 switch (elaborated_ty->getKeyword()) {
2427 case ETK_Enum: {
2428 AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), expr->getLocStart());
2429 return to_enum_zero_cmp(c, res, enum_type);
2430 }
2431 case ETK_Struct:
2432 case ETK_Union:
2433 case ETK_Interface:
2434 case ETK_Class:
2435 case ETK_Typename:
2436 case ETK_None:
2437 return res;
2438 }
2439 }
2440
2441 case Type::FunctionProto:
2442 case Type::Record:
2443 case Type::ConstantArray:
2444 case Type::Paren:
2445 case Type::Decayed:
2446 case Type::Attributed:
2447 case Type::IncompleteArray:
2448 case Type::BlockPointer:
2449 case Type::LValueReference:
2450 case Type::RValueReference:
2451 case Type::MemberPointer:
2452 case Type::VariableArray:
2453 case Type::DependentSizedArray:
2454 case Type::DependentSizedExtVector:
2455 case Type::Vector:
2456 case Type::ExtVector:
2457 case Type::FunctionNoProto:
2458 case Type::UnresolvedUsing:
2459 case Type::Adjusted:
2460 case Type::TypeOfExpr:
2461 case Type::TypeOf:
2462 case Type::Decltype:
2463 case Type::UnaryTransform:
2464 case Type::TemplateTypeParm:
2465 case Type::SubstTemplateTypeParm:
2466 case Type::SubstTemplateTypeParmPack:
2467 case Type::TemplateSpecialization:
2468 case Type::Auto:
2469 case Type::InjectedClassName:
2470 case Type::DependentName:
2471 case Type::DependentTemplateSpecialization:
2472 case Type::PackExpansion:
2473 case Type::ObjCObject:
2474 case Type::ObjCInterface:
2475 case Type::Complex:
2476 case Type::ObjCObjectPointer:
2477 case Type::Atomic:
2478 case Type::Pipe:
2479 case Type::ObjCTypeParam:
2480 case Type::DeducedTemplateSpecialization:
2481 return res;
2482 }
2483 zig_unreachable();
2484}
2485
22092486static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
22102487 TransScopeWhile *while_scope = trans_scope_while_create(c, scope);
22112488
2212 while_scope->node->data.while_expr.condition = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2489 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
22132490 if (while_scope->node->data.while_expr.condition == nullptr)
22142491 return nullptr;
22152492
22162493 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(),
22172494 &while_scope->node->data.while_expr.body);
2218 if (body_scope == nullptr)
2495 if (body_scope == nullptr)
22192496 return nullptr;
22202497
22212498 return while_scope->node;
......@@ -2236,87 +2513,11 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *
22362513 return nullptr;
22372514 }
22382515
2239 AstNode *condition_node = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2240 if (condition_node == nullptr)
2516 if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2517 if (if_node->data.if_bool_expr.condition == nullptr)
22412518 return nullptr;
22422519
2243 switch (condition_node->type) {
2244 case NodeTypeBinOpExpr:
2245 switch (condition_node->data.bin_op_expr.bin_op) {
2246 case BinOpTypeBoolOr:
2247 case BinOpTypeBoolAnd:
2248 case BinOpTypeCmpEq:
2249 case BinOpTypeCmpNotEq:
2250 case BinOpTypeCmpLessThan:
2251 case BinOpTypeCmpGreaterThan:
2252 case BinOpTypeCmpLessOrEq:
2253 case BinOpTypeCmpGreaterOrEq:
2254 if_node->data.if_bool_expr.condition = condition_node;
2255 return if_node;
2256 default:
2257 goto convert_to_bitcast;
2258 }
2259
2260 case NodeTypePrefixOpExpr:
2261 switch (condition_node->data.prefix_op_expr.prefix_op) {
2262 case PrefixOpBoolNot:
2263 if_node->data.if_bool_expr.condition = condition_node;
2264 return if_node;
2265 default:
2266 goto convert_to_bitcast;
2267 }
2268
2269 case NodeTypeBoolLiteral:
2270 if_node->data.if_bool_expr.condition = condition_node;
2271 return if_node;
2272
2273 default: {
2274 // In Zig, float, int and pointer does not work in if statements.
2275 // To make it work, we bitcast any value we get to an int of the right size
2276 // and comp it to 0
2277 // TODO: This doesn't work for pointers, as they become nullable on
2278 // translate
2279 // c: if (cond) { }
2280 // zig: {
2281 // zig: const _tmp = cond;
2282 // zig: if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) { }
2283 // zig: }
2284 convert_to_bitcast:
2285 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
2286
2287 // const _tmp = cond;
2288 // TODO: avoid name collisions with generated variable names
2289 Buf* tmp_var_name = buf_create_from_str("_tmp");
2290 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, condition_node);
2291 child_scope->node->data.block.statements.append(tmp_var_decl);
2292
2293 // @sizeOf(@typeOf(_tmp)) * 8
2294 AstNode *typeof_tmp = trans_create_node_builtin_fn_call_str(c, "typeOf");
2295 typeof_tmp->data.fn_call_expr.params.append(trans_create_node_symbol(c, tmp_var_name));
2296 AstNode *sizeof_tmp = trans_create_node_builtin_fn_call_str(c, "sizeOf");
2297 sizeof_tmp->data.fn_call_expr.params.append(typeof_tmp);
2298 AstNode *sizeof_tmp_in_bits = trans_create_node_bin_op(
2299 c, sizeof_tmp, BinOpTypeMult,
2300 trans_create_node_unsigned_negative(c, 8, false));
2301
2302 // @IntType(false, @sizeOf(@typeOf(_tmp)) * 8)
2303 AstNode *int_type = trans_create_node_builtin_fn_call_str(c, "IntType");
2304 int_type->data.fn_call_expr.params.append(trans_create_node_bool(c, false));
2305 int_type->data.fn_call_expr.params.append(sizeof_tmp_in_bits);
2306
2307 // @bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp)
2308 AstNode *bit_cast = trans_create_node_builtin_fn_call_str(c, "bitCast");
2309 bit_cast->data.fn_call_expr.params.append(int_type);
2310 bit_cast->data.fn_call_expr.params.append(trans_create_node_symbol(c, tmp_var_name));
2311
2312 // if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) { }
2313 AstNode *not_eql_zero = trans_create_node_bin_op(c, bit_cast, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
2314 if_node->data.if_bool_expr.condition = not_eql_zero;
2315 child_scope->node->data.block.statements.append(if_node);
2316
2317 return child_scope->node;
2318 }
2319 }
2520 return if_node;
23202521}
23212522
23222523static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const CallExpr *stmt) {
......@@ -2326,8 +2527,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
23262527 if (callee_raw_node == nullptr)
23272528 return nullptr;
23282529
2530 bool is_ptr = false;
2531 const FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
23292532 AstNode *callee_node = nullptr;
2330 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {
2533 if (is_ptr && fn_ty) {
23312534 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
23322535 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());
23332536 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
......@@ -2359,6 +2562,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
23592562 node->data.fn_call_expr.params.append(arg_node);
23602563 }
23612564
2565 if (result_used == ResultUsedNo && fn_ty && !qual_type_canon(fn_ty->getReturnType())->isVoidType()) {
2566 node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node);
2567 }
2568
23622569 return node;
23632570}
23642571
......@@ -2501,10 +2708,18 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
25012708 if (cond_stmt == nullptr) {
25022709 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
25032710 } else {
2504 TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt,
2505 &while_scope->node->data.while_expr.condition);
2506 if (end_cond_scope == nullptr)
2507 return nullptr;
2711 if (Expr::classof(cond_stmt)) {
2712 const Expr *cond_expr = static_cast<const Expr*>(cond_stmt);
2713 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope, cond_expr, TransRValue);
2714
2715 if (while_scope->node->data.while_expr.condition == nullptr)
2716 return nullptr;
2717 } else {
2718 TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt,
2719 &while_scope->node->data.while_expr.condition);
2720 if (end_cond_scope == nullptr)
2721 return nullptr;
2722 }
25082723 }
25092724
25102725 const Stmt *inc_stmt = stmt->getInc();
......@@ -2525,6 +2740,155 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
25252740 return loop_block_node;
25262741}
25272742
2743static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const SwitchStmt *stmt) {
2744 TransScopeBlock *block_scope = trans_scope_block_create(c, parent_scope);
2745
2746 TransScopeSwitch *switch_scope;
2747
2748 const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
2749 if (var_decl_stmt == nullptr) {
2750 switch_scope = trans_scope_switch_create(c, &block_scope->base);
2751 } else {
2752 AstNode *vars_node;
2753 TransScope *var_scope = trans_stmt(c, &block_scope->base, var_decl_stmt, &vars_node);
2754 if (var_scope == nullptr)
2755 return nullptr;
2756 if (vars_node != nullptr)
2757 block_scope->node->data.block.statements.append(vars_node);
2758 switch_scope = trans_scope_switch_create(c, var_scope);
2759 }
2760 block_scope->node->data.block.statements.append(switch_scope->switch_node);
2761
2762 // TODO avoid name collisions
2763 Buf *end_label_name = buf_create_from_str("__switch");
2764 switch_scope->end_label_name = end_label_name;
2765 block_scope->node->data.block.name = end_label_name;
2766
2767 const Expr *cond_expr = stmt->getCond();
2768 assert(cond_expr != nullptr);
2769
2770 AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue);
2771 if (expr_node == nullptr)
2772 return nullptr;
2773 switch_scope->switch_node->data.switch_expr.expr = expr_node;
2774
2775 AstNode *body_node;
2776 const Stmt *body_stmt = stmt->getBody();
2777 if (body_stmt->getStmtClass() == Stmt::CompoundStmtClass) {
2778 if (trans_compound_stmt_inline(c, &switch_scope->base, (const CompoundStmt *)body_stmt,
2779 block_scope->node, nullptr))
2780 {
2781 return nullptr;
2782 }
2783 } else {
2784 TransScope *body_scope = trans_stmt(c, &switch_scope->base, body_stmt, &body_node);
2785 if (body_scope == nullptr)
2786 return nullptr;
2787 if (body_node != nullptr)
2788 block_scope->node->data.block.statements.append(body_node);
2789 }
2790
2791 if (!switch_scope->found_default && !stmt->isAllEnumCasesCovered()) {
2792 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2793 prong_node->data.switch_prong.expr = trans_create_node_break(c, end_label_name, nullptr);
2794 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2795 }
2796
2797 return block_scope->node;
2798}
2799
2800static TransScopeSwitch *trans_scope_switch_find(TransScope *scope) {
2801 while (scope != nullptr) {
2802 if (scope->id == TransScopeIdSwitch) {
2803 return (TransScopeSwitch *)scope;
2804 }
2805 scope = scope->parent;
2806 }
2807 return nullptr;
2808}
2809
2810static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStmt *stmt, AstNode **out_node,
2811 TransScope **out_scope) {
2812 *out_node = nullptr;
2813
2814 if (stmt->getRHS() != nullptr) {
2815 emit_warning(c, stmt->getLocStart(), "TODO support GNU switch case a ... b extension");
2816 return ErrorUnexpected;
2817 }
2818
2819 TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
2820 assert(switch_scope != nullptr);
2821
2822 Buf *label_name = buf_sprintf("__case_%" PRIu32, switch_scope->case_index);
2823 switch_scope->case_index += 1;
2824
2825 {
2826 // Add the prong
2827 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2828 AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, stmt->getLHS(), TransRValue);
2829 if (item_node == nullptr)
2830 return ErrorUnexpected;
2831 prong_node->data.switch_prong.items.append(item_node);
2832 prong_node->data.switch_prong.expr = trans_create_node_break(c, label_name, nullptr);
2833 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2834 }
2835
2836 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
2837
2838 AstNode *case_block = trans_create_node(c, NodeTypeBlock);
2839 case_block->data.block.name = label_name;
2840 case_block->data.block.statements = scope_block->node->data.block.statements;
2841 scope_block->node->data.block.statements = {0};
2842 scope_block->node->data.block.statements.append(case_block);
2843
2844 AstNode *sub_stmt_node;
2845 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
2846 if (new_scope == nullptr)
2847 return ErrorUnexpected;
2848 if (sub_stmt_node != nullptr)
2849 scope_block->node->data.block.statements.append(sub_stmt_node);
2850
2851 *out_scope = new_scope;
2852 return ErrorNone;
2853}
2854
2855static int trans_switch_default(Context *c, TransScope *parent_scope, const DefaultStmt *stmt, AstNode **out_node,
2856 TransScope **out_scope)
2857{
2858 *out_node = nullptr;
2859
2860 TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
2861 assert(switch_scope != nullptr);
2862
2863 Buf *label_name = buf_sprintf("__default");
2864
2865 {
2866 // Add the prong
2867 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2868 prong_node->data.switch_prong.expr = trans_create_node_break(c, label_name, nullptr);
2869 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2870 switch_scope->found_default = true;
2871 }
2872
2873 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
2874
2875 AstNode *case_block = trans_create_node(c, NodeTypeBlock);
2876 case_block->data.block.name = label_name;
2877 case_block->data.block.statements = scope_block->node->data.block.statements;
2878 scope_block->node->data.block.statements = {0};
2879 scope_block->node->data.block.statements.append(case_block);
2880
2881 AstNode *sub_stmt_node;
2882 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
2883 if (new_scope == nullptr)
2884 return ErrorUnexpected;
2885 if (sub_stmt_node != nullptr)
2886 scope_block->node->data.block.statements.append(sub_stmt_node);
2887
2888 *out_scope = new_scope;
2889 return ErrorNone;
2890}
2891
25282892static AstNode *trans_string_literal(Context *c, TransScope *scope, const StringLiteral *stmt) {
25292893 switch (stmt->getKind()) {
25302894 case StringLiteral::Ascii:
......@@ -2549,7 +2913,8 @@ static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt
25492913 if (cur_scope->id == TransScopeIdWhile) {
25502914 return trans_create_node(c, NodeTypeBreak);
25512915 } else if (cur_scope->id == TransScopeIdSwitch) {
2552 zig_panic("TODO");
2916 TransScopeSwitch *switch_scope = (TransScopeSwitch *)cur_scope;
2917 return trans_create_node_break(c, switch_scope->end_label_name, nullptr);
25532918 }
25542919 cur_scope = cur_scope->parent;
25552920 }
......@@ -2649,14 +3014,12 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
26493014 return wrap_stmt(out_node, out_child_scope, scope,
26503015 trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue));
26513016 case Stmt::SwitchStmtClass:
2652 emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");
2653 return ErrorUnexpected;
3017 return wrap_stmt(out_node, out_child_scope, scope,
3018 trans_switch_stmt(c, scope, (const SwitchStmt *)stmt));
26543019 case Stmt::CaseStmtClass:
2655 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
2656 return ErrorUnexpected;
3020 return trans_switch_case(c, scope, (const CaseStmt *)stmt, out_node, out_child_scope);
26573021 case Stmt::DefaultStmtClass:
2658 emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");
2659 return ErrorUnexpected;
3022 return trans_switch_default(c, scope, (const DefaultStmt *)stmt, out_node, out_child_scope);
26603023 case Stmt::NoStmtClass:
26613024 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
26623025 return ErrorUnexpected;
......@@ -3826,6 +4189,14 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop
38264189 return result;
38274190}
38284191
4192static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) {
4193 TransScopeSwitch *result = allocate<TransScopeSwitch>(1);
4194 result->base.id = TransScopeIdSwitch;
4195 result->base.parent = parent_scope;
4196 result->switch_node = trans_create_node(c, NodeTypeSwitchExpr);
4197 return result;
4198}
4199
38294200static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
38304201 while (scope != nullptr) {
38314202 if (scope->id == TransScopeIdBlock) {
std/buf_map.zig+1-3
......@@ -62,9 +62,7 @@ pub const BufMap = struct {
6262 }
6363
6464 fn free(self: &BufMap, value: []const u8) void {
65 // remove the const
66 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
67 self.hash_map.allocator.free(mut_value);
65 self.hash_map.allocator.free(value);
6866 }
6967
7068 fn copy(self: &BufMap, value: []const u8) ![]const u8 {
std/buf_set.zig+1-3
......@@ -50,9 +50,7 @@ pub const BufSet = struct {
5050 }
5151
5252 fn free(self: &BufSet, value: []const u8) void {
53 // remove the const
54 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
55 self.hash_map.allocator.free(mut_value);
53 self.hash_map.allocator.free(value);
5654 }
5755
5856 fn copy(self: &BufSet, value: []const u8) ![]const u8 {
std/os/index.zig+1-1
......@@ -1634,7 +1634,7 @@ pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {
16341634 for (args_alloc) |arg| {
16351635 total_bytes += @sizeOf([]u8) + arg.len;
16361636 }
1637 const unaligned_allocated_buf = @ptrCast(&u8, args_alloc.ptr)[0..total_bytes];
1637 const unaligned_allocated_buf = @ptrCast(&const u8, args_alloc.ptr)[0..total_bytes];
16381638 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);
16391639 return allocator.free(aligned_allocated_buf);
16401640}
std/special/compiler_rt/udivmod.zig+2-2
......@@ -11,8 +11,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
1111 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
1212 const Log2SingleInt = @import("../../math/index.zig").Log2Int(SingleInt);
1313
14 const n = *@ptrCast(&[2]SingleInt, &a); // TODO issue #421
15 const d = *@ptrCast(&[2]SingleInt, &b); // TODO issue #421
14 const n = *@ptrCast(&const [2]SingleInt, &a); // TODO issue #421
15 const d = *@ptrCast(&const [2]SingleInt, &b); // TODO issue #421
1616 var q: [2]SingleInt = undefined;
1717 var r: [2]SingleInt = undefined;
1818 var sr: c_uint = undefined;
std/unicode.zig+14-6
......@@ -96,7 +96,15 @@ pub fn utf8ValidateSlice(s: []const u8) bool {
9696 return true;
9797}
9898
99const Utf8View = struct {
99/// Utf8View iterates the code points of a utf-8 encoded string.
100///
101/// ```
102/// var utf8 = (try std.unicode.Utf8View.init("hi there")).iterator();
103/// while (utf8.nextCodepointSlice()) |codepoint| {
104/// std.debug.warn("got codepoint {}\n", codepoint);
105/// }
106/// ```
107pub const Utf8View = struct {
100108 bytes: []const u8,
101109
102110 pub fn init(s: []const u8) !Utf8View {
......@@ -124,7 +132,7 @@ const Utf8View = struct {
124132 }
125133 }
126134
127 pub fn Iterator(s: &const Utf8View) Utf8Iterator {
135 pub fn iterator(s: &const Utf8View) Utf8Iterator {
128136 return Utf8Iterator {
129137 .bytes = s.bytes,
130138 .i = 0,
......@@ -165,13 +173,13 @@ const Utf8Iterator = struct {
165173test "utf8 iterator on ascii" {
166174 const s = Utf8View.initComptime("abc");
167175
168 var it1 = s.Iterator();
176 var it1 = s.iterator();
169177 debug.assert(std.mem.eql(u8, "a", ??it1.nextCodepointSlice()));
170178 debug.assert(std.mem.eql(u8, "b", ??it1.nextCodepointSlice()));
171179 debug.assert(std.mem.eql(u8, "c", ??it1.nextCodepointSlice()));
172180 debug.assert(it1.nextCodepointSlice() == null);
173181
174 var it2 = s.Iterator();
182 var it2 = s.iterator();
175183 debug.assert(??it2.nextCodepoint() == 'a');
176184 debug.assert(??it2.nextCodepoint() == 'b');
177185 debug.assert(??it2.nextCodepoint() == 'c');
......@@ -189,13 +197,13 @@ test "utf8 view bad" {
189197test "utf8 view ok" {
190198 const s = Utf8View.initComptime("東京市");
191199
192 var it1 = s.Iterator();
200 var it1 = s.iterator();
193201 debug.assert(std.mem.eql(u8, "東", ??it1.nextCodepointSlice()));
194202 debug.assert(std.mem.eql(u8, "京", ??it1.nextCodepointSlice()));
195203 debug.assert(std.mem.eql(u8, "市", ??it1.nextCodepointSlice()));
196204 debug.assert(it1.nextCodepointSlice() == null);
197205
198 var it2 = s.Iterator();
206 var it2 = s.iterator();
199207 debug.assert(??it2.nextCodepoint() == 0x6771);
200208 debug.assert(??it2.nextCodepoint() == 0x4eac);
201209 debug.assert(??it2.nextCodepoint() == 0x5e02);
test/cases/cast.zig+1-1
......@@ -16,7 +16,7 @@ test "integer literal to pointer cast" {
1616test "pointer reinterpret const float to int" {
1717 const float: f64 = 5.99999999999994648725e-01;
1818 const float_ptr = &float;
19 const int_ptr = @ptrCast(&i32, float_ptr);
19 const int_ptr = @ptrCast(&const i32, float_ptr);
2020 const int_val = *int_ptr;
2121 assert(int_val == 858993411);
2222}
test/cases/misc.zig+11-1
......@@ -261,7 +261,7 @@ test "generic malloc free" {
261261 const a = memAlloc(u8, 10) catch unreachable;
262262 memFree(u8, a);
263263}
264const some_mem : [100]u8 = undefined;
264var some_mem : [100]u8 = undefined;
265265fn memAlloc(comptime T: type, n: usize) error![]T {
266266 return @ptrCast(&T, &some_mem[0])[0..n];
267267}
......@@ -650,3 +650,13 @@ test "packed struct, enum, union parameters in extern function" {
650650
651651export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
652652}
653
654
655test "slicing zero length array" {
656 const s1 = ""[0..];
657 const s2 = ([]u32{})[0..];
658 assert(s1.len == 0);
659 assert(s2.len == 0);
660 assert(mem.eql(u8, s1, ""));
661 assert(mem.eql(u32, s2, []u32{}));
662}
test/compare_output.zig+2-2
......@@ -285,8 +285,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
285285 \\const c = @cImport(@cInclude("stdlib.h"));
286286 \\
287287 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {
288 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);
289 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);
288 \\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable);
289 \\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable);
290290 \\ if (*a_int < *b_int) {
291291 \\ return -1;
292292 \\ } else if (*a_int > *b_int) {
test/compile_errors.zig+40-1
......@@ -1,6 +1,45 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: &tests.CompileErrorContext) void {
4 cases.add("@tagName used on union with no associated enum tag",
5 \\const FloatInt = extern union {
6 \\ Float: f32,
7 \\ Int: i32,
8 \\};
9 \\export fn entry() void {
10 \\ var fi = FloatInt{.Float = 123.45};
11 \\ var tagName = @tagName(fi);
12 \\}
13 ,
14 ".tmp_source.zig:7:19: error: union has no associated enum",
15 ".tmp_source.zig:1:18: note: declared here");
16
17 cases.add("returning error from void async function",
18 \\const std = @import("std");
19 \\export fn entry() void {
20 \\ const p = async(std.debug.global_allocator) amain() catch unreachable;
21 \\}
22 \\async fn amain() void {
23 \\ return error.ShouldBeCompileError;
24 \\}
25 ,
26 ".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'");
27
28 cases.add("var not allowed in structs",
29 \\export fn entry() void {
30 \\ var s = (struct{v: var}){.v=i32(10)};
31 \\}
32 ,
33 ".tmp_source.zig:2:23: error: invalid token: 'var'");
34
35 cases.add("@ptrCast discards const qualifier",
36 \\export fn entry() void {
37 \\ const x: i32 = 1234;
38 \\ const y = @ptrCast(&i32, &x);
39 \\}
40 ,
41 ".tmp_source.zig:3:15: error: cast discards const qualifier");
42
443 cases.add("comptime slice of undefined pointer non-zero len",
544 \\export fn entry() void {
645 \\ const slice = (&i32)(undefined)[0..1];
......@@ -2432,7 +2471,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
24322471 \\const Derp = @OpaqueType();
24332472 \\extern fn bar(d: &Derp) void;
24342473 \\export fn foo() void {
2435 \\ const x = u8(1);
2474 \\ var x = u8(1);
24362475 \\ bar(@ptrCast(&c_void, &x));
24372476 \\}
24382477 ,
test/translate_c.zig+167-31
......@@ -351,7 +351,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
351351 \\ var i: c_int = 0;
352352 \\ while (a > c_uint(0)) {
353353 \\ a >>= @import("std").math.Log2Int(c_uint)(1);
354 \\ };
354 \\ }
355355 \\ return i;
356356 \\}
357357 );
......@@ -451,6 +451,28 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
451451 \\}
452452 );
453453
454 cases.addC("logical and, logical or on none bool values",
455 \\int and_or_none_bool(int a, float b, void *c) {
456 \\ if (a && b) return 0;
457 \\ if (b && c) return 1;
458 \\ if (a && c) return 2;
459 \\ if (a || b) return 3;
460 \\ if (b || c) return 4;
461 \\ if (a || c) return 5;
462 \\ return 6;
463 \\}
464 ,
465 \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?&c_void) c_int {
466 \\ if ((a != 0) and (b != 0)) return 0;
467 \\ if ((b != 0) and (c != null)) return 1;
468 \\ if ((a != 0) and (c != null)) return 2;
469 \\ if ((a != 0) or (b != 0)) return 3;
470 \\ if ((b != 0) or (c != null)) return 4;
471 \\ if ((a != 0) or (c != null)) return 5;
472 \\ return 6;
473 \\}
474 );
475
454476 cases.addC("assign",
455477 \\int max(int a) {
456478 \\ int tmp;
......@@ -498,7 +520,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
498520 \\ var i: c_int = 0;
499521 \\ while (a > c_uint(0)) {
500522 \\ a >>= u5(1);
501 \\ };
523 \\ }
502524 \\ return i;
503525 \\}
504526 );
......@@ -515,11 +537,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
515537
516538 cases.addC("function call",
517539 \\static void bar(void) { }
518 \\void foo(void) { bar(); }
540 \\static int baz(void) { return 0; }
541 \\void foo(void) {
542 \\ bar();
543 \\ baz();
544 \\}
519545 ,
520546 \\pub fn bar() void {}
547 \\pub fn baz() c_int {
548 \\ return 0;
549 \\}
521550 \\pub export fn foo() void {
522551 \\ bar();
552 \\ _ = baz();
523553 \\}
524554 );
525555
......@@ -867,32 +897,42 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
867897 \\ while (true) {
868898 \\ a -= 1;
869899 \\ if (!(a != 0)) break;
870 \\ };
900 \\ }
871901 \\ var b: c_int = 2;
872902 \\ while (true) {
873903 \\ b -= 1;
874904 \\ if (!(b != 0)) break;
875 \\ };
905 \\ }
876906 \\}
877907 );
878908
879909 cases.addC("deref function pointer",
880910 \\void foo(void) {}
881 \\void baz(void) {}
911 \\int baz(void) { return 0; }
882912 \\void bar(void) {
883913 \\ void(*f)(void) = foo;
914 \\ int(*b)(void) = baz;
884915 \\ f();
885916 \\ (*(f))();
917 \\ foo();
918 \\ b();
919 \\ (*(b))();
886920 \\ baz();
887921 \\}
888922 ,
889923 \\pub export fn foo() void {}
890 \\pub export fn baz() void {}
924 \\pub export fn baz() c_int {
925 \\ return 0;
926 \\}
891927 \\pub export fn bar() void {
892928 \\ var f: ?extern fn() void = foo;
929 \\ var b: ?extern fn() c_int = baz;
893930 \\ (??f)();
894931 \\ (??f)();
895 \\ baz();
932 \\ foo();
933 \\ _ = (??b)();
934 \\ _ = (??b)();
935 \\ _ = baz();
896936 \\}
897937 );
898938
......@@ -962,8 +1002,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
9621002 \\pub fn foo() void {
9631003 \\ {
9641004 \\ var i: c_int = 0;
965 \\ while (i < 10) : (i += 1) {};
966 \\ };
1005 \\ while (i < 10) : (i += 1) {}
1006 \\ }
9671007 \\}
9681008 );
9691009
......@@ -973,7 +1013,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
9731013 \\}
9741014 ,
9751015 \\pub fn foo() void {
976 \\ while (true) {};
1016 \\ while (true) {}
9771017 \\}
9781018 );
9791019
......@@ -987,7 +1027,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
9871027 \\pub fn foo() void {
9881028 \\ while (true) {
9891029 \\ break;
990 \\ };
1030 \\ }
9911031 \\}
9921032 );
9931033
......@@ -1001,7 +1041,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
10011041 \\pub fn foo() void {
10021042 \\ while (true) {
10031043 \\ continue;
1004 \\ };
1044 \\ }
10051045 \\}
10061046 );
10071047
......@@ -1058,7 +1098,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
10581098 \\ {
10591099 \\ var x_0: c_int = 2;
10601100 \\ x_0 += 1;
1061 \\ };
1101 \\ }
10621102 \\ return x;
10631103 \\}
10641104 );
......@@ -1083,6 +1123,22 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
10831123 \\}
10841124 );
10851125
1126 cases.add("bool not",
1127 \\int foo(int a, float b, void *c) {
1128 \\ return !(a == 0);
1129 \\ return !a;
1130 \\ return !b;
1131 \\ return !c;
1132 \\}
1133 ,
1134 \\pub fn foo(a: c_int, b: f32, c: ?&c_void) c_int {
1135 \\ return !(a == 0);
1136 \\ return !(a != 0);
1137 \\ return !(b != 0);
1138 \\ return !(c != null);
1139 \\}
1140 );
1141
10861142 cases.add("primitive types included in defined symbols",
10871143 \\int foo(int u32) {
10881144 \\ return u32;
......@@ -1110,29 +1166,109 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
11101166 );
11111167
11121168 cases.add("macro pointer cast",
1113 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1169 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
11141170 ,
11151171 \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast(&NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr(&NRF_GPIO_Type, NRF_GPIO_BASE) else (&NRF_GPIO_Type)(NRF_GPIO_BASE);
11161172 );
11171173
1118 cases.add("if on int",
1119 \\int if_int(int i) {
1120 \\ if (i) {
1121 \\ return 0;
1122 \\ } else {
1123 \\ return 1;
1124 \\ }
1174 cases.add("if on none bool",
1175 \\enum SomeEnum { A, B, C };
1176 \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
1177 \\ if (a) return 0;
1178 \\ if (b) return 1;
1179 \\ if (c) return 2;
1180 \\ if (d) return 3;
1181 \\ return 4;
11251182 \\}
11261183 ,
1127 \\pub fn if_int(i: c_int) c_int {
1128 \\ {
1129 \\ const _tmp = i;
1130 \\ if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) {
1131 \\ return 0;
1132 \\ } else {
1133 \\ return 1;
1134 \\ };
1135 \\ };
1184 \\pub const A = enum_SomeEnum.A;
1185 \\pub const B = enum_SomeEnum.B;
1186 \\pub const C = enum_SomeEnum.C;
1187 \\pub const enum_SomeEnum = extern enum {
1188 \\ A,
1189 \\ B,
1190 \\ C,
1191 \\};
1192 \\pub fn if_none_bool(a: c_int, b: f32, c: ?&c_void, d: enum_SomeEnum) c_int {
1193 \\ if (a != 0) return 0;
1194 \\ if (b != 0) return 1;
1195 \\ if (c != null) return 2;
1196 \\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3;
1197 \\ return 4;
1198 \\}
1199 );
1200
1201 cases.add("while on none bool",
1202 \\int while_none_bool(int a, float b, void *c) {
1203 \\ while (a) return 0;
1204 \\ while (b) return 1;
1205 \\ while (c) return 2;
1206 \\ return 3;
1207 \\}
1208 ,
1209 \\pub fn while_none_bool(a: c_int, b: f32, c: ?&c_void) c_int {
1210 \\ while (a != 0) return 0;
1211 \\ while (b != 0) return 1;
1212 \\ while (c != null) return 2;
1213 \\ return 3;
1214 \\}
1215 );
1216
1217 cases.add("for on none bool",
1218 \\int for_none_bool(int a, float b, void *c) {
1219 \\ for (;a;) return 0;
1220 \\ for (;b;) return 1;
1221 \\ for (;c;) return 2;
1222 \\ return 3;
11361223 \\}
1224 ,
1225 \\pub fn for_none_bool(a: c_int, b: f32, c: ?&c_void) c_int {
1226 \\ while (a != 0) return 0;
1227 \\ while (b != 0) return 1;
1228 \\ while (c != null) return 2;
1229 \\ return 3;
1230 \\}
1231 );
1232
1233 cases.add("switch on int",
1234 \\int switch_fn(int i) {
1235 \\ int res = 0;
1236 \\ switch (i) {
1237 \\ case 0:
1238 \\ res = 1;
1239 \\ case 1:
1240 \\ res = 2;
1241 \\ default:
1242 \\ res = 3 * i;
1243 \\ break;
1244 \\ case 2:
1245 \\ res = 5;
1246 \\ }
1247 \\}
1248 ,
1249 \\pub fn switch_fn(i: c_int) c_int {
1250 \\ var res: c_int = 0;
1251 \\ __switch: {
1252 \\ __case_2: {
1253 \\ __default: {
1254 \\ __case_1: {
1255 \\ __case_0: {
1256 \\ switch (i) {
1257 \\ 0 => break :__case_0,
1258 \\ 1 => break :__case_1,
1259 \\ else => break :__default,
1260 \\ 2 => break :__case_2,
1261 \\ }
1262 \\ }
1263 \\ res = 1;
1264 \\ }
1265 \\ res = 2;
1266 \\ }
1267 \\ res = (3 * i);
1268 \\ break :__switch;
1269 \\ }
1270 \\ res = 5;
1271 \\ }
1272 \\}
11371273 );
11381274}