aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp2
-rw-r--r--src/analyze.cpp38
-rw-r--r--src/codegen.cpp25
-rw-r--r--src/eval.cpp1
-rw-r--r--src/parser.cpp2
-rw-r--r--src/zig_llvm.hpp1
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);