aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-08-04 15:19:03 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-08-04 15:19:03 -0400
commitb48948d6e805cdee7f33243098af9a862c152df1 (patch)
tree8b1b4b37670f7444e8fe12748a8db99ac7498cce /src/ir.cpp
parentf804310d9f953c9d78a4271ba8d75133341840e6 (diff)
parent9bd8b01650f9cf21e601117951711b21aa5fd216 (diff)
downloadzig-b48948d6e805cdee7f33243098af9a862c152df1.tar.gz
zig-b48948d6e805cdee7f33243098af9a862c152df1.zip
Merge branch 'master' into llvm7
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp78
1 files changed, 64 insertions, 14 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 699baa152e..3e423487aa 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -580,6 +580,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *)
return IrInstructionIdFrameAddress;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionHandle *) {
+ return IrInstructionIdHandle;
+}
+
static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) {
return IrInstructionIdAlignOf;
}
@@ -2240,6 +2244,17 @@ static IrInstruction *ir_build_frame_address_from(IrBuilder *irb, IrInstruction
return new_instruction;
}
+static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) {
+ IrInstructionHandle *instruction = ir_build_instruction<IrInstructionHandle>(irb, scope, source_node);
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_handle_from(IrBuilder *irb, IrInstruction *old_instruction) {
+ IrInstruction *new_instruction = ir_build_handle(irb, old_instruction->scope, old_instruction->source_node);
+ ir_link_new_instruction(new_instruction, old_instruction);
+ return new_instruction;
+}
+
static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2,
IrInstruction *result_ptr, TypeTableEntry *result_ptr_type)
@@ -3317,7 +3332,15 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name,
bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime)
{
- VariableTableEntry *var = create_local_var(irb->codegen, node, scope, name, src_is_const, gen_is_const, is_shadowable, is_comptime);
+ bool is_underscored = name ? buf_eql_str(name, "_") : false;
+ VariableTableEntry *var = create_local_var( irb->codegen
+ , node
+ , scope
+ , (is_underscored ? nullptr : name)
+ , src_is_const
+ , gen_is_const
+ , (is_underscored ? true : is_shadowable)
+ , is_comptime );
if (is_comptime != nullptr || gen_is_const) {
var->mem_slot_index = exec_next_mem_slot(irb->exec);
var->owner_exec = irb->exec;
@@ -3843,6 +3866,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return irb->codegen->invalid_instruction;
}
+ bool is_async = exec_is_async(irb->exec);
+
switch (builtin_fn->id) {
case BuiltinFnIdInvalid:
zig_unreachable();
@@ -4475,6 +4500,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval);
case BuiltinFnIdFrameAddress:
return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval);
+ case BuiltinFnIdHandle:
+ if (!irb->exec->fn_entry) {
+ add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition"));
+ return irb->codegen->invalid_instruction;
+ }
+ if (!is_async) {
+ add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function"));
+ return irb->codegen->invalid_instruction;
+ }
+ return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval);
case BuiltinFnIdAlignOf:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
@@ -5159,6 +5194,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
+ if (buf_eql_str(variable_declaration->symbol, "_")) {
+ add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol"));
+ return irb->codegen->invalid_instruction;
+ }
+
IrInstruction *type_instruction;
if (variable_declaration->type != nullptr) {
type_instruction = ir_gen_node(irb, variable_declaration->type, scope);
@@ -5171,6 +5211,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
bool is_shadowable = false;
bool is_const = variable_declaration->is_const;
bool is_extern = variable_declaration->is_extern;
+
IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node,
ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime);
VariableTableEntry *var = ir_create_var(irb, node, scope, variable_declaration->symbol,
@@ -7069,19 +7110,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
if (node->data.suspend.block == nullptr) {
suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);
} else {
- assert(node->data.suspend.promise_symbol != nullptr);
- assert(node->data.suspend.promise_symbol->type == NodeTypeSymbol);
- Buf *promise_symbol_name = node->data.suspend.promise_symbol->data.symbol_expr.symbol;
Scope *child_scope;
- if (!buf_eql_str(promise_symbol_name, "_")) {
- VariableTableEntry *promise_var = ir_create_var(irb, node, parent_scope, promise_symbol_name,
- true, true, false, const_bool_false);
- ir_build_var_decl(irb, parent_scope, node, promise_var, nullptr, nullptr, irb->exec->coro_handle);
- child_scope = promise_var->child_scope;
- } else {
- child_scope = parent_scope;
- }
- ScopeSuspend *suspend_scope = create_suspend_scope(node, child_scope);
+ ScopeSuspend *suspend_scope = create_suspend_scope(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);
@@ -9598,6 +9628,9 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
case ConstValSpecialStatic:
return &value->value;
case ConstValSpecialRuntime:
+ if (!type_has_bits(value->value.type)) {
+ return &value->value;
+ }
ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression"));
return nullptr;
case ConstValSpecialUndef:
@@ -16099,8 +16132,14 @@ static TypeTableEntry *ir_analyze_container_init_fields_union(IrAnalyze *ira, Ir
if (casted_field_value == ira->codegen->invalid_instruction)
return ira->codegen->builtin_types.entry_invalid;
+ type_ensure_zero_bits_known(ira->codegen, casted_field_value->value.type);
+ if (type_is_invalid(casted_field_value->value.type))
+ return ira->codegen->builtin_types.entry_invalid;
+
bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope);
- if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) {
+ if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime ||
+ !type_has_bits(casted_field_value->value.type))
+ {
ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);
if (!field_val)
return ira->codegen->builtin_types.entry_invalid;
@@ -19007,6 +19046,14 @@ static TypeTableEntry *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIn
return u8_ptr_const;
}
+static TypeTableEntry *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) {
+ ir_build_handle_from(&ira->new_irb, &instruction->base);
+
+ FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
+ assert(fn_entry != nullptr);
+ return get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type);
+}
+
static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {
IrInstruction *type_value = instruction->type_value->other;
if (type_is_invalid(type_value->value.type))
@@ -20982,6 +21029,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction);
case IrInstructionIdFrameAddress:
return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction);
+ case IrInstructionIdHandle:
+ return ir_analyze_instruction_handle(ira, (IrInstructionHandle *)instruction);
case IrInstructionIdAlignOf:
return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction);
case IrInstructionIdOverflowOp:
@@ -21274,6 +21323,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdAlignOf:
case IrInstructionIdReturnAddress:
case IrInstructionIdFrameAddress:
+ case IrInstructionIdHandle:
case IrInstructionIdTestErr:
case IrInstructionIdUnwrapErrCode:
case IrInstructionIdOptionalWrap: