Commit e269caae02
Changed files (3)
src/all_types.hpp
@@ -62,6 +62,7 @@ struct ConstPtrValue {
struct ConstExprValue {
bool ok; // true if constant expression evalution worked
bool depends_on_compile_var;
+ bool undef;
union {
BigNum x_bignum;
@@ -808,6 +809,7 @@ enum TypeTableEntryId {
TypeTableEntryIdStruct,
TypeTableEntryIdNumLitFloat,
TypeTableEntryIdNumLitInt,
+ TypeTableEntryIdUndefLit,
TypeTableEntryIdMaybe,
TypeTableEntryIdError,
TypeTableEntryIdEnum,
@@ -949,6 +951,7 @@ struct CodeGen {
TypeTableEntry *entry_invalid;
TypeTableEntry *entry_num_lit_int;
TypeTableEntry *entry_num_lit_float;
+ TypeTableEntry *entry_undef;
} builtin_types;
LLVMTargetDataRef target_data_ref;
src/analyze.cpp
@@ -111,6 +111,7 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
case TypeTableEntryIdMaybe:
case TypeTableEntryIdFn:
case TypeTableEntryIdError:
+ case TypeTableEntryIdUndefLit:
// nothing to init
break;
case TypeTableEntryIdStruct:
@@ -1063,6 +1064,7 @@ static bool type_has_codegen_value(TypeTableEntryId id) {
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
+ case TypeTableEntryIdUndefLit:
return false;
case TypeTableEntryIdBool:
@@ -2481,10 +2483,9 @@ static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEnt
ConstExprValue *const_val = &expr->const_val;
const_val->ok = true;
+ const_val->undef = true;
- zig_panic("TODO");
-
- return expected_type;
+ return expected_type ? expected_type : g->builtin_types.entry_undef;
}
src/codegen.cpp
@@ -1725,84 +1725,91 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
}
if (variable->type->size_in_bits == 0) {
return nullptr;
- } else {
- if (var_decl->expr) {
- TypeTableEntry *expr_type = get_expr_type(var_decl->expr);
- LLVMValueRef value;
- if (unwrap_maybe) {
- assert(var_decl->expr);
- assert(expr_type->id == TypeTableEntryIdMaybe);
- value = gen_unwrap_maybe(g, source_node, *init_value);
- expr_type = expr_type->data.maybe.child_type;
- } else {
- value = *init_value;
- }
- gen_assign_raw(g, var_decl->expr, BinOpTypeAssign, variable->value_ref,
- value, variable->type, expr_type);
+ }
+
+ bool have_init_expr = false;
+ if (var_decl->expr) {
+ ConstExprValue *const_val = &get_resolved_expr(var_decl->expr)->const_val;
+ if (!const_val->ok || !const_val->undef) {
+ have_init_expr = true;
+ }
+ }
+ if (have_init_expr) {
+ TypeTableEntry *expr_type = get_expr_type(var_decl->expr);
+ LLVMValueRef value;
+ if (unwrap_maybe) {
+ assert(var_decl->expr);
+ assert(expr_type->id == TypeTableEntryIdMaybe);
+ value = gen_unwrap_maybe(g, source_node, *init_value);
+ expr_type = expr_type->data.maybe.child_type;
} else {
- bool ignore_uninit = false;
- TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);
- if (var_type->id == TypeTableEntryIdStruct &&
- var_type->data.structure.is_unknown_size_array)
- {
- assert(var_decl->type->type == NodeTypeArrayType);
- AstNode *size_node = var_decl->type->data.array_type.size;
- if (size_node) {
- ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
- if (!const_val->ok) {
- TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;
- assert(ptr_type->id == TypeTableEntryIdPointer);
- TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
-
- LLVMValueRef size_val = gen_expr(g, size_node);
-
- add_debug_source_node(g, source_node);
- LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,
- size_val, "");
-
- // store the freshly allocated pointer in the unknown size array struct
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,
- variable->value_ref, 0, "");
- LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);
-
- // store the size in the len field
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,
- variable->value_ref, 1, "");
- LLVMBuildStore(g->builder, size_val, len_field_ptr);
-
- // don't clobber what we just did with debug initialization
- ignore_uninit = true;
- }
+ value = *init_value;
+ }
+ gen_assign_raw(g, var_decl->expr, BinOpTypeAssign, variable->value_ref,
+ value, variable->type, expr_type);
+ } else {
+ bool ignore_uninit = false;
+ TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);
+ if (var_type->id == TypeTableEntryIdStruct &&
+ var_type->data.structure.is_unknown_size_array)
+ {
+ assert(var_decl->type->type == NodeTypeArrayType);
+ AstNode *size_node = var_decl->type->data.array_type.size;
+ if (size_node) {
+ ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
+ if (!const_val->ok) {
+ TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;
+ assert(ptr_type->id == TypeTableEntryIdPointer);
+ TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
+
+ LLVMValueRef size_val = gen_expr(g, size_node);
+
+ add_debug_source_node(g, source_node);
+ LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,
+ size_val, "");
+
+ // store the freshly allocated pointer in the unknown size array struct
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,
+ variable->value_ref, 0, "");
+ LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);
+
+ // store the size in the len field
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,
+ variable->value_ref, 1, "");
+ LLVMBuildStore(g->builder, size_val, len_field_ptr);
+
+ // don't clobber what we just did with debug initialization
+ ignore_uninit = true;
}
}
- if (!ignore_uninit && g->build_type != CodeGenBuildTypeRelease) {
- // memset uninitialized memory to 0xa
- add_debug_source_node(g, source_node);
- LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
- LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
- LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
- LLVMValueRef byte_count = LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8),
- variable->type->size_in_bits / 8, false);
- LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(),
- variable->type->align_in_bits / 8, false);
- LLVMValueRef params[] = {
- dest_ptr,
- fill_char,
- byte_count,
- align_in_bytes,
- LLVMConstNull(LLVMInt1Type()), // is volatile
- };
-
- LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, "");
- }
}
+ if (!ignore_uninit && g->build_type != CodeGenBuildTypeRelease) {
+ // memset uninitialized memory to 0xa
+ add_debug_source_node(g, source_node);
+ LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
+ LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
+ LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
+ LLVMValueRef byte_count = LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8),
+ variable->type->size_in_bits / 8, false);
+ LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(),
+ variable->type->align_in_bits / 8, false);
+ LLVMValueRef params[] = {
+ dest_ptr,
+ fill_char,
+ byte_count,
+ align_in_bytes,
+ LLVMConstNull(LLVMInt1Type()), // is volatile
+ };
- LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(source_node->line + 1, source_node->column + 1,
- g->cur_block_context->di_scope);
- LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc,
- LLVMGetInsertBlock(g->builder));
- return nullptr;
+ LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, "");
+ }
}
+
+ LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(source_node->line + 1, source_node->column + 1,
+ g->cur_block_context->di_scope);
+ LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc,
+ LLVMGetInsertBlock(g->builder));
+ return nullptr;
}
static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) {
@@ -2035,6 +2042,10 @@ static void build_label_blocks(CodeGen *g, AstNode *block_node) {
static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) {
assert(const_val->ok);
+ if (const_val->undef) {
+ return LLVMConstNull(type_entry->type_ref);
+ }
+
if (type_entry->id == TypeTableEntryIdInt) {
return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);
} else if (type_entry->id == TypeTableEntryIdFloat) {
@@ -2389,6 +2400,11 @@ static void define_builtin_types(CodeGen *g) {
buf_init_from_str(&entry->name, "(integer literal)");
g->builtin_types.entry_num_lit_int = entry;
}
+ {
+ TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);
+ buf_init_from_str(&entry->name, "(undefined)");
+ g->builtin_types.entry_undef = entry;
+ }
for (int i = 0; i < array_length(int_sizes_in_bits); i += 1) {
int size_in_bits = int_sizes_in_bits[i];