diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-11-07 18:58:01 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-11-07 18:58:01 -0500 |
| commit | 05de70017d8bf15a37f1d1be4e23f5d3f3f9b146 (patch) | |
| tree | 434ef9d14ed874f72231ccd734d8d618ca91affb /src | |
| parent | a2e32939305e470ce3d32c9d2667d3083158ddb3 (diff) | |
| download | zig-05de70017d8bf15a37f1d1be4e23f5d3f3f9b146.tar.gz zig-05de70017d8bf15a37f1d1be4e23f5d3f3f9b146.zip | |
IR: support slice types
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 16 | ||||
| -rw-r--r-- | src/analyze.cpp | 4 | ||||
| -rw-r--r-- | src/analyze.hpp | 1 | ||||
| -rw-r--r-- | src/codegen.cpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 450 | ||||
| -rw-r--r-- | src/ir_print.cpp | 19 |
6 files changed, 341 insertions, 151 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 8cc943f30b..177a74883f 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1447,6 +1447,8 @@ enum IrInstructionId { IrInstructionIdToPtrType, IrInstructionIdPtrTypeChild, IrInstructionIdSetFnTest, + IrInstructionIdArrayType, + IrInstructionIdSliceType, }; struct IrInstruction { @@ -1696,6 +1698,20 @@ struct IrInstructionSetFnTest { IrInstruction *is_test; }; +struct IrInstructionArrayType { + IrInstruction base; + + IrInstruction *size; + IrInstruction *child_type; +}; + +struct IrInstructionSliceType { + IrInstruction base; + + bool is_const; + IrInstruction *child_type; +}; + enum LValPurpose { LValPurposeNone, LValPurposeAssign, diff --git a/src/analyze.cpp b/src/analyze.cpp index 50e690b9bf..a329fa540c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -369,7 +369,7 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { } } -static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { +TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { if (child_type->error_parent) { return child_type->error_parent; } else { @@ -2582,7 +2582,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { &fn_table_entry->analyzed_executable, expected_type, fn_proto->return_type); node->data.fn_def.implicit_return_type = block_return_type; - if (g->verbose) { + if (block_return_type->id != TypeTableEntryIdInvalid && g->verbose) { fprintf(stderr, "fn %s { // (analyzed)\n", buf_ptr(&fn_table_entry->symbol_name)); ir_print(stderr, &fn_table_entry->analyzed_executable, 4); fprintf(stderr, "}\n"); diff --git a/src/analyze.hpp b/src/analyze.hpp index b6bcf5868c..cbcffc30b7 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -31,6 +31,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, ContainerKind kind, AstNode *decl_node, const char *name); TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); +TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); bool handle_is_ptr(TypeTableEntry *type_entry); void find_libc_include_path(CodeGen *g); void find_libc_lib_path(CodeGen *g); diff --git a/src/codegen.cpp b/src/codegen.cpp index 086394a950..9f30a37e0c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2966,6 +2966,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdPtrTypeChild: case IrInstructionIdFieldPtr: case IrInstructionIdSetFnTest: + case IrInstructionIdArrayType: + case IrInstructionIdSliceType: zig_unreachable(); case IrInstructionIdReturn: return ir_render_return(g, executable, (IrInstructionReturn *)instruction); diff --git a/src/ir.cpp b/src/ir.cpp index 96bf78bdf5..84c0332c9b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -189,6 +189,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) { return IrInstructionIdSetFnTest; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { + return IrInstructionIdArrayType; +} + +static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { + return IrInstructionIdSliceType; +} + template<typename T> static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { T *special_instruction = allocate<T>(1); @@ -716,19 +724,30 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node, return &instruction->base; } -//static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { -// size_t result = 0; -// while (inner_block != outer_block) { -// if (inner_block->node->type == NodeTypeDefer && -// (inner_block->node->data.defer.kind == ReturnKindError || -// inner_block->node->data.defer.kind == ReturnKindMaybe)) -// { -// result += 1; -// } -// inner_block = inner_block->parent; -// } -// return result; -//} +static IrInstruction *ir_build_array_type(IrBuilder *irb, AstNode *source_node, IrInstruction *size, + IrInstruction *child_type) +{ + IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, source_node); + instruction->size = size; + instruction->child_type = child_type; + + ir_ref_instruction(size); + ir_ref_instruction(child_type); + + return &instruction->base; +} + +static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node, bool is_const, + IrInstruction *child_type) +{ + IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, source_node); + instruction->is_const = is_const; + instruction->child_type = child_type; + + ir_ref_instruction(child_type); + + return &instruction->base; +} static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, bool gen_error_defers, bool gen_maybe_defers) @@ -777,23 +796,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) { zig_unreachable(); } -//static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) { -// BlockContext *defer_inner_block = source_node->block_context; -// BlockContext *defer_outer_block = irb->node->block_context; -// if (rk == ReturnKnowledgeUnknown) { -// if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) { -// // generate branching code that checks the return value and generates defers -// // if the return value is error -// zig_panic("TODO"); -// } -// } else if (rk != ReturnKnowledgeSkipDefers) { -// ir_gen_defers_for_block(irb, defer_inner_block, defer_outer_block, -// rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull); -// } -// -// return ir_build_return(irb, source_node, value); -//} - static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { assert(basic_block); @@ -1588,6 +1590,38 @@ static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, AstNode *node) { return ir_build_const_bool(irb, node, node->data.bool_literal.value); } +static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) { + assert(node->type == NodeTypeArrayType); + + AstNode *size_node = node->data.array_type.size; + AstNode *child_type_node = node->data.array_type.child_type; + bool is_const = node->data.array_type.is_const; + + if (size_node) { + if (is_const) { + add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); + return irb->codegen->invalid_instruction; + } + + IrInstruction *size_value = ir_gen_node(irb, size_node, node->block_context); + if (size_value == irb->codegen->invalid_instruction) + return size_value; + + IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->block_context); + if (child_type == irb->codegen->invalid_instruction) + return child_type; + + return ir_build_array_type(irb, node, size_value, child_type); + } else { + IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node, + node->block_context, LValPurposeAddressOf); + if (child_type == irb->codegen->invalid_instruction) + return child_type; + + return ir_build_slice_type(irb, node, is_const, child_type); + } +} + static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, LValPurpose lval) { @@ -1627,6 +1661,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont return ir_gen_this_literal(irb, node); case NodeTypeBoolLiteral: return ir_gen_bool_literal(irb, node); + case NodeTypeArrayType: + return ir_gen_array_type(irb, node); case NodeTypeUnwrapErrorExpr: case NodeTypeDefer: case NodeTypeSliceExpr: @@ -1644,7 +1680,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont case NodeTypeZeroesLiteral: case NodeTypeErrorType: case NodeTypeTypeLiteral: - case NodeTypeArrayType: case NodeTypeVarLiteral: case NodeTypeRoot: case NodeTypeFnProto: @@ -1703,51 +1738,6 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { return ir_gen(codegn, body_node, scope, ir_executable); } -/* -static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) { - assert(node->type == NodeTypeGoto); - Buf *label_name = node->data.goto_expr.name; - BlockContext *context = node->block_context; - assert(context); - LabelTableEntry *label = find_label(g, context, label_name); - - if (!label) { - add_node_error(g, node, buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); - return; - } - - label->used = true; - node->data.goto_expr.label_entry = label; -} - - for (size_t i = 0; i < fn_table_entry->goto_list.length; i += 1) { - AstNode *goto_node = fn_table_entry->goto_list.at(i); - assert(goto_node->type == NodeTypeGoto); - analyze_goto_pass2(g, import, goto_node); - } - - for (size_t i = 0; i < fn_table_entry->all_labels.length; i += 1) { - LabelTableEntry *label = fn_table_entry->all_labels.at(i); - if (!label->used) { - add_node_error(g, label->decl_node, - buf_sprintf("label '%s' defined but not used", - buf_ptr(label->decl_node->data.label.name))); - } - } -*/ - -//static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf *name) { -// BlockContext *context = orig_context; -// while (context && context->fn_entry) { -// auto entry = context->label_table.maybe_get(name); -// if (entry) { -// return entry->value; -// } -// context = context->parent; -// } -// return nullptr; -//} - static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) { TypeTableEntry *other_type_underlying = get_underlying_type(other_type); @@ -2970,6 +2960,59 @@ static TypeTableEntry *ir_analyze_unary_bool_not(IrAnalyze *ira, IrInstructionUn return bool_type; } +static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { + assert(un_op_instruction->op_id == IrUnOpError); + IrInstruction *value = un_op_instruction->value->other; + + TypeTableEntry *type_entry = value->type_entry; + if (type_entry->id == TypeTableEntryIdInvalid) + return ira->codegen->builtin_types.entry_invalid; + + TypeTableEntry *meta_type = ir_resolve_type(ira, value); + TypeTableEntry *underlying_meta_type = get_underlying_type(meta_type); + switch (underlying_meta_type->id) { + case TypeTableEntryIdTypeDecl: + zig_unreachable(); + case TypeTableEntryIdInvalid: + return ira->codegen->builtin_types.entry_invalid; + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdPointer: + case TypeTableEntryIdArray: + case TypeTableEntryIdStruct: + case TypeTableEntryIdMaybe: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdEnum: + case TypeTableEntryIdUnion: + case TypeTableEntryIdFn: + case TypeTableEntryIdGenericFn: + { + ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, + value->static_value.depends_on_compile_var); + TypeTableEntry *result_type = get_error_type(ira->codegen, meta_type); + out_val->data.x_type = result_type; + return ira->codegen->builtin_types.entry_type; + } + case TypeTableEntryIdMetaType: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBlock: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdVar: + add_node_error(ira->codegen, un_op_instruction->base.source_node, + buf_sprintf("unable to wrap type '%s' in error type", buf_ptr(&meta_type->name))); + // TODO if meta_type is type decl, add note pointing to type decl declaration + return ira->codegen->builtin_types.entry_invalid; + } + zig_unreachable(); +} + static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { IrUnOp op_id = un_op_instruction->op_id; switch (op_id) { @@ -2977,7 +3020,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio zig_unreachable(); case IrUnOpBoolNot: return ir_analyze_unary_bool_not(ira, un_op_instruction); - zig_panic("TODO analyze PrefixOpBoolNot"); case IrUnOpBinNot: zig_panic("TODO analyze PrefixOpBinNot"); //{ @@ -3106,31 +3148,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio // } //} case IrUnOpError: - zig_panic("TODO analyze PrefixOpError"); - //{ - // TypeTableEntry *type_entry = analyze_expression(g, import, context, nullptr, *expr_node); - - // if (type_entry->id == TypeTableEntryIdInvalid) { - // return type_entry; - // } else if (type_entry->id == TypeTableEntryIdMetaType) { - // TypeTableEntry *meta_type = resolve_type(g, *expr_node); - // if (meta_type->id == TypeTableEntryIdInvalid) { - // return meta_type; - // } else if (meta_type->id == TypeTableEntryIdUnreachable) { - // add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in error type")); - // return g->builtin_types.entry_invalid; - // } else { - // return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type), false); - // } - // } else if (type_entry->id == TypeTableEntryIdUnreachable) { - // add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in error type")); - // return g->builtin_types.entry_invalid; - // } else { - // // TODO eval const expr - // return get_error_type(g, type_entry); - // } - - //} + return ir_analyze_unary_prefix_op_err(ira, un_op_instruction); case IrUnOpUnwrapError: zig_panic("TODO analyze PrefixOpUnwrapError"); //{ @@ -3691,6 +3709,59 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira, return ira->codegen->builtin_types.entry_void; } +static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, + IrInstructionSliceType *slice_type_instruction) +{ + IrInstruction *child_type = slice_type_instruction->child_type->other; + if (child_type->type_entry->id == TypeTableEntryIdInvalid) + return ira->codegen->builtin_types.entry_invalid; + bool is_const = slice_type_instruction->is_const; + + TypeTableEntry *resolved_child_type = ir_resolve_type(ira, child_type); + TypeTableEntry *canon_child_type = get_underlying_type(resolved_child_type); + switch (canon_child_type->id) { + case TypeTableEntryIdTypeDecl: + zig_unreachable(); + case TypeTableEntryIdInvalid: + return ira->codegen->builtin_types.entry_invalid; + case TypeTableEntryIdVar: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdBlock: + add_node_error(ira->codegen, slice_type_instruction->base.source_node, + buf_sprintf("slice of type '%s' not allowed", buf_ptr(&resolved_child_type->name))); + // TODO if this is a typedecl, add error note showing the declaration of the type decl + return ira->codegen->builtin_types.entry_invalid; + case TypeTableEntryIdMetaType: + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdPointer: + case TypeTableEntryIdArray: + case TypeTableEntryIdStruct: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdMaybe: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdEnum: + case TypeTableEntryIdUnion: + case TypeTableEntryIdFn: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdGenericFn: + { + TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const); + ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base, + child_type->static_value.depends_on_compile_var); + out_val->data.x_type = result_type; + return ira->codegen->builtin_types.entry_type; + } + } + zig_unreachable(); +} + static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { switch (instruction->id) { case IrInstructionIdInvalid: @@ -3735,11 +3806,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); case IrInstructionIdSetFnTest: return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction); + case IrInstructionIdSliceType: + return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); case IrInstructionIdSwitchBr: case IrInstructionIdCast: case IrInstructionIdContainerInitList: case IrInstructionIdContainerInitFields: case IrInstructionIdStructFieldPtr: + case IrInstructionIdArrayType: zig_panic("TODO analyze more instructions"); } zig_unreachable(); @@ -3836,6 +3910,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdPtrTypeChild: case IrInstructionIdReadField: case IrInstructionIdStructFieldPtr: + case IrInstructionIdArrayType: + case IrInstructionIdSliceType: return false; } zig_unreachable(); @@ -6782,53 +6858,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { // false, nullptr, false); //} // -//static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, -// TypeTableEntry *expected_type, AstNode *node) -//{ -// AstNode *size_node = node->data.array_type.size; -// -// TypeTableEntry *child_type = analyze_type_expr_pointer_only(g, import, context, -// node->data.array_type.child_type, true); -// -// if (child_type->id == TypeTableEntryIdUnreachable) { -// add_node_error(g, node, buf_create_from_str("array of unreachable not allowed")); -// return g->builtin_types.entry_invalid; -// } else if (child_type->id == TypeTableEntryIdInvalid) { -// return g->builtin_types.entry_invalid; -// } -// -// if (size_node) { -// child_type = analyze_type_expr(g, import, context, node->data.array_type.child_type); -// TypeTableEntry *size_type = analyze_expression(g, import, context, -// g->builtin_types.entry_usize, size_node); -// if (size_type->id == TypeTableEntryIdInvalid) { -// return g->builtin_types.entry_invalid; -// } -// -// ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; -// if (const_val->ok) { -// if (const_val->data.x_bignum.is_negative) { -// add_node_error(g, size_node, -// buf_sprintf("array size %s is negative", -// buf_ptr(bignum_to_buf(&const_val->data.x_bignum)))); -// return g->builtin_types.entry_invalid; -// } else { -// return resolve_expr_const_val_as_type(g, node, -// get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false); -// } -// } else if (context->fn_entry) { -// return resolve_expr_const_val_as_type(g, node, -// get_slice_type(g, child_type, node->data.array_type.is_const), false); -// } else { -// add_node_error(g, first_executing_node(size_node), -// buf_sprintf("unable to evaluate constant expression")); -// return g->builtin_types.entry_invalid; -// } -// } else { -// TypeTableEntry *slice_type = get_slice_type(g, child_type, node->data.array_type.is_const); -// return resolve_expr_const_val_as_type(g, node, slice_type, false); -// } -//} // //static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, // TypeTableEntry *expected_type, AstNode *node) @@ -7218,3 +7247,126 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { // } //} // +//static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, +// TypeTableEntry *expected_type, AstNode *node) +//{ +// AstNode *size_node = node->data.array_type.size; +// +// TypeTableEntry *child_type = analyze_type_expr_pointer_only(g, import, context, +// node->data.array_type.child_type, true); +// +// if (child_type->id == TypeTableEntryIdUnreachable) { +// add_node_error(g, node, buf_create_from_str("array of unreachable not allowed")); +// return g->builtin_types.entry_invalid; +// } else if (child_type->id == TypeTableEntryIdInvalid) { +// return g->builtin_types.entry_invalid; +// } +// +// if (size_node) { +// child_type = analyze_type_expr(g, import, context, node->data.array_type.child_type); +// TypeTableEntry *size_type = analyze_expression(g, import, context, +// g->builtin_types.entry_usize, size_node); +// if (size_type->id == TypeTableEntryIdInvalid) { +// return g->builtin_types.entry_invalid; +// } +// +// ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; +// if (const_val->ok) { +// if (const_val->data.x_bignum.is_negative) { +// add_node_error(g, size_node, +// buf_sprintf("array size %s is negative", +// buf_ptr(bignum_to_buf(&const_val->data.x_bignum)))); +// return g->builtin_types.entry_invalid; +// } else { +// return resolve_expr_const_val_as_type(g, node, +// get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false); +// } +// } else if (context->fn_entry) { +// return resolve_expr_const_val_as_type(g, node, +// get_slice_type(g, child_type, node->data.array_type.is_const), false); +// } else { +// add_node_error(g, first_executing_node(size_node), +// buf_sprintf("unable to evaluate constant expression")); +// return g->builtin_types.entry_invalid; +// } +// } else { +// TypeTableEntry *slice_type = get_slice_type(g, child_type, node->data.array_type.is_const); +// return resolve_expr_const_val_as_type(g, node, slice_type, false); +// } +//} +//static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { +// size_t result = 0; +// while (inner_block != outer_block) { +// if (inner_block->node->type == NodeTypeDefer && +// (inner_block->node->data.defer.kind == ReturnKindError || +// inner_block->node->data.defer.kind == ReturnKindMaybe)) +// { +// result += 1; +// } +// inner_block = inner_block->parent; +// } +// return result; +//} + + +//static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) { +// BlockContext *defer_inner_block = source_node->block_context; +// BlockContext *defer_outer_block = irb->node->block_context; +// if (rk == ReturnKnowledgeUnknown) { +// if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) { +// // generate branching code that checks the return value and generates defers +// // if the return value is error +// zig_panic("TODO"); +// } +// } else if (rk != ReturnKnowledgeSkipDefers) { +// ir_gen_defers_for_block(irb, defer_inner_block, defer_outer_block, +// rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull); +// } +// +// return ir_build_return(irb, source_node, value); +//} +/* +static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) { + assert(node->type == NodeTypeGoto); + Buf *label_name = node->data.goto_expr.name; + BlockContext *context = node->block_context; + assert(context); + LabelTableEntry *label = find_label(g, context, label_name); + + if (!label) { + add_node_error(g, node, buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); + return; + } + + label->used = true; + node->data.goto_expr.label_entry = label; +} + + for (size_t i = 0; i < fn_table_entry->goto_list.length; i += 1) { + AstNode *goto_node = fn_table_entry->goto_list.at(i); + assert(goto_node->type == NodeTypeGoto); + analyze_goto_pass2(g, import, goto_node); + } + + for (size_t i = 0; i < fn_table_entry->all_labels.length; i += 1) { + LabelTableEntry *label = fn_table_entry->all_labels.at(i); + if (!label->used) { + add_node_error(g, label->decl_node, + buf_sprintf("label '%s' defined but not used", + buf_ptr(label->decl_node->data.label.name))); + } + } +*/ + +//static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf *name) { +// BlockContext *context = orig_context; +// while (context && context->fn_entry) { +// auto entry = context->label_table.maybe_get(name); +// if (entry) { +// return entry->value; +// } +// context = context->parent; +// } +// return nullptr; +//} + diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 5a0f33b317..f3d030519e 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -394,6 +394,19 @@ static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instructi fprintf(irp->f, ")"); } +static void ir_print_array_type(IrPrint *irp, IrInstructionArrayType *instruction) { + fprintf(irp->f, "["); + ir_print_other_instruction(irp, instruction->size); + fprintf(irp->f, "]"); + ir_print_other_instruction(irp, instruction->child_type); +} + +static void ir_print_slice_type(IrPrint *irp, IrInstructionSliceType *instruction) { + const char *const_kw = instruction->is_const ? "const " : ""; + fprintf(irp->f, "[]%s", const_kw); + ir_print_other_instruction(irp, instruction->child_type); +} + static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { ir_print_prefix(irp, instruction); switch (instruction->id) { @@ -471,6 +484,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdSetFnTest: ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction); break; + case IrInstructionIdArrayType: + ir_print_array_type(irp, (IrInstructionArrayType *)instruction); + break; + case IrInstructionIdSliceType: + ir_print_slice_type(irp, (IrInstructionSliceType *)instruction); + break; case IrInstructionIdSwitchBr: zig_panic("TODO print more IR instructions"); } |
