diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 2 | ||||
| -rw-r--r-- | src/analyze.cpp | 38 | ||||
| -rw-r--r-- | src/codegen.cpp | 25 | ||||
| -rw-r--r-- | src/eval.cpp | 1 | ||||
| -rw-r--r-- | src/parser.cpp | 2 | ||||
| -rw-r--r-- | src/zig_llvm.hpp | 1 |
6 files changed, 61 insertions, 8 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index b94188bdbd..60ce641de4 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -387,6 +387,7 @@ enum CastOp { CastOpBoolToInt, CastOpResizeSlice, CastOpIntToEnum, + CastOpBytesToSlice, }; struct AstNodeFnCallExpr { @@ -1311,6 +1312,7 @@ struct VariableTableEntry { int gen_arg_index; BlockContext *block_context; LLVMValueRef param_value_ref; + bool force_depends_on_compile_var; }; struct ErrorTableEntry { diff --git a/src/analyze.cpp b/src/analyze.cpp index f9b85c3fff..d736498eab 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3038,7 +3038,7 @@ static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, Variabl ConstExprValue *other_const_val = &get_resolved_expr(var->val_node)->const_val; if (other_const_val->ok) { return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node, - depends_on_compile_var); + depends_on_compile_var || var->force_depends_on_compile_var); } } return var->type; @@ -3959,12 +3959,12 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, { assert(node->type == NodeTypeWhileExpr); - AstNode *condition_node = node->data.while_expr.condition; + AstNode **condition_node = &node->data.while_expr.condition; AstNode *while_body_node = node->data.while_expr.body; AstNode **continue_expr_node = &node->data.while_expr.continue_expr; TypeTableEntry *condition_type = analyze_expression(g, import, context, - g->builtin_types.entry_bool, condition_node); + g->builtin_types.entry_bool, *condition_node); if (*continue_expr_node) { analyze_expression(g, import, context, g->builtin_types.entry_void, *continue_expr_node); @@ -3983,7 +3983,7 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, } else { // if the condition is a simple constant expression and there are no break statements // then the return type is unreachable - ConstExprValue *const_val = &get_resolved_expr(condition_node)->const_val; + ConstExprValue *const_val = &get_resolved_expr(*condition_node)->const_val; if (const_val->ok) { if (const_val->data.x_bool) { node->data.while_expr.condition_always_true = true; @@ -4392,6 +4392,24 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B return resolve_cast(g, context, node, expr_node, wanted_type, CastOpResizeSlice, true); } + // explicit cast from [N]u8 to []T + if (is_slice(wanted_type) && + actual_type->id == TypeTableEntryIdArray && + is_u8(actual_type->data.array.child_type)) + { + mark_impure_fn(context); + uint64_t child_type_size = type_size(g, + wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type); + if (actual_type->data.array.len % child_type_size == 0) { + return resolve_cast(g, context, node, expr_node, wanted_type, CastOpBytesToSlice, true); + } else { + add_node_error(g, node, + buf_sprintf("unable to convert %s to %s: size mismatch", + buf_ptr(&actual_type->name), buf_ptr(&wanted_type->name))); + return g->builtin_types.entry_invalid; + } + } + // explicit cast from pointer to another pointer if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) && (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn)) @@ -5062,8 +5080,10 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry return g->builtin_types.entry_invalid; } else { uint64_t size_in_bytes = type_size(g, type_entry); + bool depends_on_compile_var = (type_entry == g->builtin_types.entry_usize || + type_entry == g->builtin_types.entry_isize); return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, - size_in_bytes, false); + size_in_bytes, depends_on_compile_var); } } case BuiltinFnIdAlignof: @@ -5461,8 +5481,11 @@ static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableE ConstExprValue *const_val = &get_resolved_expr(*param_node)->const_val; if (const_val->ok) { - add_local_var(g, generic_param_decl_node, decl_node->owner, child_context, + VariableTableEntry *var = add_local_var(g, generic_param_decl_node, decl_node->owner, child_context, &generic_param_decl_node->data.param_decl.name, param_type, true, *param_node); + // This generic function instance could be called with anything, so when this variable is read it + // needs to know that it depends on compile time variable data. + var->force_depends_on_compile_var = true; } else { add_node_error(g, *param_node, buf_sprintf("unable to evaluate constant expression for inline parameter")); @@ -5552,8 +5575,9 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp ConstExprValue *const_val = &get_resolved_expr(*param_node)->const_val; if (const_val->ok) { - add_local_var(g, generic_param_decl_node, decl_node->owner, child_context, + VariableTableEntry *var = add_local_var(g, generic_param_decl_node, decl_node->owner, child_context, &generic_param_decl_node->data.param_decl.name, param_type, true, *param_node); + var->force_depends_on_compile_var = true; } else { add_node_error(g, *param_node, buf_sprintf("unable to evaluate constant expression")); diff --git a/src/codegen.cpp b/src/codegen.cpp index d33c10116a..59ce94e02e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1007,6 +1007,31 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { return cast_expr->tmp_ptr; } + case CastOpBytesToSlice: + { + assert(cast_expr->tmp_ptr); + assert(wanted_type->id == TypeTableEntryIdStruct); + assert(wanted_type->data.structure.is_slice); + assert(actual_type->id == TypeTableEntryIdArray); + + TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; + TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; + + set_debug_source_node(g, node); + + int wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index; + LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, wanted_ptr_index, ""); + LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, ""); + LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr); + + int wanted_len_index = wanted_type->data.structure.fields[1].gen_index; + LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, wanted_len_index, ""); + LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, + actual_type->data.array.len / type_size(g, wanted_child_type), false); + LLVMBuildStore(g->builder, len_val, len_ptr); + + return cast_expr->tmp_ptr; + } case CastOpIntToFloat: assert(actual_type->id == TypeTableEntryIdInt); if (actual_type->data.integral.is_signed) { diff --git a/src/eval.cpp b/src/eval.cpp index 321a5d667f..e8ebc110ac 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -601,6 +601,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op, case CastOpPtrToInt: case CastOpIntToPtr: case CastOpResizeSlice: + case CastOpBytesToSlice: // can't do it break; case CastOpToUnknownSizeArray: diff --git a/src/parser.cpp b/src/parser.cpp index 418a9d210f..6ff43217c0 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3301,6 +3301,8 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index, case NodeTypeWhileExpr: clone_subtree_field(&new_node->data.while_expr.condition, old_node->data.while_expr.condition, next_node_index); clone_subtree_field(&new_node->data.while_expr.body, old_node->data.while_expr.body, next_node_index); + clone_subtree_field(&new_node->data.while_expr.continue_expr, + old_node->data.while_expr.continue_expr, next_node_index); break; case NodeTypeForExpr: clone_subtree_field(&new_node->data.for_expr.elem_node, old_node->data.for_expr.elem_node, next_node_index); diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp index 444081ce98..77b8fdaa67 100644 --- a/src/zig_llvm.hpp +++ b/src/zig_llvm.hpp @@ -145,7 +145,6 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD LLVMZigDIType *fn_di_type, bool is_local_to_unit, bool is_definition, unsigned scope_line, unsigned flags, bool is_optimized, LLVMZigDISubprogram *decl_subprogram); - void ZigLLVMFnSetSubprogram(LLVMValueRef fn, LLVMZigDISubprogram *subprogram); void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder); |
