diff options
| author | Alexandros Naskos <alex_naskos@hotmail.com> | 2020-04-27 18:07:18 +0300 |
|---|---|---|
| committer | Alexandros Naskos <alex_naskos@hotmail.com> | 2020-04-27 18:07:18 +0300 |
| commit | 37fa418a94fc5da695f8799b6b021b632bb1d500 (patch) | |
| tree | a5f84478194c56cd0541f9c8b914a00e08167cc7 /src/ir.cpp | |
| parent | 908b908481260322b60f479ccf4cabff72fcc5d5 (diff) | |
| download | zig-37fa418a94fc5da695f8799b6b021b632bb1d500.tar.gz zig-37fa418a94fc5da695f8799b6b021b632bb1d500.zip | |
Cleaned up code, added a testcase for an extern member function call
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 64f39bf6f5..6f44f6c899 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19707,25 +19707,31 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, } if (modifier == CallModifierCompileTime) { - bool extern_fn_in_typeof = false; + // If we are evaluating an extern function in a TypeOf call, we can return an undefined value + // of its return type. + if (fn_entry != nullptr && source_instr->scope->id == ScopeIdTypeOf && + fn_proto_node->data.fn_proto.is_extern) { + + assert(fn_entry->body_node == nullptr); + AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; + ZigType *return_type = ir_analyze_type_expr(ira, source_instr->scope, return_type_node); + if (type_is_invalid(return_type)) + return ira->codegen->invalid_inst_gen; + + return ir_const_undef(ira, source_instr, return_type); + } // No special handling is needed for compile time evaluation of generic functions. if (!fn_entry || fn_entry->body_node == nullptr) { - // We keep evaluating extern functions directly in TypeOfs - if (fn_entry && source_instr->scope->id == ScopeIdTypeOf) { - extern_fn_in_typeof = true; - } else { - ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); - return ira->codegen->invalid_inst_gen; - } + ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); + return ira->codegen->invalid_inst_gen; } if (!ir_emit_backward_branch(ira, source_instr)) return ira->codegen->invalid_inst_gen; // Fork a scope of the function with known values for the parameters. - // If we are evaluating an extern function in a TypeOf, we use the current scope instead. - Scope *exec_scope = extern_fn_in_typeof ? source_instr->scope : &fn_entry->fndef_scope->base; + Scope *exec_scope = &fn_entry->fndef_scope->base; size_t next_proto_i = 0; if (first_arg_ptr) { @@ -19752,7 +19758,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, return ira->codegen->invalid_inst_gen; } - if (!extern_fn_in_typeof) for (size_t call_i = 0; call_i < args_len; call_i += 1) { + for (size_t call_i = 0; call_i < args_len; call_i += 1) { IrInstGen *old_arg = args_ptr[call_i]; if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) @@ -19774,7 +19780,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, return_type = specified_return_type; } - bool cacheable = !extern_fn_in_typeof && fn_eval_cacheable(exec_scope, return_type); + bool cacheable = fn_eval_cacheable(exec_scope, return_type); ZigValue *result = nullptr; if (cacheable) { auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); @@ -19788,15 +19794,12 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, ZigValue *result_ptr; create_result_ptr(ira->codegen, return_type, &result, &result_ptr); - // If we are evaluating an extern function in a TypeOf, create a value and keep it undefined. - if (!extern_fn_in_typeof) { - if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, - ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, - fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, - UndefOk))) - { - return ira->codegen->invalid_inst_gen; - } + if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, + ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, + fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, + UndefOk))) + { + return ira->codegen->invalid_inst_gen; } if (inferred_err_set_type != nullptr) { |
