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....@@ -125,13 +125,13 @@ libc. Create demo games using Zig.
125125
126 * cmake >= 2.8.5126 * cmake >= 2.8.5
127 * gcc >= 5.0.0 or clang >= 3.6.0127 * gcc >= 5.0.0 or clang >= 3.6.0
128 * LLVM, Clang, LLD libraries == 6.x, compiled with the same gcc or clang version above128 * LLVM, Clang, LLD development libraries == 6.x, compiled with the same gcc or clang version above
129129
130##### Windows130##### Windows
131131
132 * cmake >= 2.8.5132 * cmake >= 2.8.5
133 * Microsoft Visual Studio 2015133 * Microsoft Visual Studio 2015
134 * LLVM, Clang, LLD libraries == 6.x, compiled with the same MSVC version above134 * LLVM, Clang, LLD development libraries == 6.x, compiled with the same MSVC version above
135135
136#### Instructions136#### Instructions
137137
doc/langref.html.in+3-3
...@@ -5733,19 +5733,19 @@ UseDecl = "use" Expression ";"...@@ -5733,19 +5733,19 @@ UseDecl = "use" Expression ";"
57335733
5734ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"5734ExternDecl = "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("!") TypeExpr5736FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") (TypeExpr | "var")
57375737
5738FnDef = option("inline" | "export") FnProto Block5738FnDef = option("inline" | "export") FnProto Block
57395739
5740ParamDeclList = "(" list(ParamDecl, ",") ")"5740ParamDeclList = "(" list(ParamDecl, ",") ")"
57415741
5742ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")5742ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "var" | "...")
57435743
5744Block = option(Symbol ":") "{" many(Statement) "}"5744Block = option(Symbol ":") "{" many(Statement) "}"
57455745
5746Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"5746Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
57475747
5748TypeExpr = ErrorSetExpr | "var"5748TypeExpr = ErrorSetExpr
57495749
5750ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression5750ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
57515751
src/all_types.hpp+5-6
...@@ -16,6 +16,7 @@...@@ -16,6 +16,7 @@
16#include "bigint.hpp"16#include "bigint.hpp"
17#include "bigfloat.hpp"17#include "bigfloat.hpp"
18#include "target.hpp"18#include "target.hpp"
19#include "tokenizer.hpp"
1920
20struct AstNode;21struct AstNode;
21struct ImportTableEntry;22struct ImportTableEntry;
...@@ -399,7 +400,6 @@ enum NodeType {...@@ -399,7 +400,6 @@ enum NodeType {
399 NodeTypeStructValueField,400 NodeTypeStructValueField,
400 NodeTypeArrayType,401 NodeTypeArrayType,
401 NodeTypeErrorType,402 NodeTypeErrorType,
402 NodeTypeVarLiteral,
403 NodeTypeIfErrorExpr,403 NodeTypeIfErrorExpr,
404 NodeTypeTestExpr,404 NodeTypeTestExpr,
405 NodeTypeErrorSetDecl,405 NodeTypeErrorSetDecl,
...@@ -427,6 +427,7 @@ struct AstNodeFnProto {...@@ -427,6 +427,7 @@ struct AstNodeFnProto {
427 Buf *name;427 Buf *name;
428 ZigList<AstNode *> params;428 ZigList<AstNode *> params;
429 AstNode *return_type;429 AstNode *return_type;
430 Token *return_var_token;
430 bool is_var_args;431 bool is_var_args;
431 bool is_extern;432 bool is_extern;
432 bool is_export;433 bool is_export;
...@@ -456,6 +457,7 @@ struct AstNodeFnDecl {...@@ -456,6 +457,7 @@ struct AstNodeFnDecl {
456struct AstNodeParamDecl {457struct AstNodeParamDecl {
457 Buf *name;458 Buf *name;
458 AstNode *type;459 AstNode *type;
460 Token *var_token;
459 bool is_noalias;461 bool is_noalias;
460 bool is_inline;462 bool is_inline;
461 bool is_var_args;463 bool is_var_args;
...@@ -866,9 +868,6 @@ struct AstNodeUnreachableExpr {...@@ -866,9 +868,6 @@ struct AstNodeUnreachableExpr {
866struct AstNodeErrorType {868struct AstNodeErrorType {
867};869};
868870
869struct AstNodeVarLiteral {
870};
871
872struct AstNodeAwaitExpr {871struct AstNodeAwaitExpr {
873 AstNode *expr;872 AstNode *expr;
874};873};
...@@ -933,7 +932,6 @@ struct AstNode {...@@ -933,7 +932,6 @@ struct AstNode {
933 AstNodeUnreachableExpr unreachable_expr;932 AstNodeUnreachableExpr unreachable_expr;
934 AstNodeArrayType array_type;933 AstNodeArrayType array_type;
935 AstNodeErrorType error_type;934 AstNodeErrorType error_type;
936 AstNodeVarLiteral var_literal;
937 AstNodeErrorSetDecl err_set_decl;935 AstNodeErrorSetDecl err_set_decl;
938 AstNodeCancelExpr cancel_expr;936 AstNodeCancelExpr cancel_expr;
939 AstNodeResumeExpr resume_expr;937 AstNodeResumeExpr resume_expr;
...@@ -1098,6 +1096,8 @@ struct TypeTableEntryUnion {...@@ -1098,6 +1096,8 @@ struct TypeTableEntryUnion {
1098 size_t gen_union_index;1096 size_t gen_union_index;
1099 size_t gen_tag_index;1097 size_t gen_tag_index;
11001098
1099 bool have_explicit_tag_type;
1100
1101 uint32_t union_size_bytes;1101 uint32_t union_size_bytes;
1102 TypeTableEntry *most_aligned_union_member;1102 TypeTableEntry *most_aligned_union_member;
11031103
...@@ -1134,7 +1134,6 @@ struct TypeTableEntryPromise {...@@ -1134,7 +1134,6 @@ struct TypeTableEntryPromise {
11341134
1135enum TypeTableEntryId {1135enum TypeTableEntryId {
1136 TypeTableEntryIdInvalid,1136 TypeTableEntryIdInvalid,
1137 TypeTableEntryIdVar,
1138 TypeTableEntryIdMetaType,1137 TypeTableEntryIdMetaType,
1139 TypeTableEntryIdVoid,1138 TypeTableEntryIdVoid,
1140 TypeTableEntryIdBool,1139 TypeTableEntryIdBool,
src/analyze.cpp+53-39
...@@ -200,7 +200,6 @@ static uint8_t bits_needed_for_unsigned(uint64_t x) {...@@ -200,7 +200,6 @@ static uint8_t bits_needed_for_unsigned(uint64_t x) {
200bool type_is_complete(TypeTableEntry *type_entry) {200bool type_is_complete(TypeTableEntry *type_entry) {
201 switch (type_entry->id) {201 switch (type_entry->id) {
202 case TypeTableEntryIdInvalid:202 case TypeTableEntryIdInvalid:
203 case TypeTableEntryIdVar:
204 zig_unreachable();203 zig_unreachable();
205 case TypeTableEntryIdStruct:204 case TypeTableEntryIdStruct:
206 return type_entry->data.structure.complete;205 return type_entry->data.structure.complete;
...@@ -239,7 +238,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {...@@ -239,7 +238,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {
239bool type_has_zero_bits_known(TypeTableEntry *type_entry) {238bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
240 switch (type_entry->id) {239 switch (type_entry->id) {
241 case TypeTableEntryIdInvalid:240 case TypeTableEntryIdInvalid:
242 case TypeTableEntryIdVar:
243 zig_unreachable();241 zig_unreachable();
244 case TypeTableEntryIdStruct:242 case TypeTableEntryIdStruct:
245 return type_entry->data.structure.zero_bits_known;243 return type_entry->data.structure.zero_bits_known;
...@@ -466,9 +464,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)...@@ -466,9 +464,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
466 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);464 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);
467 const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};465 const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};
468 TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};466 TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};
469 size_t field_count = type_has_bits(result_ptr_type) ? 3 : 1;
470 Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));467 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
473 return_type->promise_frame_parent = entry;470 return_type->promise_frame_parent = entry;
474 return entry;471 return entry;
...@@ -1281,7 +1278,6 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **...@@ -1281,7 +1278,6 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
1281static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {1278static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1282 switch (type_entry->id) {1279 switch (type_entry->id) {
1283 case TypeTableEntryIdInvalid:1280 case TypeTableEntryIdInvalid:
1284 case TypeTableEntryIdVar:
1285 zig_unreachable();1281 zig_unreachable();
1286 case TypeTableEntryIdMetaType:1282 case TypeTableEntryIdMetaType:
1287 case TypeTableEntryIdUnreachable:1283 case TypeTableEntryIdUnreachable:
...@@ -1324,7 +1320,6 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {...@@ -1324,7 +1320,6 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1324static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {1320static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1325 switch (type_entry->id) {1321 switch (type_entry->id) {
1326 case TypeTableEntryIdInvalid:1322 case TypeTableEntryIdInvalid:
1327 case TypeTableEntryIdVar:
1328 zig_unreachable();1323 zig_unreachable();
1329 case TypeTableEntryIdMetaType:1324 case TypeTableEntryIdMetaType:
1330 case TypeTableEntryIdNumLitFloat:1325 case TypeTableEntryIdNumLitFloat:
...@@ -1428,6 +1423,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1428,6 +1423,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1428 calling_convention_name(fn_type_id.cc)));1423 calling_convention_name(fn_type_id.cc)));
1429 return g->builtin_types.entry_invalid;1424 return g->builtin_types.entry_invalid;
1430 }1425 }
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);
1431 }1434 }
14321435
1433 TypeTableEntry *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type);1436 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...@@ -1463,14 +1466,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1463 add_node_error(g, param_node->data.param_decl.type,1466 add_node_error(g, param_node->data.param_decl.type,
1464 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));1467 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
1465 return g->builtin_types.entry_invalid;1468 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);
1474 case TypeTableEntryIdNumLitFloat:1469 case TypeTableEntryIdNumLitFloat:
1475 case TypeTableEntryIdNumLitInt:1470 case TypeTableEntryIdNumLitInt:
1476 case TypeTableEntryIdNamespace:1471 case TypeTableEntryIdNamespace:
...@@ -1514,6 +1509,19 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1514,6 +1509,19 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1514 }1509 }
1515 }1510 }
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
1517 TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);1525 TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
1518 if (type_is_invalid(specified_return_type)) {1526 if (type_is_invalid(specified_return_type)) {
1519 fn_type_id.return_type = g->builtin_types.entry_invalid;1527 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...@@ -1552,7 +1560,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1552 case TypeTableEntryIdNamespace:1560 case TypeTableEntryIdNamespace:
1553 case TypeTableEntryIdBlock:1561 case TypeTableEntryIdBlock:
1554 case TypeTableEntryIdBoundFn:1562 case TypeTableEntryIdBoundFn:
1555 case TypeTableEntryIdVar:
1556 case TypeTableEntryIdMetaType:1563 case TypeTableEntryIdMetaType:
1557 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {1564 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1558 add_node_error(g, fn_proto->return_type,1565 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...@@ -1707,7 +1714,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1707 buf_init_from_str(&struct_type->name, type_name);1714 buf_init_from_str(&struct_type->name, type_name);
17081715
1709 struct_type->data.structure.src_field_count = field_count;1716 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;
1711 struct_type->data.structure.zero_bits_known = true;1718 struct_type->data.structure.zero_bits_known = true;
1712 struct_type->data.structure.complete = true;1719 struct_type->data.structure.complete = true;
1713 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);1720 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...@@ -1716,22 +1723,26 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1716 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);1723 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
1717 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);1724 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
1718 for (size_t i = 0; i < field_count; i += 1) {1725 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
1721 TypeStructField *field = &struct_type->data.structure.fields[i];1728 TypeStructField *field = &struct_type->data.structure.fields[i];
1722 field->name = buf_create_from_str(field_names[i]);1729 field->name = buf_create_from_str(field_names[i]);
1723 field->type_entry = field_types[i];1730 field->type_entry = field_types[i];
1724 field->src_index = i;1731 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
1729 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);1740 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
1730 assert(prev_entry == nullptr);1741 assert(prev_entry == nullptr);
1731 }1742 }
17321743
1733 struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name);1744 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
1736 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,1747 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
1737 ZigLLVMTag_DW_structure_type(), type_name,1748 ZigLLVMTag_DW_structure_type(), type_name,
...@@ -1739,11 +1750,14 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f...@@ -1739,11 +1750,14 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17391750
1740 for (size_t i = 0; i < field_count; i += 1) {1751 for (size_t i = 0; i < field_count; i += 1) {
1741 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1752 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1753 if (type_struct_field->gen_index == SIZE_MAX) {
1754 continue;
1755 }
1742 TypeTableEntry *field_type = type_struct_field->type_entry;1756 TypeTableEntry *field_type = type_struct_field->type_entry;
1743 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);1757 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1744 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);1758 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);1759 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, type_struct_field->gen_index);
1746 di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,1760 di_element_types[type_struct_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1747 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),1761 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
1748 nullptr, 0,1762 nullptr, 0,
1749 debug_size_in_bits,1763 debug_size_in_bits,
...@@ -1751,7 +1765,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f...@@ -1751,7 +1765,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1751 debug_offset_in_bits,1765 debug_offset_in_bits,
1752 0, field_type->di_type);1766 0, field_type->di_type);
17531767
1754 assert(di_element_types[i]);1768 assert(di_element_types[type_struct_field->gen_index]);
1755 }1769 }
17561770
1757 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref);1771 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...@@ -1762,7 +1776,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1762 debug_size_in_bits,1776 debug_size_in_bits,
1763 debug_align_in_bits,1777 debug_align_in_bits,
1764 0,1778 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
1767 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);1781 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
1768 struct_type->di_type = replacement_di_type;1782 struct_type->di_type = replacement_di_type;
...@@ -2544,6 +2558,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2544,6 +2558,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2544 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};2558 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
25452559
2546 AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr;2560 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;
2547 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);2563 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
2548 bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr);2564 bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr);
2549 TypeTableEntry *tag_type;2565 TypeTableEntry *tag_type;
...@@ -3226,7 +3242,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3226,7 +3242,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3226 case NodeTypeStructValueField:3242 case NodeTypeStructValueField:
3227 case NodeTypeArrayType:3243 case NodeTypeArrayType:
3228 case NodeTypeErrorType:3244 case NodeTypeErrorType:
3229 case NodeTypeVarLiteral:
3230 case NodeTypeIfErrorExpr:3245 case NodeTypeIfErrorExpr:
3231 case NodeTypeTestExpr:3246 case NodeTypeTestExpr:
3232 case NodeTypeErrorSetDecl:3247 case NodeTypeErrorSetDecl:
...@@ -3262,7 +3277,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -3262,7 +3277,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
3262 case TypeTableEntryIdInvalid:3277 case TypeTableEntryIdInvalid:
3263 return g->builtin_types.entry_invalid;3278 return g->builtin_types.entry_invalid;
3264 case TypeTableEntryIdUnreachable:3279 case TypeTableEntryIdUnreachable:
3265 case TypeTableEntryIdVar:
3266 case TypeTableEntryIdNumLitFloat:3280 case TypeTableEntryIdNumLitFloat:
3267 case TypeTableEntryIdNumLitInt:3281 case TypeTableEntryIdNumLitInt:
3268 case TypeTableEntryIdUndefLit:3282 case TypeTableEntryIdUndefLit:
...@@ -3641,7 +3655,6 @@ TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *t...@@ -3641,7 +3655,6 @@ TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *t
3641static bool is_container(TypeTableEntry *type_entry) {3655static bool is_container(TypeTableEntry *type_entry) {
3642 switch (type_entry->id) {3656 switch (type_entry->id) {
3643 case TypeTableEntryIdInvalid:3657 case TypeTableEntryIdInvalid:
3644 case TypeTableEntryIdVar:
3645 zig_unreachable();3658 zig_unreachable();
3646 case TypeTableEntryIdStruct:3659 case TypeTableEntryIdStruct:
3647 case TypeTableEntryIdEnum:3660 case TypeTableEntryIdEnum:
...@@ -3716,7 +3729,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {...@@ -3716,7 +3729,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
3716 case TypeTableEntryIdBlock:3729 case TypeTableEntryIdBlock:
3717 case TypeTableEntryIdBoundFn:3730 case TypeTableEntryIdBoundFn:
3718 case TypeTableEntryIdInvalid:3731 case TypeTableEntryIdInvalid:
3719 case TypeTableEntryIdVar:
3720 case TypeTableEntryIdArgTuple:3732 case TypeTableEntryIdArgTuple:
3721 case TypeTableEntryIdOpaque:3733 case TypeTableEntryIdOpaque:
3722 case TypeTableEntryIdPromise:3734 case TypeTableEntryIdPromise:
...@@ -3753,6 +3765,19 @@ uint32_t get_ptr_align(TypeTableEntry *type) {...@@ -3753,6 +3765,19 @@ uint32_t get_ptr_align(TypeTableEntry *type) {
3753 }3765 }
3754}3766}
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
3756AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) {3781AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) {
3757 if (fn_entry->param_source_nodes)3782 if (fn_entry->param_source_nodes)
3758 return fn_entry->param_source_nodes[index];3783 return fn_entry->param_source_nodes[index];
...@@ -4203,7 +4228,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -4203,7 +4228,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
4203 case TypeTableEntryIdNamespace:4228 case TypeTableEntryIdNamespace:
4204 case TypeTableEntryIdBlock:4229 case TypeTableEntryIdBlock:
4205 case TypeTableEntryIdBoundFn:4230 case TypeTableEntryIdBoundFn:
4206 case TypeTableEntryIdVar:
4207 case TypeTableEntryIdArgTuple:4231 case TypeTableEntryIdArgTuple:
4208 case TypeTableEntryIdOpaque:4232 case TypeTableEntryIdOpaque:
4209 zig_unreachable();4233 zig_unreachable();
...@@ -4502,7 +4526,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4502,7 +4526,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4502 case TypeTableEntryIdBoundFn:4526 case TypeTableEntryIdBoundFn:
4503 case TypeTableEntryIdInvalid:4527 case TypeTableEntryIdInvalid:
4504 case TypeTableEntryIdUnreachable:4528 case TypeTableEntryIdUnreachable:
4505 case TypeTableEntryIdVar:
4506 zig_unreachable();4529 zig_unreachable();
4507 }4530 }
4508 zig_unreachable();4531 zig_unreachable();
...@@ -4600,7 +4623,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {...@@ -4600,7 +4623,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {
4600bool type_requires_comptime(TypeTableEntry *type_entry) {4623bool type_requires_comptime(TypeTableEntry *type_entry) {
4601 switch (type_entry->id) {4624 switch (type_entry->id) {
4602 case TypeTableEntryIdInvalid:4625 case TypeTableEntryIdInvalid:
4603 case TypeTableEntryIdVar:
4604 case TypeTableEntryIdOpaque:4626 case TypeTableEntryIdOpaque:
4605 zig_unreachable();4627 zig_unreachable();
4606 case TypeTableEntryIdNumLitFloat:4628 case TypeTableEntryIdNumLitFloat:
...@@ -5096,7 +5118,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -5096,7 +5118,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
5096 case TypeTableEntryIdBoundFn:5118 case TypeTableEntryIdBoundFn:
5097 case TypeTableEntryIdInvalid:5119 case TypeTableEntryIdInvalid:
5098 case TypeTableEntryIdUnreachable:5120 case TypeTableEntryIdUnreachable:
5099 case TypeTableEntryIdVar:
5100 case TypeTableEntryIdPromise:5121 case TypeTableEntryIdPromise:
5101 zig_unreachable();5122 zig_unreachable();
5102 }5123 }
...@@ -5176,9 +5197,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5176,9 +5197,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5176 case TypeTableEntryIdInvalid:5197 case TypeTableEntryIdInvalid:
5177 buf_appendf(buf, "(invalid)");5198 buf_appendf(buf, "(invalid)");
5178 return;5199 return;
5179 case TypeTableEntryIdVar:
5180 buf_appendf(buf, "(var)");
5181 return;
5182 case TypeTableEntryIdVoid:5200 case TypeTableEntryIdVoid:
5183 buf_appendf(buf, "{}");5201 buf_appendf(buf, "{}");
5184 return;5202 return;
...@@ -5414,7 +5432,6 @@ TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits)...@@ -5414,7 +5432,6 @@ TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits)
5414uint32_t type_id_hash(TypeId x) {5432uint32_t type_id_hash(TypeId x) {
5415 switch (x.id) {5433 switch (x.id) {
5416 case TypeTableEntryIdInvalid:5434 case TypeTableEntryIdInvalid:
5417 case TypeTableEntryIdVar:
5418 case TypeTableEntryIdOpaque:5435 case TypeTableEntryIdOpaque:
5419 case TypeTableEntryIdMetaType:5436 case TypeTableEntryIdMetaType:
5420 case TypeTableEntryIdVoid:5437 case TypeTableEntryIdVoid:
...@@ -5461,7 +5478,6 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -5461,7 +5478,6 @@ bool type_id_eql(TypeId a, TypeId b) {
5461 return false;5478 return false;
5462 switch (a.id) {5479 switch (a.id) {
5463 case TypeTableEntryIdInvalid:5480 case TypeTableEntryIdInvalid:
5464 case TypeTableEntryIdVar:
5465 case TypeTableEntryIdMetaType:5481 case TypeTableEntryIdMetaType:
5466 case TypeTableEntryIdVoid:5482 case TypeTableEntryIdVoid:
5467 case TypeTableEntryIdBool:5483 case TypeTableEntryIdBool:
...@@ -5616,7 +5632,6 @@ size_t type_id_len() {...@@ -5616,7 +5632,6 @@ size_t type_id_len() {
5616size_t type_id_index(TypeTableEntryId id) {5632size_t type_id_index(TypeTableEntryId id) {
5617 switch (id) {5633 switch (id) {
5618 case TypeTableEntryIdInvalid:5634 case TypeTableEntryIdInvalid:
5619 case TypeTableEntryIdVar:
5620 zig_unreachable();5635 zig_unreachable();
5621 case TypeTableEntryIdMetaType:5636 case TypeTableEntryIdMetaType:
5622 return 0;5637 return 0;
...@@ -5675,7 +5690,6 @@ size_t type_id_index(TypeTableEntryId id) {...@@ -5675,7 +5690,6 @@ size_t type_id_index(TypeTableEntryId id) {
5675const char *type_id_name(TypeTableEntryId id) {5690const char *type_id_name(TypeTableEntryId id) {
5676 switch (id) {5691 switch (id) {
5677 case TypeTableEntryIdInvalid:5692 case TypeTableEntryIdInvalid:
5678 case TypeTableEntryIdVar:
5679 zig_unreachable();5693 zig_unreachable();
5680 case TypeTableEntryIdMetaType:5694 case TypeTableEntryIdMetaType:
5681 return "Type";5695 return "Type";
src/analyze.hpp+1
...@@ -55,6 +55,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);...@@ -55,6 +55,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);
5555
56TypeTableEntry *get_codegen_ptr_type(TypeTableEntry *type);56TypeTableEntry *get_codegen_ptr_type(TypeTableEntry *type);
57uint32_t get_ptr_align(TypeTableEntry *type);57uint32_t get_ptr_align(TypeTableEntry *type);
58bool get_ptr_const(TypeTableEntry *type);
58TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);59TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
59TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);60TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
60bool type_is_complete(TypeTableEntry *type_entry);61bool 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) {...@@ -236,8 +236,6 @@ static const char *node_type_str(NodeType node_type) {
236 return "ArrayType";236 return "ArrayType";
237 case NodeTypeErrorType:237 case NodeTypeErrorType:
238 return "ErrorType";238 return "ErrorType";
239 case NodeTypeVarLiteral:
240 return "VarLiteral";
241 case NodeTypeIfErrorExpr:239 case NodeTypeIfErrorExpr:
242 return "IfErrorExpr";240 return "IfErrorExpr";
243 case NodeTypeTestExpr:241 case NodeTypeTestExpr:
...@@ -436,6 +434,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -436,6 +434,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
436 }434 }
437 if (param_decl->data.param_decl.is_var_args) {435 if (param_decl->data.param_decl.is_var_args) {
438 fprintf(ar->f, "...");436 fprintf(ar->f, "...");
437 } else if (param_decl->data.param_decl.var_token != nullptr) {
438 fprintf(ar->f, "var");
439 } else {439 } else {
440 render_node_grouped(ar, param_decl->data.param_decl.type);440 render_node_grouped(ar, param_decl->data.param_decl.type);
441 }441 }
...@@ -456,13 +456,17 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -456,13 +456,17 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
456 fprintf(ar->f, ")");456 fprintf(ar->f, ")");
457 }457 }
458458
459 AstNode *return_type_node = node->data.fn_proto.return_type;459 if (node->data.fn_proto.return_var_token != nullptr) {
460 assert(return_type_node != nullptr);460 fprintf(ar->f, "var");
461 fprintf(ar->f, " ");461 } else {
462 if (node->data.fn_proto.auto_err_set) {462 AstNode *return_type_node = node->data.fn_proto.return_type;
463 fprintf(ar->f, "!");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);
464 }469 }
465 render_node_grouped(ar, return_type_node);
466 break;470 break;
467 }471 }
468 case NodeTypeFnDef:472 case NodeTypeFnDef:
...@@ -486,7 +490,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -486,7 +490,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
486 AstNode *statement = node->data.block.statements.at(i);490 AstNode *statement = node->data.block.statements.at(i);
487 print_indent(ar);491 print_indent(ar);
488 render_node_grouped(ar, statement);492 render_node_grouped(ar, statement);
489 fprintf(ar->f, ";");493
494 if (!statement_terminates_without_semicolon(statement))
495 fprintf(ar->f, ";");
496
490 fprintf(ar->f, "\n");497 fprintf(ar->f, "\n");
491 }498 }
492 ar->indent -= ar->indent_size;499 ar->indent -= ar->indent_size;
...@@ -768,9 +775,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -768,9 +775,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
768 case NodeTypeErrorType:775 case NodeTypeErrorType:
769 fprintf(ar->f, "error");776 fprintf(ar->f, "error");
770 break;777 break;
771 case NodeTypeVarLiteral:
772 fprintf(ar->f, "var");
773 break;
774 case NodeTypeAsmExpr:778 case NodeTypeAsmExpr:
775 {779 {
776 AstNodeAsmExpr *asm_expr = &node->data.asm_expr;780 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...@@ -4508,7 +4508,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
4508 assert(!type_entry->zero_bits);4508 assert(!type_entry->zero_bits);
4509 switch (type_entry->id) {4509 switch (type_entry->id) {
4510 case TypeTableEntryIdInvalid:4510 case TypeTableEntryIdInvalid:
4511 case TypeTableEntryIdVar:
4512 case TypeTableEntryIdMetaType:4511 case TypeTableEntryIdMetaType:
4513 case TypeTableEntryIdUnreachable:4512 case TypeTableEntryIdUnreachable:
4514 case TypeTableEntryIdNumLitFloat:4513 case TypeTableEntryIdNumLitFloat:
...@@ -4960,7 +4959,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -4960,7 +4959,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
4960 case TypeTableEntryIdNamespace:4959 case TypeTableEntryIdNamespace:
4961 case TypeTableEntryIdBlock:4960 case TypeTableEntryIdBlock:
4962 case TypeTableEntryIdBoundFn:4961 case TypeTableEntryIdBoundFn:
4963 case TypeTableEntryIdVar:
4964 case TypeTableEntryIdArgTuple:4962 case TypeTableEntryIdArgTuple:
4965 case TypeTableEntryIdOpaque:4963 case TypeTableEntryIdOpaque:
4966 case TypeTableEntryIdPromise:4964 case TypeTableEntryIdPromise:
...@@ -5611,11 +5609,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -5611,11 +5609,6 @@ static void define_builtin_types(CodeGen *g) {
5611 entry->zero_bits = true;5609 entry->zero_bits = true;
5612 g->builtin_types.entry_null = entry;5610 g->builtin_types.entry_null = entry;
5613 }5611 }
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 }
5619 {5612 {
5620 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArgTuple);5613 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArgTuple);
5621 buf_init_from_str(&entry->name, "(args)");5614 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...@@ -6444,7 +6437,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry
64446437
6445 switch (type_entry->id) {6438 switch (type_entry->id) {
6446 case TypeTableEntryIdInvalid:6439 case TypeTableEntryIdInvalid:
6447 case TypeTableEntryIdVar:
6448 case TypeTableEntryIdMetaType:6440 case TypeTableEntryIdMetaType:
6449 case TypeTableEntryIdNumLitFloat:6441 case TypeTableEntryIdNumLitFloat:
6450 case TypeTableEntryIdNumLitInt:6442 case TypeTableEntryIdNumLitInt:
...@@ -6639,7 +6631,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf...@@ -6639,7 +6631,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf
6639 case TypeTableEntryIdNumLitInt:6631 case TypeTableEntryIdNumLitInt:
6640 case TypeTableEntryIdUndefLit:6632 case TypeTableEntryIdUndefLit:
6641 case TypeTableEntryIdNullLit:6633 case TypeTableEntryIdNullLit:
6642 case TypeTableEntryIdVar:
6643 case TypeTableEntryIdArgTuple:6634 case TypeTableEntryIdArgTuple:
6644 case TypeTableEntryIdPromise:6635 case TypeTableEntryIdPromise:
6645 zig_unreachable();6636 zig_unreachable();
...@@ -6781,7 +6772,6 @@ static void gen_h_file(CodeGen *g) {...@@ -6781,7 +6772,6 @@ static void gen_h_file(CodeGen *g) {
6781 TypeTableEntry *type_entry = gen_h->types_to_declare.at(type_i);6772 TypeTableEntry *type_entry = gen_h->types_to_declare.at(type_i);
6782 switch (type_entry->id) {6773 switch (type_entry->id) {
6783 case TypeTableEntryIdInvalid:6774 case TypeTableEntryIdInvalid:
6784 case TypeTableEntryIdVar:
6785 case TypeTableEntryIdMetaType:6775 case TypeTableEntryIdMetaType:
6786 case TypeTableEntryIdVoid:6776 case TypeTableEntryIdVoid:
6787 case TypeTableEntryIdBool:6777 case TypeTableEntryIdBool:
src/ir.cpp+80-92
...@@ -948,12 +948,10 @@ static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope,...@@ -948,12 +948,10 @@ static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope,
948 const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;948 const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;
949 const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;949 const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;
950 const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;950 const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;
951 if (struct_type->data.structure.src_field_count > 1) {951 const_instruction->base.value.data.x_struct.fields[1].type = return_type;
952 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[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].type = struct_type->data.structure.fields[2].type_entry;954 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
955 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
956 }
957 return &const_instruction->base;955 return &const_instruction->base;
958}956}
959957
...@@ -2147,7 +2145,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s...@@ -2147,7 +2145,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s
2147 size_t param_count = source_node->data.fn_proto.params.length;2145 size_t param_count = source_node->data.fn_proto.params.length;
2148 if (is_var_args) param_count -= 1;2146 if (is_var_args) param_count -= 1;
2149 for (size_t i = 0; i < param_count; i += 1) {2147 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);
2151 }2149 }
2152 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);2150 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
2153 ir_ref_instruction(return_type, irb->current_basic_block);2151 ir_ref_instruction(return_type, irb->current_basic_block);
...@@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode...@@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
2741 return return_inst;2739 return return_inst;
2742 }2740 }
27432741
2744 if (irb->exec->coro_result_ptr_field_ptr) {2742 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, 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);2743 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2746 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2747 }
2748 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,2744 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,
2749 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));2745 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
2750 // TODO replace replacement_value with @intToPtr(?promise, 0x1) when it doesn't crash zig2746 // 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...@@ -3305,12 +3301,6 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode
3305 return ir_build_const_null(irb, scope, node);3301 return ir_build_const_null(irb, scope, node);
3306}3302}
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
3314static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {3304static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
3315 assert(node->type == NodeTypeSymbol);3305 assert(node->type == NodeTypeSymbol);
33163306
...@@ -5916,11 +5906,15 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5916,11 +5906,15 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
5916 is_var_args = true;5906 is_var_args = true;
5917 break;5907 break;
5918 }5908 }
5919 AstNode *type_node = param_node->data.param_decl.type;5909 if (param_node->data.param_decl.var_token == nullptr) {
5920 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope);5910 AstNode *type_node = param_node->data.param_decl.type;
5921 if (type_value == irb->codegen->invalid_instruction)5911 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope);
5922 return irb->codegen->invalid_instruction;5912 if (type_value == irb->codegen->invalid_instruction)
5923 param_types[i] = type_value;5913 return irb->codegen->invalid_instruction;
5914 param_types[i] = type_value;
5915 } else {
5916 param_types[i] = nullptr;
5917 }
5924 }5918 }
59255919
5926 IrInstruction *align_value = nullptr;5920 IrInstruction *align_value = nullptr;
...@@ -5931,12 +5925,16 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5931,12 +5925,16 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
5931 }5925 }
59325926
5933 IrInstruction *return_type;5927 IrInstruction *return_type;
5934 if (node->data.fn_proto.return_type == nullptr) {5928 if (node->data.fn_proto.return_var_token == nullptr) {
5935 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void);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 }
5936 } else {5936 } else {
5937 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);5937 return_type = nullptr;
5938 if (return_type == irb->codegen->invalid_instruction)
5939 return irb->codegen->invalid_instruction;
5940 }5938 }
59415939
5942 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);5940 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...@@ -6189,8 +6187,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
6189 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval);6187 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval);
6190 case NodeTypeNullLiteral:6188 case NodeTypeNullLiteral:
6191 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval);6189 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);
6194 case NodeTypeIfErrorExpr:6190 case NodeTypeIfErrorExpr:
6195 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval);6191 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval);
6196 case NodeTypeTestExpr:6192 case NodeTypeTestExpr:
...@@ -6328,14 +6324,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6328,14 +6324,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6328 Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);6324 Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);
6329 irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,6325 irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
6330 awaiter_handle_field_name);6326 awaiter_handle_field_name);
6331 if (type_has_bits(return_type)) {6327 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6332 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);
6333 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);
6334 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);
6335 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,6331 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_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 }
63396332
63406333
6341 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");6334 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,...@@ -7515,11 +7508,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
7515 return ImplicitCastMatchResultReportedError;7508 return ImplicitCastMatchResultReportedError;
7516 }7509 }
75177510
7518 // implicit conversion from anything to var
7519 if (expected_type->id == TypeTableEntryIdVar) {
7520 return ImplicitCastMatchResultYes;
7521 }
7522
7523 // implicit conversion from non maybe type to maybe type7511 // implicit conversion from non maybe type to maybe type
7524 if (expected_type->id == TypeTableEntryIdMaybe &&7512 if (expected_type->id == TypeTableEntryIdMaybe &&
7525 ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type, actual_type, value))7513 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...@@ -9341,9 +9329,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9341 return ira->codegen->invalid_instruction;9329 return ira->codegen->invalid_instruction;
9342 }9330 }
93439331
9344 if (wanted_type->id == TypeTableEntryIdVar)
9345 return value;
9346
9347 // explicit match or non-const to const9332 // explicit match or non-const to const
9348 if (types_match_const_cast_only(ira, wanted_type, actual_type, source_node).id == ConstCastResultIdOk) {9333 if (types_match_const_cast_only(ira, wanted_type, actual_type, source_node).id == ConstCastResultIdOk) {
9349 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);9334 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...@@ -10311,9 +10296,6 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
10311 ir_add_error_node(ira, source_node,10296 ir_add_error_node(ira, source_node,
10312 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));10297 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
10313 return ira->codegen->builtin_types.entry_invalid;10298 return ira->codegen->builtin_types.entry_invalid;
10314
10315 case TypeTableEntryIdVar:
10316 zig_unreachable();
10317 }10299 }
1031810300
10319 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type);10301 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type);
...@@ -11106,7 +11088,6 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {...@@ -11106,7 +11088,6 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
11106 case TypeTableEntryIdInvalid:11088 case TypeTableEntryIdInvalid:
11107 zig_unreachable();11089 zig_unreachable();
11108 case TypeTableEntryIdUnreachable:11090 case TypeTableEntryIdUnreachable:
11109 case TypeTableEntryIdVar:
11110 return VarClassRequiredIllegal;11091 return VarClassRequiredIllegal;
11111 case TypeTableEntryIdBool:11092 case TypeTableEntryIdBool:
11112 case TypeTableEntryIdInt:11093 case TypeTableEntryIdInt:
...@@ -11279,7 +11260,6 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi...@@ -11279,7 +11260,6 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
1127911260
11280 switch (target->value.type->id) {11261 switch (target->value.type->id) {
11281 case TypeTableEntryIdInvalid:11262 case TypeTableEntryIdInvalid:
11282 case TypeTableEntryIdVar:
11283 case TypeTableEntryIdUnreachable:11263 case TypeTableEntryIdUnreachable:
11284 zig_unreachable();11264 zig_unreachable();
11285 case TypeTableEntryIdFn: {11265 case TypeTableEntryIdFn: {
...@@ -11332,7 +11312,6 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi...@@ -11332,7 +11312,6 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
11332 TypeTableEntry *type_value = target->value.data.x_type;11312 TypeTableEntry *type_value = target->value.data.x_type;
11333 switch (type_value->id) {11313 switch (type_value->id) {
11334 case TypeTableEntryIdInvalid:11314 case TypeTableEntryIdInvalid:
11335 case TypeTableEntryIdVar:
11336 zig_unreachable();11315 zig_unreachable();
11337 case TypeTableEntryIdStruct:11316 case TypeTableEntryIdStruct:
11338 if (is_slice(type_value)) {11317 if (is_slice(type_value)) {
...@@ -11543,14 +11522,20 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node...@@ -11543,14 +11522,20 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
11543{11522{
11544 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);11523 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);
11545 assert(param_decl_node->type == NodeTypeParamDecl);11524 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);11526 IrInstruction *casted_arg;
11552 if (type_is_invalid(casted_arg->value.type))11527 if (param_decl_node->data.param_decl.var_token == nullptr) {
11553 return false;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
11555 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad);11540 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad);
11556 if (!arg_val)11541 if (!arg_val)
...@@ -11579,19 +11564,18 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -11579,19 +11564,18 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
11579 arg_part_of_generic_id = true;11564 arg_part_of_generic_id = true;
11580 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);11565 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
11581 } else {11566 } else {
11582 AstNode *param_type_node = param_decl_node->data.param_decl.type;11567 if (param_decl_node->data.param_decl.var_token == nullptr) {
11583 TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);11568 AstNode *param_type_node = param_decl_node->data.param_decl.type;
11584 if (type_is_invalid(param_type))11569 TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);
11585 return false;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 {
11592 casted_arg = ir_implicit_cast(ira, arg, param_type);11573 casted_arg = ir_implicit_cast(ira, arg, param_type);
11593 if (type_is_invalid(casted_arg->value.type))11574 if (type_is_invalid(casted_arg->value.type))
11594 return false;11575 return false;
11576 } else {
11577 arg_part_of_generic_id = true;
11578 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
11595 }11579 }
11596 }11580 }
1159711581
...@@ -12028,7 +12012,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12028,7 +12012,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12028 inst_fn_type_id.alignment = align_bytes;12012 inst_fn_type_id.alignment = align_bytes;
12029 }12013 }
1203012014
12031 {12015 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) {
12032 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;12016 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
12033 TypeTableEntry *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);12017 TypeTableEntry *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
12034 if (type_is_invalid(specified_return_type))12018 if (type_is_invalid(specified_return_type))
...@@ -12304,7 +12288,6 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op...@@ -12304,7 +12288,6 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
12304 return ira->codegen->builtin_types.entry_invalid;12288 return ira->codegen->builtin_types.entry_invalid;
12305 switch (type_entry->id) {12289 switch (type_entry->id) {
12306 case TypeTableEntryIdInvalid:12290 case TypeTableEntryIdInvalid:
12307 case TypeTableEntryIdVar:
12308 zig_unreachable();12291 zig_unreachable();
12309 case TypeTableEntryIdMetaType:12292 case TypeTableEntryIdMetaType:
12310 case TypeTableEntryIdVoid:12293 case TypeTableEntryIdVoid:
...@@ -13539,10 +13522,6 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi...@@ -13539,10 +13522,6 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
13539 switch (type_entry->id) {13522 switch (type_entry->id) {
13540 case TypeTableEntryIdInvalid:13523 case TypeTableEntryIdInvalid:
13541 zig_unreachable(); // handled above13524 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;
13546 case TypeTableEntryIdNumLitFloat:13525 case TypeTableEntryIdNumLitFloat:
13547 case TypeTableEntryIdNumLitInt:13526 case TypeTableEntryIdNumLitInt:
13548 case TypeTableEntryIdUndefLit:13527 case TypeTableEntryIdUndefLit:
...@@ -13807,7 +13786,6 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -13807,7 +13786,6 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
13807 switch (child_type->id) {13786 switch (child_type->id) {
13808 case TypeTableEntryIdInvalid: // handled above13787 case TypeTableEntryIdInvalid: // handled above
13809 zig_unreachable();13788 zig_unreachable();
13810 case TypeTableEntryIdVar:
13811 case TypeTableEntryIdUnreachable:13789 case TypeTableEntryIdUnreachable:
13812 case TypeTableEntryIdUndefLit:13790 case TypeTableEntryIdUndefLit:
13813 case TypeTableEntryIdNullLit:13791 case TypeTableEntryIdNullLit:
...@@ -13916,7 +13894,6 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -13916,7 +13894,6 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
13916 switch (child_type->id) {13894 switch (child_type->id) {
13917 case TypeTableEntryIdInvalid: // handled above13895 case TypeTableEntryIdInvalid: // handled above
13918 zig_unreachable();13896 zig_unreachable();
13919 case TypeTableEntryIdVar:
13920 case TypeTableEntryIdUnreachable:13897 case TypeTableEntryIdUnreachable:
13921 case TypeTableEntryIdUndefLit:13898 case TypeTableEntryIdUndefLit:
13922 case TypeTableEntryIdNullLit:13899 case TypeTableEntryIdNullLit:
...@@ -13968,7 +13945,6 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -13968,7 +13945,6 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
13968 switch (type_entry->id) {13945 switch (type_entry->id) {
13969 case TypeTableEntryIdInvalid: // handled above13946 case TypeTableEntryIdInvalid: // handled above
13970 zig_unreachable();13947 zig_unreachable();
13971 case TypeTableEntryIdVar:
13972 case TypeTableEntryIdUnreachable:13948 case TypeTableEntryIdUnreachable:
13973 case TypeTableEntryIdUndefLit:13949 case TypeTableEntryIdUndefLit:
13974 case TypeTableEntryIdNullLit:13950 case TypeTableEntryIdNullLit:
...@@ -14161,6 +14137,14 @@ static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source...@@ -14161,6 +14137,14 @@ static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source
14161 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name)));14137 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name)));
14162 return ira->codegen->invalid_instruction;14138 return ira->codegen->invalid_instruction;
14163 }14139 }
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
14165 TypeTableEntry *tag_type = value->value.type->data.unionation.tag_type;14149 TypeTableEntry *tag_type = value->value.type->data.unionation.tag_type;
14166 assert(tag_type->id == TypeTableEntryIdEnum);14150 assert(tag_type->id == TypeTableEntryIdEnum);
...@@ -14316,7 +14300,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -14316,7 +14300,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1431614300
14317 switch (target_type->id) {14301 switch (target_type->id) {
14318 case TypeTableEntryIdInvalid:14302 case TypeTableEntryIdInvalid:
14319 case TypeTableEntryIdVar:
14320 zig_unreachable();14303 zig_unreachable();
14321 case TypeTableEntryIdMetaType:14304 case TypeTableEntryIdMetaType:
14322 case TypeTableEntryIdVoid:14305 case TypeTableEntryIdVoid:
...@@ -14911,7 +14894,6 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_...@@ -14911,7 +14894,6 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
14911 }14894 }
14912 case TypeTableEntryIdEnum:14895 case TypeTableEntryIdEnum:
14913 zig_panic("TODO min/max value for enum type");14896 zig_panic("TODO min/max value for enum type");
14914 case TypeTableEntryIdVar:
14915 case TypeTableEntryIdMetaType:14897 case TypeTableEntryIdMetaType:
14916 case TypeTableEntryIdUnreachable:14898 case TypeTableEntryIdUnreachable:
14917 case TypeTableEntryIdPointer:14899 case TypeTableEntryIdPointer:
...@@ -15821,9 +15803,13 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -15821,9 +15803,13 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
15821 TypeTableEntry *return_type;15803 TypeTableEntry *return_type;
1582215804
15823 if (array_type->id == TypeTableEntryIdArray) {15805 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 }
15824 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,15810 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,
15825 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,15811 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);
15827 return_type = get_slice_type(ira->codegen, slice_ptr_type);15813 return_type = get_slice_type(ira->codegen, slice_ptr_type);
15828 } else if (array_type->id == TypeTableEntryIdPointer) {15814 } else if (array_type->id == TypeTableEntryIdPointer) {
15829 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,15815 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...@@ -16155,7 +16141,6 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
1615516141
16156 switch (type_entry->id) {16142 switch (type_entry->id) {
16157 case TypeTableEntryIdInvalid:16143 case TypeTableEntryIdInvalid:
16158 case TypeTableEntryIdVar:
16159 zig_unreachable();16144 zig_unreachable();
16160 case TypeTableEntryIdMetaType:16145 case TypeTableEntryIdMetaType:
16161 case TypeTableEntryIdUnreachable:16146 case TypeTableEntryIdUnreachable:
...@@ -16457,21 +16442,23 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc...@@ -16457,21 +16442,23 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc
16457 zig_unreachable();16442 zig_unreachable();
16458 }16443 }
16459 }16444 }
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
16464 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];16445 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
16465 param_info->is_noalias = param_node->data.param_decl.is_noalias;16446 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;
16471 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);16450 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
16472 out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id);16451 out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id);
16473 return ira->codegen->builtin_types.entry_type;16452 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;
16474 }16460 }
16461
16475 }16462 }
1647616463
16477 if (instruction->align_value != nullptr) {16464 if (instruction->align_value != nullptr) {
...@@ -16816,6 +16803,11 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc...@@ -16816,6 +16803,11 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc
16816 return ira->codegen->builtin_types.entry_invalid;16803 return ira->codegen->builtin_types.entry_invalid;
16817 }16804 }
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
16819 if (instr_is_comptime(ptr)) {16811 if (instr_is_comptime(ptr)) {
16820 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);16812 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
16821 if (!val)16813 if (!val)
...@@ -16860,7 +16852,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -16860,7 +16852,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
16860 assert(val->special == ConstValSpecialStatic);16852 assert(val->special == ConstValSpecialStatic);
16861 switch (val->type->id) {16853 switch (val->type->id) {
16862 case TypeTableEntryIdInvalid:16854 case TypeTableEntryIdInvalid:
16863 case TypeTableEntryIdVar:
16864 case TypeTableEntryIdMetaType:16855 case TypeTableEntryIdMetaType:
16865 case TypeTableEntryIdOpaque:16856 case TypeTableEntryIdOpaque:
16866 case TypeTableEntryIdBoundFn:16857 case TypeTableEntryIdBoundFn:
...@@ -16928,7 +16919,6 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -16928,7 +16919,6 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
16928 assert(val->special == ConstValSpecialStatic);16919 assert(val->special == ConstValSpecialStatic);
16929 switch (val->type->id) {16920 switch (val->type->id) {
16930 case TypeTableEntryIdInvalid:16921 case TypeTableEntryIdInvalid:
16931 case TypeTableEntryIdVar:
16932 case TypeTableEntryIdMetaType:16922 case TypeTableEntryIdMetaType:
16933 case TypeTableEntryIdOpaque:16923 case TypeTableEntryIdOpaque:
16934 case TypeTableEntryIdBoundFn:16924 case TypeTableEntryIdBoundFn:
...@@ -17005,7 +16995,6 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc...@@ -17005,7 +16995,6 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
1700516995
17006 switch (src_type->id) {16996 switch (src_type->id) {
17007 case TypeTableEntryIdInvalid:16997 case TypeTableEntryIdInvalid:
17008 case TypeTableEntryIdVar:
17009 case TypeTableEntryIdMetaType:16998 case TypeTableEntryIdMetaType:
17010 case TypeTableEntryIdOpaque:16999 case TypeTableEntryIdOpaque:
17011 case TypeTableEntryIdBoundFn:17000 case TypeTableEntryIdBoundFn:
...@@ -17032,7 +17021,6 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc...@@ -17032,7 +17021,6 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
1703217021
17033 switch (dest_type->id) {17022 switch (dest_type->id) {
17034 case TypeTableEntryIdInvalid:17023 case TypeTableEntryIdInvalid:
17035 case TypeTableEntryIdVar:
17036 case TypeTableEntryIdMetaType:17024 case TypeTableEntryIdMetaType:
17037 case TypeTableEntryIdOpaque:17025 case TypeTableEntryIdOpaque:
17038 case TypeTableEntryIdBoundFn:17026 case TypeTableEntryIdBoundFn:
src/parser.cpp+24-25
...@@ -263,21 +263,14 @@ static AstNode *ast_parse_error_set_expr(ParseContext *pc, size_t *token_index,...@@ -263,21 +263,14 @@ static AstNode *ast_parse_error_set_expr(ParseContext *pc, size_t *token_index,
263}263}
264264
265/*265/*
266TypeExpr = ErrorSetExpr | "var"266TypeExpr = ErrorSetExpr
267*/267*/
268static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {268static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
269 Token *token = &pc->tokens->at(*token_index);269 return ast_parse_error_set_expr(pc, token_index, mandatory);
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 }
277}270}
278271
279/*272/*
280ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")273ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "var" | "...")
281*/274*/
282static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {275static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
283 Token *token = &pc->tokens->at(*token_index);276 Token *token = &pc->tokens->at(*token_index);
...@@ -308,6 +301,9 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {...@@ -308,6 +301,9 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
308 if (ellipsis_tok->id == TokenIdEllipsis3) {301 if (ellipsis_tok->id == TokenIdEllipsis3) {
309 *token_index += 1;302 *token_index += 1;
310 node->data.param_decl.is_var_args = true;303 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;
311 } else {307 } else {
312 node->data.param_decl.type = ast_parse_type_expr(pc, token_index, true);308 node->data.param_decl.type = ast_parse_type_expr(pc, token_index, true);
313 }309 }
...@@ -2319,7 +2315,7 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool...@@ -2319,7 +2315,7 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool
2319 return nullptr;2315 return nullptr;
2320}2316}
23212317
2322static bool statement_terminates_without_semicolon(AstNode *node) {2318bool statement_terminates_without_semicolon(AstNode *node) {
2323 switch (node->type) {2319 switch (node->type) {
2324 case NodeTypeIfBoolExpr:2320 case NodeTypeIfBoolExpr:
2325 if (node->data.if_bool_expr.else_node)2321 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...@@ -2421,7 +2417,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
2421}2417}
24222418
2423/*2419/*
2424FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") TypeExpr2420FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("(" Expression ")"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") (TypeExpr | "var")
2425*/2421*/
2426static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {2422static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
2427 Token *first_token = &pc->tokens->at(*token_index);2423 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...@@ -2507,19 +2503,25 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
2507 ast_eat_token(pc, token_index, TokenIdRParen);2503 ast_eat_token(pc, token_index, TokenIdRParen);
2508 next_token = &pc->tokens->at(*token_index);2504 next_token = &pc->tokens->at(*token_index);
2509 }2505 }
2510 if (next_token->id == TokenIdKeywordError) {2506 if (next_token->id == TokenIdKeywordVar) {
2511 Token *maybe_lbrace_tok = &pc->tokens->at(*token_index + 1);2507 node->data.fn_proto.return_var_token = next_token;
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) {
2518 *token_index += 1;2508 *token_index += 1;
2519 node->data.fn_proto.auto_err_set = true;
2520 next_token = &pc->tokens->at(*token_index);2509 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);
2521 }2524 }
2522 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
25232525
2524 return node;2526 return node;
2525}2527}
...@@ -3069,9 +3071,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3069,9 +3071,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3069 case NodeTypeErrorType:3071 case NodeTypeErrorType:
3070 // none3072 // none
3071 break;3073 break;
3072 case NodeTypeVarLiteral:
3073 // none
3074 break;
3075 case NodeTypeAddrOfExpr:3074 case NodeTypeAddrOfExpr:
3076 visit_field(&node->data.addr_of_expr.align_expr, visit, context);3075 visit_field(&node->data.addr_of_expr.align_expr, visit, context);
3077 visit_field(&node->data.addr_of_expr.op_expr, visit, context);3076 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);...@@ -23,4 +23,6 @@ void ast_print(AstNode *node, int indent);
2323
24void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);24void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);
2525
26bool statement_terminates_without_semicolon(AstNode *node);
27
26#endif28#endif
src/target.cpp+1-1
...@@ -787,7 +787,7 @@ static FloatAbi get_float_abi(ZigTarget *target) {...@@ -787,7 +787,7 @@ static FloatAbi get_float_abi(ZigTarget *target) {
787 {787 {
788 return FloatAbiHard;788 return FloatAbiHard;
789 } else {789 } else {
790 zig_panic("TODO: user needs to input if they want hard or soft floating point");790 return FloatAbiSoft;
791 }791 }
792}792}
793793
src/translate_c.cpp+482-111
...@@ -104,6 +104,7 @@ static TransScopeRoot *trans_scope_root_create(Context *c);...@@ -104,6 +104,7 @@ static TransScopeRoot *trans_scope_root_create(Context *c);
104static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);104static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
105static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);105static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
106static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);106static 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
108static TransScopeBlock *trans_scope_block_find(TransScope *scope);109static TransScopeBlock *trans_scope_block_find(TransScope *scope);
109110
...@@ -118,7 +119,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,...@@ -118,7 +119,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
118static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node);119static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node);
119static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);120static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
120static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);121static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
121122static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
122123
123ATTRIBUTE_PRINTF(3, 4)124ATTRIBUTE_PRINTF(3, 4)
124static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {125static 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) {...@@ -466,6 +467,14 @@ static QualType get_expr_qual_type(Context *c, const Expr *expr) {
466 return expr->getType();467 return expr->getType();
467}468}
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
469static AstNode *get_expr_type(Context *c, const Expr *expr) {478static AstNode *get_expr_type(Context *c, const Expr *expr) {
470 return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());479 return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());
471}480}
...@@ -499,15 +508,31 @@ static bool qual_type_is_ptr(QualType qt) {...@@ -499,15 +508,31 @@ static bool qual_type_is_ptr(QualType qt) {
499 return ty->getTypeClass() == Type::Pointer;508 return ty->getTypeClass() == Type::Pointer;
500}509}
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) {
503 const Type *ty = qual_type_canon(qt);512 const Type *ty = qual_type_canon(qt);
504 if (ty->getTypeClass() != Type::Pointer) {513 *is_ptr = false;
505 return 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);
506 }524 }
507 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);525
508 QualType child_qt = pointer_ty->getPointeeType();526 return nullptr;
509 const Type *child_ty = child_qt.getTypePtr();527}
510 return child_ty->getTypeClass() == Type::FunctionProto;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;
511}536}
512537
513static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {538static 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) {...@@ -632,7 +657,7 @@ static bool c_is_signed_integer(Context *c, QualType qt) {
632 case BuiltinType::Int128:657 case BuiltinType::Int128:
633 case BuiltinType::WChar_S:658 case BuiltinType::WChar_S:
634 return true;659 return true;
635 default: 660 default:
636 return false;661 return false;
637 }662 }
638}663}
...@@ -653,7 +678,7 @@ static bool c_is_unsigned_integer(Context *c, QualType qt) {...@@ -653,7 +678,7 @@ static bool c_is_unsigned_integer(Context *c, QualType qt) {
653 case BuiltinType::UInt128:678 case BuiltinType::UInt128:
654 case BuiltinType::WChar_U:679 case BuiltinType::WChar_U:
655 return true;680 return true;
656 default: 681 default:
657 return false;682 return false;
658 }683 }
659}684}
...@@ -678,7 +703,7 @@ static bool c_is_float(Context *c, QualType qt) {...@@ -678,7 +703,7 @@ static bool c_is_float(Context *c, QualType qt) {
678 case BuiltinType::Float128:703 case BuiltinType::Float128:
679 case BuiltinType::LongDouble:704 case BuiltinType::LongDouble:
680 return true;705 return true;
681 default: 706 default:
682 return false;707 return false;
683 }708 }
684}709}
...@@ -1138,6 +1163,22 @@ static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, Bi...@@ -1138,6 +1163,22 @@ static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, Bi
1138 return node;1163 return node;
1139}1164}
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
1141static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) {1182static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) {
1142 if (result_used == ResultUsedNo) {1183 if (result_used == ResultUsedNo) {
1143 // common case1184 // common case
...@@ -1282,10 +1323,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS...@@ -1282,10 +1323,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
1282 case BO_Or:1323 case BO_Or:
1283 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());1324 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
1284 case BO_LAnd:1325 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());
1286 case BO_LOr:1327 case BO_LOr:
1287 // TODO: int vs bool1328 return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1288 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1289 case BO_Assign:1329 case BO_Assign:
1290 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());1330 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());
1291 case BO_Comma:1331 case BO_Comma:
...@@ -1395,7 +1435,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1395,7 +1435,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
1395 if (result_used == ResultUsedYes) {1435 if (result_used == ResultUsedYes) {
1396 // break :x *_ref1436 // break :x *_ref
1397 child_scope->node->data.block.statements.append(1437 child_scope->node->data.block.statements.append(
1398 trans_create_node_break(c, label_name, 1438 trans_create_node_break(c, label_name,
1399 trans_create_node_prefix_op(c, PrefixOpDereference,1439 trans_create_node_prefix_op(c, PrefixOpDereference,
1400 trans_create_node_symbol(c, tmp_var_name))));1440 trans_create_node_symbol(c, tmp_var_name))));
1401 }1441 }
...@@ -1879,7 +1919,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc...@@ -1879,7 +1919,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
1879 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);1919 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
1880 if (value_node == nullptr)1920 if (value_node == nullptr)
1881 return nullptr;1921 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());
1883 if (is_fn_ptr)1923 if (is_fn_ptr)
1884 return value_node;1924 return value_node;
1885 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);1925 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...@@ -1922,11 +1962,18 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
1922 AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);1962 AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
1923 if (sub_node == nullptr)1963 if (sub_node == nullptr)
1924 return nullptr;1964 return nullptr;
1965
1925 return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node);1966 return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node);
1926 }1967 }
1927 case UO_LNot:1968 case UO_LNot:
1928 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_LNot");1969 {
1929 return nullptr;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 }
1930 case UO_Real:1977 case UO_Real:
1931 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Real");1978 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Real");
1932 return nullptr;1979 return nullptr;
...@@ -2206,16 +2253,246 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt...@@ -2206,16 +2253,246 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt
2206 return ErrorNone;2253 return ErrorNone;
2207}2254}
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
2209static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {2486static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
2210 TransScopeWhile *while_scope = trans_scope_while_create(c, scope);2487 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);
2213 if (while_scope->node->data.while_expr.condition == nullptr)2490 if (while_scope->node->data.while_expr.condition == nullptr)
2214 return nullptr;2491 return nullptr;
22152492
2216 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(),2493 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(),
2217 &while_scope->node->data.while_expr.body);2494 &while_scope->node->data.while_expr.body);
2218 if (body_scope == nullptr) 2495 if (body_scope == nullptr)
2219 return nullptr;2496 return nullptr;
22202497
2221 return while_scope->node;2498 return while_scope->node;
...@@ -2236,87 +2513,11 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *...@@ -2236,87 +2513,11 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *
2236 return nullptr;2513 return nullptr;
2237 }2514 }
22382515
2239 AstNode *condition_node = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);2516 if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2240 if (condition_node == nullptr)2517 if (if_node->data.if_bool_expr.condition == nullptr)
2241 return nullptr;2518 return nullptr;
22422519
2243 switch (condition_node->type) {2520 return if_node;
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 }
2320}2521}
23212522
2322static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const CallExpr *stmt) {2523static 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 *...@@ -2326,8 +2527,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
2326 if (callee_raw_node == nullptr)2527 if (callee_raw_node == nullptr)
2327 return nullptr;2528 return nullptr;
23282529
2530 bool is_ptr = false;
2531 const FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
2329 AstNode *callee_node = nullptr;2532 AstNode *callee_node = nullptr;
2330 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {2533 if (is_ptr && fn_ty) {
2331 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {2534 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
2332 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());2535 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());
2333 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {2536 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
...@@ -2359,6 +2562,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *...@@ -2359,6 +2562,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
2359 node->data.fn_call_expr.params.append(arg_node);2562 node->data.fn_call_expr.params.append(arg_node);
2360 }2563 }
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
2362 return node;2569 return node;
2363}2570}
23642571
...@@ -2501,10 +2708,18 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt...@@ -2501,10 +2708,18 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
2501 if (cond_stmt == nullptr) {2708 if (cond_stmt == nullptr) {
2502 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);2709 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
2503 } else {2710 } else {
2504 TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt,2711 if (Expr::classof(cond_stmt)) {
2505 &while_scope->node->data.while_expr.condition);2712 const Expr *cond_expr = static_cast<const Expr*>(cond_stmt);
2506 if (end_cond_scope == nullptr)2713 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope, cond_expr, TransRValue);
2507 return nullptr;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 }
2508 }2723 }
25092724
2510 const Stmt *inc_stmt = stmt->getInc();2725 const Stmt *inc_stmt = stmt->getInc();
...@@ -2525,6 +2740,155 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt...@@ -2525,6 +2740,155 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
2525 return loop_block_node;2740 return loop_block_node;
2526}2741}
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
2528static AstNode *trans_string_literal(Context *c, TransScope *scope, const StringLiteral *stmt) {2892static AstNode *trans_string_literal(Context *c, TransScope *scope, const StringLiteral *stmt) {
2529 switch (stmt->getKind()) {2893 switch (stmt->getKind()) {
2530 case StringLiteral::Ascii:2894 case StringLiteral::Ascii:
...@@ -2549,7 +2913,8 @@ static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt...@@ -2549,7 +2913,8 @@ static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt
2549 if (cur_scope->id == TransScopeIdWhile) {2913 if (cur_scope->id == TransScopeIdWhile) {
2550 return trans_create_node(c, NodeTypeBreak);2914 return trans_create_node(c, NodeTypeBreak);
2551 } else if (cur_scope->id == TransScopeIdSwitch) {2915 } 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);
2553 }2918 }
2554 cur_scope = cur_scope->parent;2919 cur_scope = cur_scope->parent;
2555 }2920 }
...@@ -2649,14 +3014,12 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,...@@ -2649,14 +3014,12 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
2649 return wrap_stmt(out_node, out_child_scope, scope,3014 return wrap_stmt(out_node, out_child_scope, scope,
2650 trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue));3015 trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue));
2651 case Stmt::SwitchStmtClass:3016 case Stmt::SwitchStmtClass:
2652 emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");3017 return wrap_stmt(out_node, out_child_scope, scope,
2653 return ErrorUnexpected;3018 trans_switch_stmt(c, scope, (const SwitchStmt *)stmt));
2654 case Stmt::CaseStmtClass:3019 case Stmt::CaseStmtClass:
2655 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");3020 return trans_switch_case(c, scope, (const CaseStmt *)stmt, out_node, out_child_scope);
2656 return ErrorUnexpected;
2657 case Stmt::DefaultStmtClass:3021 case Stmt::DefaultStmtClass:
2658 emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");3022 return trans_switch_default(c, scope, (const DefaultStmt *)stmt, out_node, out_child_scope);
2659 return ErrorUnexpected;
2660 case Stmt::NoStmtClass:3023 case Stmt::NoStmtClass:
2661 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");3024 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
2662 return ErrorUnexpected;3025 return ErrorUnexpected;
...@@ -3826,6 +4189,14 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop...@@ -3826,6 +4189,14 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop
3826 return result;4189 return result;
3827}4190}
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
3829static TransScopeBlock *trans_scope_block_find(TransScope *scope) {4200static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
3830 while (scope != nullptr) {4201 while (scope != nullptr) {
3831 if (scope->id == TransScopeIdBlock) {4202 if (scope->id == TransScopeIdBlock) {
std/buf_map.zig+1-3
...@@ -62,9 +62,7 @@ pub const BufMap = struct {...@@ -62,9 +62,7 @@ pub const BufMap = struct {
62 }62 }
6363
64 fn free(self: &BufMap, value: []const u8) void {64 fn free(self: &BufMap, value: []const u8) void {
65 // remove the const65 self.hash_map.allocator.free(value);
66 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
67 self.hash_map.allocator.free(mut_value);
68 }66 }
6967
70 fn copy(self: &BufMap, value: []const u8) ![]const u8 {68 fn copy(self: &BufMap, value: []const u8) ![]const u8 {
std/buf_set.zig+1-3
...@@ -50,9 +50,7 @@ pub const BufSet = struct {...@@ -50,9 +50,7 @@ pub const BufSet = struct {
50 }50 }
5151
52 fn free(self: &BufSet, value: []const u8) void {52 fn free(self: &BufSet, value: []const u8) void {
53 // remove the const53 self.hash_map.allocator.free(value);
54 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
55 self.hash_map.allocator.free(mut_value);
56 }54 }
5755
58 fn copy(self: &BufSet, value: []const u8) ![]const u8 {56 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 {...@@ -1634,7 +1634,7 @@ pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {
1634 for (args_alloc) |arg| {1634 for (args_alloc) |arg| {
1635 total_bytes += @sizeOf([]u8) + arg.len;1635 total_bytes += @sizeOf([]u8) + arg.len;
1636 }1636 }
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];
1638 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);1638 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);
1639 return allocator.free(aligned_allocated_buf);1639 return allocator.free(aligned_allocated_buf);
1640}1640}
std/special/compiler_rt/udivmod.zig+2-2
...@@ -11,8 +11,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -11,8 +11,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
12 const Log2SingleInt = @import("../../math/index.zig").Log2Int(SingleInt);12 const Log2SingleInt = @import("../../math/index.zig").Log2Int(SingleInt);
1313
14 const n = *@ptrCast(&[2]SingleInt, &a); // TODO issue #42114 const n = *@ptrCast(&const [2]SingleInt, &a); // TODO issue #421
15 const d = *@ptrCast(&[2]SingleInt, &b); // TODO issue #42115 const d = *@ptrCast(&const [2]SingleInt, &b); // TODO issue #421
16 var q: [2]SingleInt = undefined;16 var q: [2]SingleInt = undefined;
17 var r: [2]SingleInt = undefined;17 var r: [2]SingleInt = undefined;
18 var sr: c_uint = undefined;18 var sr: c_uint = undefined;
std/unicode.zig+14-6
...@@ -96,7 +96,15 @@ pub fn utf8ValidateSlice(s: []const u8) bool {...@@ -96,7 +96,15 @@ pub fn utf8ValidateSlice(s: []const u8) bool {
96 return true;96 return true;
97}97}
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 {
100 bytes: []const u8,108 bytes: []const u8,
101109
102 pub fn init(s: []const u8) !Utf8View {110 pub fn init(s: []const u8) !Utf8View {
...@@ -124,7 +132,7 @@ const Utf8View = struct {...@@ -124,7 +132,7 @@ const Utf8View = struct {
124 }132 }
125 }133 }
126134
127 pub fn Iterator(s: &const Utf8View) Utf8Iterator {135 pub fn iterator(s: &const Utf8View) Utf8Iterator {
128 return Utf8Iterator {136 return Utf8Iterator {
129 .bytes = s.bytes,137 .bytes = s.bytes,
130 .i = 0,138 .i = 0,
...@@ -165,13 +173,13 @@ const Utf8Iterator = struct {...@@ -165,13 +173,13 @@ const Utf8Iterator = struct {
165test "utf8 iterator on ascii" {173test "utf8 iterator on ascii" {
166 const s = Utf8View.initComptime("abc");174 const s = Utf8View.initComptime("abc");
167175
168 var it1 = s.Iterator();176 var it1 = s.iterator();
169 debug.assert(std.mem.eql(u8, "a", ??it1.nextCodepointSlice()));177 debug.assert(std.mem.eql(u8, "a", ??it1.nextCodepointSlice()));
170 debug.assert(std.mem.eql(u8, "b", ??it1.nextCodepointSlice()));178 debug.assert(std.mem.eql(u8, "b", ??it1.nextCodepointSlice()));
171 debug.assert(std.mem.eql(u8, "c", ??it1.nextCodepointSlice()));179 debug.assert(std.mem.eql(u8, "c", ??it1.nextCodepointSlice()));
172 debug.assert(it1.nextCodepointSlice() == null);180 debug.assert(it1.nextCodepointSlice() == null);
173181
174 var it2 = s.Iterator();182 var it2 = s.iterator();
175 debug.assert(??it2.nextCodepoint() == 'a');183 debug.assert(??it2.nextCodepoint() == 'a');
176 debug.assert(??it2.nextCodepoint() == 'b');184 debug.assert(??it2.nextCodepoint() == 'b');
177 debug.assert(??it2.nextCodepoint() == 'c');185 debug.assert(??it2.nextCodepoint() == 'c');
...@@ -189,13 +197,13 @@ test "utf8 view bad" {...@@ -189,13 +197,13 @@ test "utf8 view bad" {
189test "utf8 view ok" {197test "utf8 view ok" {
190 const s = Utf8View.initComptime("東京市");198 const s = Utf8View.initComptime("東京市");
191199
192 var it1 = s.Iterator();200 var it1 = s.iterator();
193 debug.assert(std.mem.eql(u8, "東", ??it1.nextCodepointSlice()));201 debug.assert(std.mem.eql(u8, "東", ??it1.nextCodepointSlice()));
194 debug.assert(std.mem.eql(u8, "京", ??it1.nextCodepointSlice()));202 debug.assert(std.mem.eql(u8, "京", ??it1.nextCodepointSlice()));
195 debug.assert(std.mem.eql(u8, "市", ??it1.nextCodepointSlice()));203 debug.assert(std.mem.eql(u8, "市", ??it1.nextCodepointSlice()));
196 debug.assert(it1.nextCodepointSlice() == null);204 debug.assert(it1.nextCodepointSlice() == null);
197205
198 var it2 = s.Iterator();206 var it2 = s.iterator();
199 debug.assert(??it2.nextCodepoint() == 0x6771);207 debug.assert(??it2.nextCodepoint() == 0x6771);
200 debug.assert(??it2.nextCodepoint() == 0x4eac);208 debug.assert(??it2.nextCodepoint() == 0x4eac);
201 debug.assert(??it2.nextCodepoint() == 0x5e02);209 debug.assert(??it2.nextCodepoint() == 0x5e02);
test/cases/cast.zig+1-1
...@@ -16,7 +16,7 @@ test "integer literal to pointer cast" {...@@ -16,7 +16,7 @@ test "integer literal to pointer cast" {
16test "pointer reinterpret const float to int" {16test "pointer reinterpret const float to int" {
17 const float: f64 = 5.99999999999994648725e-01;17 const float: f64 = 5.99999999999994648725e-01;
18 const float_ptr = &float;18 const float_ptr = &float;
19 const int_ptr = @ptrCast(&i32, float_ptr);19 const int_ptr = @ptrCast(&const i32, float_ptr);
20 const int_val = *int_ptr;20 const int_val = *int_ptr;
21 assert(int_val == 858993411);21 assert(int_val == 858993411);
22}22}
test/cases/misc.zig+11-1
...@@ -261,7 +261,7 @@ test "generic malloc free" {...@@ -261,7 +261,7 @@ test "generic malloc free" {
261 const a = memAlloc(u8, 10) catch unreachable;261 const a = memAlloc(u8, 10) catch unreachable;
262 memFree(u8, a);262 memFree(u8, a);
263}263}
264const some_mem : [100]u8 = undefined;264var some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) error![]T {265fn memAlloc(comptime T: type, n: usize) error![]T {
266 return @ptrCast(&T, &some_mem[0])[0..n];266 return @ptrCast(&T, &some_mem[0])[0..n];
267}267}
...@@ -650,3 +650,13 @@ test "packed struct, enum, union parameters in extern function" {...@@ -650,3 +650,13 @@ test "packed struct, enum, union parameters in extern function" {
650650
651export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {651export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
652}652}
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 {...@@ -285,8 +285,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
285 \\const c = @cImport(@cInclude("stdlib.h"));285 \\const c = @cImport(@cInclude("stdlib.h"));
286 \\286 \\
287 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {287 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {
288 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);288 \\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable);
289 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);289 \\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable);
290 \\ if (*a_int < *b_int) {290 \\ if (*a_int < *b_int) {
291 \\ return -1;291 \\ return -1;
292 \\ } else if (*a_int > *b_int) {292 \\ } else if (*a_int > *b_int) {
test/compile_errors.zig+40-1
...@@ -1,6 +1,45 @@...@@ -1,6 +1,45 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) void {3pub 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
4 cases.add("comptime slice of undefined pointer non-zero len",43 cases.add("comptime slice of undefined pointer non-zero len",
5 \\export fn entry() void {44 \\export fn entry() void {
6 \\ const slice = (&i32)(undefined)[0..1];45 \\ const slice = (&i32)(undefined)[0..1];
...@@ -2432,7 +2471,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2432,7 +2471,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2432 \\const Derp = @OpaqueType();2471 \\const Derp = @OpaqueType();
2433 \\extern fn bar(d: &Derp) void;2472 \\extern fn bar(d: &Derp) void;
2434 \\export fn foo() void {2473 \\export fn foo() void {
2435 \\ const x = u8(1);2474 \\ var x = u8(1);
2436 \\ bar(@ptrCast(&c_void, &x));2475 \\ bar(@ptrCast(&c_void, &x));
2437 \\}2476 \\}
2438 ,2477 ,
test/translate_c.zig+167-31
...@@ -351,7 +351,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -351,7 +351,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
351 \\ var i: c_int = 0;351 \\ var i: c_int = 0;
352 \\ while (a > c_uint(0)) {352 \\ while (a > c_uint(0)) {
353 \\ a >>= @import("std").math.Log2Int(c_uint)(1);353 \\ a >>= @import("std").math.Log2Int(c_uint)(1);
354 \\ };354 \\ }
355 \\ return i;355 \\ return i;
356 \\}356 \\}
357 );357 );
...@@ -451,6 +451,28 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -451,6 +451,28 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
451 \\}451 \\}
452 );452 );
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
454 cases.addC("assign",476 cases.addC("assign",
455 \\int max(int a) {477 \\int max(int a) {
456 \\ int tmp;478 \\ int tmp;
...@@ -498,7 +520,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -498,7 +520,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
498 \\ var i: c_int = 0;520 \\ var i: c_int = 0;
499 \\ while (a > c_uint(0)) {521 \\ while (a > c_uint(0)) {
500 \\ a >>= u5(1);522 \\ a >>= u5(1);
501 \\ };523 \\ }
502 \\ return i;524 \\ return i;
503 \\}525 \\}
504 );526 );
...@@ -515,11 +537,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -515,11 +537,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
515537
516 cases.addC("function call",538 cases.addC("function call",
517 \\static void bar(void) { }539 \\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 \\}
519 ,545 ,
520 \\pub fn bar() void {}546 \\pub fn bar() void {}
547 \\pub fn baz() c_int {
548 \\ return 0;
549 \\}
521 \\pub export fn foo() void {550 \\pub export fn foo() void {
522 \\ bar();551 \\ bar();
552 \\ _ = baz();
523 \\}553 \\}
524 );554 );
525555
...@@ -867,32 +897,42 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -867,32 +897,42 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
867 \\ while (true) {897 \\ while (true) {
868 \\ a -= 1;898 \\ a -= 1;
869 \\ if (!(a != 0)) break;899 \\ if (!(a != 0)) break;
870 \\ };900 \\ }
871 \\ var b: c_int = 2;901 \\ var b: c_int = 2;
872 \\ while (true) {902 \\ while (true) {
873 \\ b -= 1;903 \\ b -= 1;
874 \\ if (!(b != 0)) break;904 \\ if (!(b != 0)) break;
875 \\ };905 \\ }
876 \\}906 \\}
877 );907 );
878908
879 cases.addC("deref function pointer",909 cases.addC("deref function pointer",
880 \\void foo(void) {}910 \\void foo(void) {}
881 \\void baz(void) {}911 \\int baz(void) { return 0; }
882 \\void bar(void) {912 \\void bar(void) {
883 \\ void(*f)(void) = foo;913 \\ void(*f)(void) = foo;
914 \\ int(*b)(void) = baz;
884 \\ f();915 \\ f();
885 \\ (*(f))();916 \\ (*(f))();
917 \\ foo();
918 \\ b();
919 \\ (*(b))();
886 \\ baz();920 \\ baz();
887 \\}921 \\}
888 ,922 ,
889 \\pub export fn foo() void {}923 \\pub export fn foo() void {}
890 \\pub export fn baz() void {}924 \\pub export fn baz() c_int {
925 \\ return 0;
926 \\}
891 \\pub export fn bar() void {927 \\pub export fn bar() void {
892 \\ var f: ?extern fn() void = foo;928 \\ var f: ?extern fn() void = foo;
929 \\ var b: ?extern fn() c_int = baz;
893 \\ (??f)();930 \\ (??f)();
894 \\ (??f)();931 \\ (??f)();
895 \\ baz();932 \\ foo();
933 \\ _ = (??b)();
934 \\ _ = (??b)();
935 \\ _ = baz();
896 \\}936 \\}
897 );937 );
898938
...@@ -962,8 +1002,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -962,8 +1002,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
962 \\pub fn foo() void {1002 \\pub fn foo() void {
963 \\ {1003 \\ {
964 \\ var i: c_int = 0;1004 \\ var i: c_int = 0;
965 \\ while (i < 10) : (i += 1) {};1005 \\ while (i < 10) : (i += 1) {}
966 \\ };1006 \\ }
967 \\}1007 \\}
968 );1008 );
9691009
...@@ -973,7 +1013,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -973,7 +1013,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
973 \\}1013 \\}
974 ,1014 ,
975 \\pub fn foo() void {1015 \\pub fn foo() void {
976 \\ while (true) {};1016 \\ while (true) {}
977 \\}1017 \\}
978 );1018 );
9791019
...@@ -987,7 +1027,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -987,7 +1027,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
987 \\pub fn foo() void {1027 \\pub fn foo() void {
988 \\ while (true) {1028 \\ while (true) {
989 \\ break;1029 \\ break;
990 \\ };1030 \\ }
991 \\}1031 \\}
992 );1032 );
9931033
...@@ -1001,7 +1041,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -1001,7 +1041,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
1001 \\pub fn foo() void {1041 \\pub fn foo() void {
1002 \\ while (true) {1042 \\ while (true) {
1003 \\ continue;1043 \\ continue;
1004 \\ };1044 \\ }
1005 \\}1045 \\}
1006 );1046 );
10071047
...@@ -1058,7 +1098,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -1058,7 +1098,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
1058 \\ {1098 \\ {
1059 \\ var x_0: c_int = 2;1099 \\ var x_0: c_int = 2;
1060 \\ x_0 += 1;1100 \\ x_0 += 1;
1061 \\ };1101 \\ }
1062 \\ return x;1102 \\ return x;
1063 \\}1103 \\}
1064 );1104 );
...@@ -1083,6 +1123,22 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -1083,6 +1123,22 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
1083 \\}1123 \\}
1084 );1124 );
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
1086 cases.add("primitive types included in defined symbols",1142 cases.add("primitive types included in defined symbols",
1087 \\int foo(int u32) {1143 \\int foo(int u32) {
1088 \\ return u32;1144 \\ return u32;
...@@ -1110,29 +1166,109 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -1110,29 +1166,109 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
1110 );1166 );
11111167
1112 cases.add("macro pointer cast",1168 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)
1114 ,1170 ,
1115 \\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);1171 \\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);
1116 );1172 );
11171173
1118 cases.add("if on int",1174 cases.add("if on none bool",
1119 \\int if_int(int i) {1175 \\enum SomeEnum { A, B, C };
1120 \\ if (i) {1176 \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
1121 \\ return 0;1177 \\ if (a) return 0;
1122 \\ } else {1178 \\ if (b) return 1;
1123 \\ return 1;1179 \\ if (c) return 2;
1124 \\ }1180 \\ if (d) return 3;
1181 \\ return 4;
1125 \\}1182 \\}
1126 ,1183 ,
1127 \\pub fn if_int(i: c_int) c_int {1184 \\pub const A = enum_SomeEnum.A;
1128 \\ {1185 \\pub const B = enum_SomeEnum.B;
1129 \\ const _tmp = i;1186 \\pub const C = enum_SomeEnum.C;
1130 \\ if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) {1187 \\pub const enum_SomeEnum = extern enum {
1131 \\ return 0;1188 \\ A,
1132 \\ } else {1189 \\ B,
1133 \\ return 1;1190 \\ C,
1134 \\ };1191 \\};
1135 \\ };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;
1136 \\}1223 \\}
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 \\}
1137 );1273 );
1138}1274}