Commit f8fe517d12
Changed files (8)
src/all_types.hpp
@@ -130,14 +130,18 @@ struct ConstUnionValue {
enum ConstArraySpecial {
ConstArraySpecialNone,
ConstArraySpecialUndef,
+ ConstArraySpecialBuf,
};
struct ConstArrayValue {
ConstArraySpecial special;
- struct {
- ConstExprValue *elements;
- ConstParent parent;
- } s_none;
+ union {
+ struct {
+ ConstExprValue *elements;
+ ConstParent parent;
+ } s_none;
+ Buf *s_buf;
+ } data;
};
enum ConstPtrSpecial {
@@ -983,6 +987,7 @@ struct FnTypeParamInfo {
};
struct GenericFnTypeId {
+ CodeGen *codegen;
ZigFn *fn_entry;
ConstExprValue *params;
size_t param_count;
@@ -1291,6 +1296,7 @@ struct FnExport {
};
struct ZigFn {
+ CodeGen *codegen;
LLVMValueRef llvm_value;
const char *llvm_name;
AstNode *proto_node;
@@ -1848,13 +1854,14 @@ enum ScopeId {
};
struct Scope {
- ScopeId id;
+ CodeGen *codegen;
AstNode *source_node;
// if the scope has a parent, this is it
Scope *parent;
ZigLLVMDIScope *di_scope;
+ ScopeId id;
};
// This scope comes from global declarations or from
src/analyze.cpp
@@ -92,62 +92,63 @@ ScopeDecls *get_container_scope(ZigType *type_entry) {
return *get_container_scope_ptr(type_entry);
}
-void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
+void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
+ dest->codegen = g;
dest->id = id;
dest->source_node = source_node;
dest->parent = parent;
}
-ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) {
+ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) {
assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
ScopeDecls *scope = allocate<ScopeDecls>(1);
- init_scope(&scope->base, ScopeIdDecls, node, parent);
+ init_scope(g, &scope->base, ScopeIdDecls, node, parent);
scope->decl_table.init(4);
scope->container_type = container_type;
scope->import = import;
return scope;
}
-ScopeBlock *create_block_scope(AstNode *node, Scope *parent) {
+ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) {
assert(node->type == NodeTypeBlock);
ScopeBlock *scope = allocate<ScopeBlock>(1);
- init_scope(&scope->base, ScopeIdBlock, node, parent);
+ init_scope(g, &scope->base, ScopeIdBlock, node, parent);
scope->name = node->data.block.name;
return scope;
}
-ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) {
+ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) {
assert(node->type == NodeTypeDefer);
ScopeDefer *scope = allocate<ScopeDefer>(1);
- init_scope(&scope->base, ScopeIdDefer, node, parent);
+ init_scope(g, &scope->base, ScopeIdDefer, node, parent);
return scope;
}
-ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) {
+ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) {
assert(node->type == NodeTypeDefer);
ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);
- init_scope(&scope->base, ScopeIdDeferExpr, node, parent);
+ init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent);
return scope;
}
-Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var) {
+Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) {
ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
- init_scope(&scope->base, ScopeIdVarDecl, node, parent);
+ init_scope(g, &scope->base, ScopeIdVarDecl, node, parent);
scope->var = var;
return &scope->base;
}
-ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) {
+ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) {
assert(node->type == NodeTypeFnCallExpr);
ScopeCImport *scope = allocate<ScopeCImport>(1);
- init_scope(&scope->base, ScopeIdCImport, node, parent);
+ init_scope(g, &scope->base, ScopeIdCImport, node, parent);
buf_resize(&scope->buf, 0);
return scope;
}
-ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {
+ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
ScopeLoop *scope = allocate<ScopeLoop>(1);
- init_scope(&scope->base, ScopeIdLoop, node, parent);
+ init_scope(g, &scope->base, ScopeIdLoop, node, parent);
if (node->type == NodeTypeWhileExpr) {
scope->name = node->data.while_expr.name;
} else if (node->type == NodeTypeForExpr) {
@@ -158,37 +159,37 @@ ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {
return scope;
}
-Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime) {
+Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) {
ScopeRuntime *scope = allocate<ScopeRuntime>(1);
scope->is_comptime = is_comptime;
- init_scope(&scope->base, ScopeIdRuntime, node, parent);
+ init_scope(g, &scope->base, ScopeIdRuntime, node, parent);
return &scope->base;
}
-ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) {
+ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
assert(node->type == NodeTypeSuspend);
ScopeSuspend *scope = allocate<ScopeSuspend>(1);
- init_scope(&scope->base, ScopeIdSuspend, node, parent);
+ init_scope(g, &scope->base, ScopeIdSuspend, node, parent);
return scope;
}
-ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry) {
+ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) {
ScopeFnDef *scope = allocate<ScopeFnDef>(1);
- init_scope(&scope->base, ScopeIdFnDef, node, parent);
+ init_scope(g, &scope->base, ScopeIdFnDef, node, parent);
scope->fn_entry = fn_entry;
return scope;
}
-Scope *create_comptime_scope(AstNode *node, Scope *parent) {
+Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr);
ScopeCompTime *scope = allocate<ScopeCompTime>(1);
- init_scope(&scope->base, ScopeIdCompTime, node, parent);
+ init_scope(g, &scope->base, ScopeIdCompTime, node, parent);
return &scope->base;
}
-Scope *create_coro_prelude_scope(AstNode *node, Scope *parent) {
+Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) {
ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1);
- init_scope(&scope->base, ScopeIdCoroPrelude, node, parent);
+ init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent);
return &scope->base;
}
@@ -204,9 +205,9 @@ ImportTableEntry *get_scope_import(Scope *scope) {
zig_unreachable();
}
-static ZigType *new_container_type_entry(ZigTypeId id, AstNode *source_node, Scope *parent_scope) {
+static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *source_node, Scope *parent_scope) {
ZigType *entry = new_type_table_entry(id);
- *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope));
+ *get_container_scope_ptr(entry) = create_decls_scope(g, source_node, parent_scope, entry, get_scope_import(parent_scope));
return entry;
}
@@ -1245,7 +1246,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
AstNode *decl_node, const char *name, ContainerLayout layout)
{
ZigTypeId type_id = container_to_type(kind);
- ZigType *entry = new_container_type_entry(type_id, decl_node, scope);
+ ZigType *entry = new_container_type_entry(g, type_id, decl_node, scope);
switch (kind) {
case ContainerKindStruct:
@@ -1372,13 +1373,17 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
+ if (array_val->data.x_array.special == ConstArraySpecialBuf) {
+ *out_buffer = array_val->data.x_array.data.s_buf;
+ return true;
+ }
expand_undef_array(g, array_val);
size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
Buf *result = buf_alloc();
buf_resize(result, len);
for (size_t i = 0; i < len; i += 1) {
size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
- ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];
+ ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
if (char_val->special == ConstValSpecialUndef) {
add_node_error(g, node, buf_sprintf("use of undefined value"));
return false;
@@ -3093,9 +3098,10 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {
buf_append_buf(buf, tld->name);
}
-ZigFn *create_fn_raw(FnInline inline_value) {
+ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
ZigFn *fn_entry = allocate<ZigFn>(1);
+ fn_entry->codegen = g;
fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
fn_entry->analyzed_executable.fn_entry = fn_entry;
@@ -3105,12 +3111,12 @@ ZigFn *create_fn_raw(FnInline inline_value) {
return fn_entry;
}
-ZigFn *create_fn(AstNode *proto_node) {
+ZigFn *create_fn(CodeGen *g, AstNode *proto_node) {
assert(proto_node->type == NodeTypeFnProto);
AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
- ZigFn *fn_entry = create_fn_raw(inline_value);
+ ZigFn *fn_entry = create_fn_raw(g, inline_value);
fn_entry->proto_node = proto_node;
fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
@@ -3209,7 +3215,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
AstNode *fn_def_node = fn_proto->fn_def_node;
- ZigFn *fn_table_entry = create_fn(source_node);
+ ZigFn *fn_table_entry = create_fn(g, source_node);
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
if (fn_proto->is_export) {
@@ -3220,7 +3226,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
tld_fn->fn_entry = fn_table_entry;
if (fn_table_entry->body_node) {
- fn_table_entry->fndef_scope = create_fndef_scope(
+ fn_table_entry->fndef_scope = create_fndef_scope(g,
fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
for (size_t i = 0; i < fn_proto->params.length; i += 1) {
@@ -3270,14 +3276,14 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
}
}
} else if (source_node->type == NodeTypeTestDecl) {
- ZigFn *fn_table_entry = create_fn_raw(FnInlineAuto);
+ ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto);
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
tld_fn->fn_entry = fn_table_entry;
fn_table_entry->proto_node = source_node;
- fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry);
+ fn_table_entry->fndef_scope = create_fndef_scope(g, source_node, tld_fn->base.parent_scope, fn_table_entry);
fn_table_entry->type_entry = get_test_fn_type(g);
fn_table_entry->body_node = source_node->data.test_decl.body;
fn_table_entry->is_test = true;
@@ -3606,7 +3612,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
Scope *child_scope;
if (source_node && source_node->type == NodeTypeParamDecl) {
- child_scope = create_var_scope(source_node, parent_scope, variable_entry);
+ child_scope = create_var_scope(g, source_node, parent_scope, variable_entry);
} else {
// it's already in the decls table
child_scope = parent_scope;
@@ -4329,7 +4335,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r
g->import_table.put(resolved_path, import_entry);
g->import_queue.append(import_entry);
- import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry);
+ import_entry->decls_scope = create_decls_scope(g, import_entry->root, nullptr, nullptr, import_entry);
assert(import_entry->root->type == NodeTypeRoot);
@@ -4880,7 +4886,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) {
assert(a_val->special == ConstValSpecialStatic);
assert(b_val->special == ConstValSpecialStatic);
- if (!const_values_equal(a_val, b_val)) {
+ if (!const_values_equal(a->fn_entry->codegen, a_val, b_val)) {
return false;
}
} else {
@@ -4920,14 +4926,18 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
case ZigTypeIdArray:
if (value->type->data.array.len == 0)
return false;
- if (value->data.x_array.special == ConstArraySpecialUndef)
- return false;
- for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {
- if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i]))
- return true;
+ switch (value->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ case ConstArraySpecialBuf:
+ return false;
+ case ConstArraySpecialNone:
+ for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {
+ if (can_mutate_comptime_var_state(&value->data.x_array.data.s_none.elements[i]))
+ return true;
+ }
+ return false;
}
- return false;
-
+ zig_unreachable();
case ZigTypeIdStruct:
for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {
if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))
@@ -5039,6 +5049,8 @@ uint32_t fn_eval_hash(Scope* scope) {
}
bool fn_eval_eql(Scope *a, Scope *b) {
+ assert(a->codegen != nullptr);
+ assert(b->codegen != nullptr);
while (a && b) {
if (a->id != b->id)
return false;
@@ -5048,7 +5060,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;
if (a_var_scope->var->value->type != b_var_scope->var->value->type)
return false;
- if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value))
+ if (!const_values_equal(a->codegen, a_var_scope->var->value, b_var_scope->var->value))
return false;
} else if (a->id == ScopeIdFnDef) {
ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;
@@ -5130,14 +5142,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
const_val->special = ConstValSpecialStatic;
const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
- const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));
-
- for (size_t i = 0; i < buf_len(str); i += 1) {
- ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];
- this_char->special = ConstValSpecialStatic;
- this_char->type = g->builtin_types.entry_u8;
- bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
- }
+ const_val->data.x_array.special = ConstArraySpecialBuf;
+ const_val->data.x_array.data.s_buf = str;
g->string_literals_table.put(str, const_val);
}
@@ -5154,14 +5160,15 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
ConstExprValue *array_val = create_const_vals(1);
array_val->special = ConstValSpecialStatic;
array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
- array_val->data.x_array.s_none.elements = create_const_vals(len_with_null);
+ // TODO buf optimization
+ array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null);
for (size_t i = 0; i < buf_len(str); i += 1) {
- ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];
+ ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i];
this_char->special = ConstValSpecialStatic;
this_char->type = g->builtin_types.entry_u8;
bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
}
- ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1];
+ ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1];
null_char->special = ConstValSpecialStatic;
null_char->type = g->builtin_types.entry_u8;
bigint_init_unsigned(&null_char->data.x_bigint, 0);
@@ -5535,7 +5542,7 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
zig_unreachable();
}
-bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
+bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
assert(a->type->id == b->type->id);
assert(a->special == ConstValSpecialStatic);
assert(b->special == ConstValSpecialStatic);
@@ -5593,13 +5600,20 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
assert(a->type->data.array.len == b->type->data.array.len);
assert(a->data.x_array.special != ConstArraySpecialUndef);
assert(b->data.x_array.special != ConstArraySpecialUndef);
+ if (a->data.x_array.special == ConstArraySpecialBuf &&
+ b->data.x_array.special == ConstArraySpecialBuf)
+ {
+ return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
+ }
+ expand_undef_array(g, a);
+ expand_undef_array(g, b);
size_t len = a->type->data.array.len;
- ConstExprValue *a_elems = a->data.x_array.s_none.elements;
- ConstExprValue *b_elems = b->data.x_array.s_none.elements;
+ ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
+ ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
for (size_t i = 0; i < len; ++i) {
- if (!const_values_equal(&a_elems[i], &b_elems[i]))
+ if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
return false;
}
@@ -5609,7 +5623,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
ConstExprValue *field_a = &a->data.x_struct.fields[i];
ConstExprValue *field_b = &b->data.x_struct.fields[i];
- if (!const_values_equal(field_a, field_b))
+ if (!const_values_equal(g, field_a, field_b))
return false;
}
return true;
@@ -5623,7 +5637,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) {
return (a->data.x_optional == nullptr && b->data.x_optional == nullptr);
} else {
- return const_values_equal(a->data.x_optional, b->data.x_optional);
+ return const_values_equal(g, a->data.x_optional, b->data.x_optional);
}
case ZigTypeIdErrorUnion:
zig_panic("TODO");
@@ -5808,26 +5822,15 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
case ZigTypeIdPointer:
return render_const_val_ptr(g, buf, const_val, type_entry);
case ZigTypeIdArray:
- {
- ZigType *child_type = type_entry->data.array.child_type;
- uint64_t len = type_entry->data.array.len;
-
- if (const_val->data.x_array.special == ConstArraySpecialUndef) {
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialUndef:
buf_append_str(buf, "undefined");
return;
- }
-
- // if it's []u8, assume UTF-8 and output a string
- if (child_type->id == ZigTypeIdInt &&
- child_type->data.integral.bit_count == 8 &&
- !child_type->data.integral.is_signed)
- {
+ case ConstArraySpecialBuf: {
+ Buf *array_buf = const_val->data.x_array.data.s_buf;
buf_append_char(buf, '"');
- for (uint64_t i = 0; i < len; i += 1) {
- ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
- uint64_t big_c = bigint_as_unsigned(&child_value->data.x_bigint);
- assert(big_c <= UINT8_MAX);
- uint8_t c = (uint8_t)big_c;
+ for (size_t i = 0; i < buf_len(array_buf); i += 1) {
+ uint8_t c = buf_ptr(array_buf)[i];
if (c == '"') {
buf_append_str(buf, "\\\"");
} else {
@@ -5837,17 +5840,20 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
buf_append_char(buf, '"');
return;
}
-
- buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
- for (uint64_t i = 0; i < len; i += 1) {
- if (i != 0)
- buf_appendf(buf, ",");
- ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
- render_const_value(g, buf, child_value);
+ case ConstArraySpecialNone: {
+ buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
+ uint64_t len = type_entry->data.array.len;
+ for (uint64_t i = 0; i < len; i += 1) {
+ if (i != 0)
+ buf_appendf(buf, ",");
+ ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
+ render_const_value(g, buf, child_value);
+ }
+ buf_appendf(buf, "}");
+ return;
}
- buf_appendf(buf, "}");
- return;
}
+ zig_unreachable();
case ZigTypeIdNull:
{
buf_appendf(buf, "null");
@@ -6102,24 +6108,49 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
zig_unreachable();
}
+// Canonicalize the array value as ConstArraySpecialNone
void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
assert(const_val->type->id == ZigTypeIdArray);
- if (const_val->data.x_array.special == ConstArraySpecialUndef) {
- const_val->data.x_array.special = ConstArraySpecialNone;
- size_t elem_count = const_val->type->data.array.len;
- const_val->data.x_array.s_none.elements = create_const_vals(elem_count);
- for (size_t i = 0; i < elem_count; i += 1) {
- ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];
- element_val->type = const_val->type->data.array.child_type;
- init_const_undefined(g, element_val);
- ConstParent *parent = get_const_val_parent(g, element_val);
- if (parent != nullptr) {
- parent->id = ConstParentIdArray;
- parent->data.p_array.array_val = const_val;
- parent->data.p_array.elem_index = i;
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialNone:
+ return;
+ case ConstArraySpecialUndef: {
+ const_val->data.x_array.special = ConstArraySpecialNone;
+ size_t elem_count = const_val->type->data.array.len;
+ const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
+ for (size_t i = 0; i < elem_count; i += 1) {
+ ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
+ element_val->type = const_val->type->data.array.child_type;
+ init_const_undefined(g, element_val);
+ ConstParent *parent = get_const_val_parent(g, element_val);
+ if (parent != nullptr) {
+ parent->id = ConstParentIdArray;
+ parent->data.p_array.array_val = const_val;
+ parent->data.p_array.elem_index = i;
+ }
}
+ return;
+ }
+ case ConstArraySpecialBuf: {
+ Buf *buf = const_val->data.x_array.data.s_buf;
+ // If we're doing this it means that we are potentially modifying the data,
+ // so we can't have it be in the string literals table
+ g->string_literals_table.maybe_remove(buf);
+
+ const_val->data.x_array.special = ConstArraySpecialNone;
+ size_t elem_count = const_val->type->data.array.len;
+ assert(elem_count == buf_len(buf));
+ const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
+ for (size_t i = 0; i < elem_count; i += 1) {
+ ConstExprValue *this_char = &const_val->data.x_array.data.s_none.elements[i];
+ this_char->special = ConstValSpecialStatic;
+ this_char->type = g->builtin_types.entry_u8;
+ bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]);
+ }
+ return;
}
}
+ zig_unreachable();
}
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
@@ -6127,7 +6158,7 @@ ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
ZigType *type_entry = value->type;
if (type_entry->id == ZigTypeIdArray) {
expand_undef_array(g, value);
- return &value->data.x_array.s_none.parent;
+ return &value->data.x_array.data.s_none.parent;
} else if (type_entry->id == ZigTypeIdStruct) {
return &value->data.x_struct.parent;
} else if (type_entry->id == ZigTypeIdUnion) {
src/analyze.hpp
@@ -84,8 +84,8 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source
ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
bool is_const, ConstExprValue *init_value, Tld *src_tld);
ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);
-ZigFn *create_fn(AstNode *proto_node);
-ZigFn *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage);
+ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
+ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);
void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
bool type_requires_comptime(ZigType *type_entry);
@@ -93,25 +93,25 @@ Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);
Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
void complete_enum(CodeGen *g, ZigType *enum_type);
bool ir_get_var_is_comptime(ZigVar *var);
-bool const_values_equal(ConstExprValue *a, ConstExprValue *b);
+bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b);
void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max);
void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max);
void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val);
void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node);
-ScopeBlock *create_block_scope(AstNode *node, Scope *parent);
-ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);
-ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent);
-Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var);
-ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);
-ScopeLoop *create_loop_scope(AstNode *node, Scope *parent);
-ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent);
-ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry);
-ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import);
-Scope *create_comptime_scope(AstNode *node, Scope *parent);
-Scope *create_coro_prelude_scope(AstNode *node, Scope *parent);
-Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime);
+ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent);
+ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent);
+ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
+Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var);
+ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent);
+ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
+ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
+ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
+ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import);
+Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
+Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);
+Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);
src/codegen.cpp
@@ -5336,7 +5336,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
expand_undef_array(g, array_const_val);
- ConstParent *parent = &array_const_val->data.x_array.s_none.parent;
+ ConstParent *parent = &array_const_val->data.x_array.data.s_none.parent;
LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
@@ -5716,23 +5716,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
case ZigTypeIdArray:
{
uint64_t len = type_entry->data.array.len;
- if (const_val->data.x_array.special == ConstArraySpecialUndef) {
- return LLVMGetUndef(type_entry->type_ref);
- }
-
- LLVMValueRef *values = allocate<LLVMValueRef>(len);
- LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
- bool make_unnamed_struct = false;
- for (uint64_t i = 0; i < len; i += 1) {
- ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
- LLVMValueRef val = gen_const_val(g, elem_value, "");
- values[i] = val;
- make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
- }
- if (make_unnamed_struct) {
- return LLVMConstStruct(values, len, true);
- } else {
- return LLVMConstArray(element_type_ref, values, (unsigned)len);
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ return LLVMGetUndef(type_entry->type_ref);
+ case ConstArraySpecialNone: {
+ LLVMValueRef *values = allocate<LLVMValueRef>(len);
+ LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
+ bool make_unnamed_struct = false;
+ for (uint64_t i = 0; i < len; i += 1) {
+ ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
+ LLVMValueRef val = gen_const_val(g, elem_value, "");
+ values[i] = val;
+ make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
+ }
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(values, len, true);
+ } else {
+ return LLVMConstArray(element_type_ref, values, (unsigned)len);
+ }
+ }
+ case ConstArraySpecialBuf: {
+ Buf *buf = const_val->data.x_array.data.s_buf;
+ return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
+ }
}
}
case ZigTypeIdUnion:
@@ -7278,7 +7284,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
import->source_code = nullptr;
import->path = full_path;
g->root_import = import;
- import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import);
+ import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);
init(g);
@@ -7352,12 +7358,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
ConstExprValue *test_fn_array = create_const_vals(1);
test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);
test_fn_array->special = ConstValSpecialStatic;
- test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length);
+ test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length);
for (size_t i = 0; i < g->test_fns.length; i += 1) {
ZigFn *test_fn_entry = g->test_fns.at(i);
- ConstExprValue *this_val = &test_fn_array->data.x_array.s_none.elements[i];
+ ConstExprValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i];
this_val->special = ConstValSpecialStatic;
this_val->type = struct_type;
this_val->data.x_struct.parent.id = ConstParentIdArray;
src/ir.cpp
@@ -166,7 +166,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
break;
case ConstPtrSpecialBaseArray:
expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val);
- result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[
+ result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.data.s_none.elements[
const_val->data.x_ptr.data.base_array.elem_index];
break;
case ConstPtrSpecialBaseStruct:
@@ -3360,7 +3360,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
variable_entry->src_is_const = src_is_const;
variable_entry->gen_is_const = gen_is_const;
variable_entry->decl_node = node;
- variable_entry->child_scope = create_var_scope(node, parent_scope, variable_entry);
+ variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry);
return variable_entry;
}
@@ -3388,7 +3388,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
ZigList<IrInstruction *> incoming_values = {0};
ZigList<IrBasicBlock *> incoming_blocks = {0};
- ScopeBlock *scope_block = create_block_scope(block_node, parent_scope);
+ ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
Scope *outer_block_scope = &scope_block->base;
Scope *child_scope = outer_block_scope;
@@ -5026,7 +5026,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
ir_set_cursor_at_end_and_append_block(irb, then_block);
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope);
if (then_expr_result == irb->codegen->invalid_instruction)
return then_expr_result;
@@ -5318,7 +5318,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline);
ir_build_br(irb, scope, node, cond_block, is_comptime);
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
Buf *var_symbol = node->data.while_expr.var_symbol;
Buf *err_symbol = node->data.while_expr.err_symbol;
if (err_symbol != nullptr) {
@@ -5359,7 +5359,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
ZigList<IrInstruction *> incoming_values = {0};
ZigList<IrBasicBlock *> incoming_blocks = {0};
- ScopeLoop *loop_scope = create_loop_scope(node, payload_scope);
+ ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
loop_scope->break_block = end_block;
loop_scope->continue_block = continue_block;
loop_scope->is_comptime = is_comptime;
@@ -5415,7 +5415,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
} else if (var_symbol != nullptr) {
ir_set_cursor_at_end_and_append_block(irb, cond_block);
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
// TODO make it an error to write to payload variable
AstNode *symbol_node = node; // TODO make more accurate
@@ -5443,7 +5443,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
ZigList<IrInstruction *> incoming_values = {0};
ZigList<IrBasicBlock *> incoming_blocks = {0};
- ScopeLoop *loop_scope = create_loop_scope(node, child_scope);
+ ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
loop_scope->break_block = end_block;
loop_scope->continue_block = continue_block;
loop_scope->is_comptime = is_comptime;
@@ -5506,9 +5506,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
ZigList<IrInstruction *> incoming_values = {0};
ZigList<IrBasicBlock *> incoming_blocks = {0};
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
- ScopeLoop *loop_scope = create_loop_scope(node, subexpr_scope);
+ ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
loop_scope->break_block = end_block;
loop_scope->continue_block = continue_block;
loop_scope->is_comptime = is_comptime;
@@ -5645,7 +5645,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
ZigList<IrInstruction *> incoming_values = {0};
ZigList<IrBasicBlock *> incoming_blocks = {0};
- ScopeLoop *loop_scope = create_loop_scope(node, child_scope);
+ ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
loop_scope->break_block = end_block;
loop_scope->continue_block = continue_block;
loop_scope->is_comptime = is_comptime;
@@ -5855,7 +5855,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
ir_set_cursor_at_end_and_append_block(irb, then_block);
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
Scope *var_scope;
if (var_symbol) {
IrInstruction *var_type = nullptr;
@@ -5930,7 +5930,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
ir_set_cursor_at_end_and_append_block(irb, ok_block);
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
Scope *var_scope;
if (var_symbol) {
IrInstruction *var_type = nullptr;
@@ -6066,8 +6066,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0};
// First do the else and the ranges
- Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
- Scope *comptime_scope = create_comptime_scope(node, scope);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
+ Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
AstNode *else_prong = nullptr;
for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
@@ -6231,7 +6231,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
assert(node->type == NodeTypeCompTime);
- Scope *child_scope = create_comptime_scope(node, parent_scope);
+ Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);
}
@@ -6394,10 +6394,10 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n
static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
assert(node->type == NodeTypeDefer);
- ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope);
+ ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope);
node->data.defer.child_scope = &defer_child_scope->base;
- ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope);
+ ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope);
node->data.defer.expr_scope = &defer_expr_scope->base;
return ir_build_const_void(irb, parent_scope, node);
@@ -7154,7 +7154,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);
} else {
Scope *child_scope;
- ScopeSuspend *suspend_scope = create_suspend_scope(node, parent_scope);
+ ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
suspend_scope->resume_block = resume_block;
child_scope = &suspend_scope->base;
IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle);
@@ -7370,7 +7370,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
ZigVar *coro_size_var;
if (is_async) {
// create the coro promise
- Scope *coro_scope = create_coro_prelude_scope(node, scope);
+ Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope);
const_bool_false = ir_build_const_bool(irb, coro_scope, node, false);
ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
@@ -10569,9 +10569,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou
array_val->special = ConstValSpecialStatic;
array_val->type = array_type;
array_val->data.x_array.special = ConstArraySpecialNone;
- array_val->data.x_array.s_none.elements = pointee;
- array_val->data.x_array.s_none.parent.id = ConstParentIdScalar;
- array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee;
+ array_val->data.x_array.data.s_none.elements = pointee;
+ array_val->data.x_array.data.s_none.parent.id = ConstParentIdScalar;
+ array_val->data.x_array.data.s_none.parent.data.p_scalar.scalar_val = pointee;
IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
source_instr->scope, source_instr->source_node);
@@ -11391,13 +11391,16 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
+ if (array_val->data.x_array.special == ConstArraySpecialBuf) {
+ return array_val->data.x_array.data.s_buf;
+ }
expand_undef_array(ira->codegen, array_val);
size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
Buf *result = buf_alloc();
buf_resize(result, len);
for (size_t i = 0; i < len; i += 1) {
size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
- ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];
+ ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
if (char_val->special == ConstValSpecialUndef) {
ir_add_error(ira, casted_value, buf_sprintf("use of undefined value"));
return nullptr;
@@ -11750,7 +11753,7 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op
Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
answer = resolve_cmp_op_id(op_id, cmp_result);
} else {
- bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val);
+ bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val);
if (op_id == IrBinOpCmpEq) {
answer = are_equal;
} else if (op_id == IrBinOpCmpNotEq) {
@@ -12463,19 +12466,20 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc
return result_type;
}
- out_array_val->data.x_array.s_none.elements = create_const_vals(new_len);
+ out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len);
+ // TODO handle the buf case here for an optimization
expand_undef_array(ira->codegen, op1_array_val);
expand_undef_array(ira->codegen, op2_array_val);
size_t next_index = 0;
for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
- out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i];
+ out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i];
}
for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
- out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i];
+ out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i];
}
if (next_index < new_len) {
- ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index];
+ ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index];
init_const_unsigned_negative(null_byte, child_type, 0, false);
next_index += 1;
}
@@ -12524,12 +12528,14 @@ static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instru
return get_array_type(ira->codegen, child_type, new_array_len);
}
- out_val->data.x_array.s_none.elements = create_const_vals(new_array_len);
+ // TODO optimize the buf case
+ expand_undef_array(ira->codegen, array_val);
+ out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len);
uint64_t i = 0;
for (uint64_t x = 0; x < mult_amt; x += 1) {
for (uint64_t y = 0; y < old_array_len; y += 1) {
- out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y];
+ out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y];
i += 1;
}
}
@@ -13502,10 +13508,10 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr
// Fork a scope of the function with known values for the parameters.
Scope *parent_scope = fn_entry->fndef_scope->base.parent;
- ZigFn *impl_fn = create_fn(fn_proto_node);
+ ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node);
impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count);
buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
- impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn);
+ impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
impl_fn->child_scope = &impl_fn->fndef_scope->base;
FnTypeId inst_fn_type_id = {0};
init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);
@@ -16073,7 +16079,7 @@ static ZigType *ir_analyze_instruction_switch_br(IrAnalyze *ira,
if (!case_val)
return ir_unreach_error(ira);
- if (const_values_equal(target_val, case_val)) {
+ if (const_values_equal(ira->codegen, target_val, case_val)) {
old_dest_block = old_case->block;
break;
}
@@ -16652,7 +16658,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
ConstExprValue const_val = {};
const_val.special = ConstValSpecialStatic;
const_val.type = fixed_size_array_type;
- const_val.data.x_array.s_none.elements = create_const_vals(elem_count);
+ const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);
bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
@@ -16677,7 +16683,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
if (!elem_val)
return ira->codegen->builtin_types.entry_invalid;
- copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true);
+ copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true);
} else {
first_non_const_instruction = casted_arg;
const_val.special = ConstValSpecialRuntime;
@@ -16689,7 +16695,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
*out_val = const_val;
for (size_t i = 0; i < elem_count; i += 1) {
- ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i];
+ ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i];
ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);
if (parent != nullptr) {
parent->id = ConstParentIdArray;
@@ -17146,8 +17152,8 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
definition_array->special = ConstValSpecialStatic;
definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);
definition_array->data.x_array.special = ConstArraySpecialNone;
- definition_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- definition_array->data.x_array.s_none.elements = create_const_vals(definition_count);
+ definition_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count);
init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);
// Loop through the definitions and generate info.
@@ -17164,7 +17170,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
continue;
}
- ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index];
+ ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index];
definition_val->special = ConstValSpecialStatic;
definition_val->type = type_info_definition_type;
@@ -17293,15 +17299,15 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
fn_arg_name_array->type = get_array_type(ira->codegen,
get_slice_type(ira->codegen, u8_ptr), fn_arg_count);
fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
- fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);
+ fn_arg_name_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
{
ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
- ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index];
+ ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index];
ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name);
init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true);
fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray;
@@ -17593,15 +17599,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
enum_field_array->special = ConstValSpecialStatic;
enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count);
enum_field_array->data.x_array.special = ConstArraySpecialNone;
- enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count);
+ enum_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);
init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false);
for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)
{
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index];
- ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index];
+ ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index];
make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type);
enum_field_val->data.x_struct.parent.id = ConstParentIdArray;
enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array;
@@ -17632,13 +17638,13 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
error_array->special = ConstValSpecialStatic;
error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count);
error_array->data.x_array.special = ConstArraySpecialNone;
- error_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- error_array->data.x_array.s_none.elements = create_const_vals(error_count);
+ error_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ error_array->data.x_array.data.s_none.elements = create_const_vals(error_count);
init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false);
for (uint32_t error_index = 0; error_index < error_count; error_index++) {
ErrorTableEntry *error = type_entry->data.error_set.errors[error_index];
- ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index];
+ ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index];
error_val->special = ConstValSpecialStatic;
error_val->type = type_info_error_type;
@@ -17727,8 +17733,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
union_field_array->special = ConstValSpecialStatic;
union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count);
union_field_array->data.x_array.special = ConstArraySpecialNone;
- union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count);
+ union_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);
init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false);
@@ -17736,7 +17742,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {
TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];
- ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index];
+ ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index];
union_field_val->special = ConstValSpecialStatic;
union_field_val->type = type_info_union_field_type;
@@ -17800,14 +17806,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
struct_field_array->special = ConstValSpecialStatic;
struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count);
struct_field_array->data.x_array.special = ConstArraySpecialNone;
- struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count);
+ struct_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);
init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false);
for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {
TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];
- ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index];
+ ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index];
struct_field_val->special = ConstValSpecialStatic;
struct_field_val->type = type_info_struct_field_type;
@@ -17906,15 +17912,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
fn_arg_array->special = ConstValSpecialStatic;
fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count);
fn_arg_array->data.x_array.special = ConstArraySpecialNone;
- fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone;
- fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);
+ fn_arg_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
+ fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false);
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
{
FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
- ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index];
+ ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index];
fn_arg_val->special = ConstValSpecialStatic;
fn_arg_val->type = type_info_fn_arg_type;
@@ -18059,7 +18065,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm
assert(node->type == NodeTypeFnCallExpr);
AstNode *block_node = node->data.fn_call_expr.params.at(0);
- ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope);
+ ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope);
// Execute the C import block like an inline function
ZigType *void_type = ira->codegen->builtin_types.entry_void;
@@ -18072,7 +18078,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm
find_libc_include_path(ira->codegen);
ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
- child_import->decls_scope = create_decls_scope(node, nullptr, nullptr, child_import);
+ child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);
child_import->c_import_node = node;
child_import->package = new_anonymous_package();
child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package);
@@ -18826,7 +18832,7 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse
{
ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
expand_undef_array(ira->codegen, array_val);
- dest_elements = array_val->data.x_array.s_none.elements;
+ dest_elements = array_val->data.x_array.data.s_none.elements;
start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
bound_end = array_val->type->data.array.len;
break;
@@ -18940,7 +18946,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
{
ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
expand_undef_array(ira->codegen, array_val);
- dest_elements = array_val->data.x_array.s_none.elements;
+ dest_elements = array_val->data.x_array.data.s_none.elements;
dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
dest_end = array_val->type->data.array.len;
break;
@@ -18976,7 +18982,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
{
ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;
expand_undef_array(ira->codegen, array_val);
- src_elements = array_val->data.x_array.s_none.elements;
+ src_elements = array_val->data.x_array.data.s_none.elements;
src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index;
src_end = array_val->type->data.array.len;
break;
@@ -20282,9 +20288,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ZigTypeIdArray:
{
size_t buf_i = 0;
+ // TODO optimize the buf case
expand_undef_array(codegen, val);
for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
- ConstExprValue *elem = &val->data.x_array.s_none.elements[elem_i];
+ ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
buf_write_value_bytes(codegen, &buf[buf_i], elem);
buf_i += type_size(codegen, elem->type);
}
test/cases/bugs/1076.zig
@@ -0,0 +1,16 @@
+const std = @import("std");
+const mem = std.mem;
+const assert = std.debug.assert;
+
+test "comptime code should not modify constant data" {
+ testCastPtrOfArrayToSliceAndPtr();
+ comptime testCastPtrOfArrayToSliceAndPtr();
+}
+
+fn testCastPtrOfArrayToSliceAndPtr() void {
+ var array = "aoeu";
+ const x: [*]u8 = &array;
+ x[0] += 1;
+ assert(mem.eql(u8, array[0..], "boeu"));
+}
+
test/cases/cast.zig
@@ -400,7 +400,7 @@ test "single-item pointer of array to slice and to unknown length pointer" {
}
fn testCastPtrOfArrayToSliceAndPtr() void {
- var array = "ao" ++ "eu"; // TODO https://github.com/ziglang/zig/issues/1076
+ var array = "aoeu";
const x: [*]u8 = &array;
x[0] += 1;
assert(mem.eql(u8, array[0..], "boeu"));
test/behavior.zig
@@ -8,6 +8,7 @@ comptime {
_ = @import("cases/atomics.zig");
_ = @import("cases/bitcast.zig");
_ = @import("cases/bool.zig");
+ _ = @import("cases/bugs/1076.zig");
_ = @import("cases/bugs/1111.zig");
_ = @import("cases/bugs/1277.zig");
_ = @import("cases/bugs/1322.zig");