diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-01-09 10:36:51 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-09 13:43:06 -0500 |
| commit | 5ab5de89c03bf9b3f08dfaa78d3b0fe41a72cdea (patch) | |
| tree | c93dcfb6b6dad6d52d8d03e1d1a4601da5f04a3c /src/ir.cpp | |
| parent | 4613e4d15f85406d23f91134a9ec5854da33965f (diff) | |
| download | zig-5ab5de89c03bf9b3f08dfaa78d3b0fe41a72cdea.tar.gz zig-5ab5de89c03bf9b3f08dfaa78d3b0fe41a72cdea.zip | |
New @export() handling
Use a struct as second parameter to be future proof (and also allows to
specify default values for the parameters)
Closes #2679 as it was just a matter of a few lines of code.
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 107 |
1 files changed, 73 insertions, 34 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 1d55736b0c..24e930eb99 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2227,19 +2227,17 @@ static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *sourc } static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *name, IrInstruction *target, IrInstruction *linkage) + IrInstruction *target, IrInstruction *options) { IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( irb, scope, source_node); export_instruction->base.value->special = ConstValSpecialStatic; export_instruction->base.value->type = irb->codegen->builtin_types.entry_void; - export_instruction->name = name; export_instruction->target = target; - export_instruction->linkage = linkage; + export_instruction->options = options; - ir_ref_instruction(name, irb->current_basic_block); ir_ref_instruction(target, irb->current_basic_block); - if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); + ir_ref_instruction(options, irb->current_basic_block); return &export_instruction->base; } @@ -6272,22 +6270,26 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } case BuiltinFnIdExport: { - AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) - return arg0_value; - - AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) - return arg1_value; - - AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) - return arg2_value; - - IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); + // Cast the options parameter to the options type + ZigType *options_type = get_builtin_type(irb->codegen, "ExportOptions"); + IrInstruction *options_type_inst = ir_build_const_type(irb, scope, node, options_type); + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); + + AstNode *target_node = node->data.fn_call_expr.params.at(0); + IrInstruction *target_value = ir_gen_node(irb, target_node, scope); + if (target_value == irb->codegen->invalid_instruction) + return target_value; + + AstNode *options_node = node->data.fn_call_expr.params.at(1); + IrInstruction *options_value = ir_gen_node_extra(irb, options_node, + scope, LValNone, &result_loc_cast->base); + if (options_value == irb->codegen->invalid_instruction) + return options_value; + + IrInstruction *casted_options_value = ir_build_implicit_cast( + irb, scope, options_node, options_value, result_loc_cast); + + IrInstruction *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value); return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); } case BuiltinFnIdErrorReturnTrace: @@ -16683,27 +16685,61 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, } static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { - Error err; + IrInstruction *target = instruction->target->child; + if (type_is_invalid(target->value->type)) + return ira->codegen->invalid_instruction; - IrInstruction *name = instruction->name->child; - Buf *symbol_name = ir_resolve_str(ira, name); - if (symbol_name == nullptr) { + IrInstruction *options = instruction->options->child; + if (type_is_invalid(options->value->type)) return ira->codegen->invalid_instruction; - } - IrInstruction *target = instruction->target->child; - if (type_is_invalid(target->value->type)) { + ZigType *options_type = options->value->type; + assert(options_type->id == ZigTypeIdStruct); + + TypeStructField *name_field = find_struct_type_field(options_type, buf_create_from_str("name")); + ir_assert(name_field != nullptr, &instruction->base); + IrInstruction *name_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, name_field); + if (type_is_invalid(name_inst->value->type)) + return ira->codegen->invalid_instruction; + + TypeStructField *linkage_field = find_struct_type_field(options_type, buf_create_from_str("linkage")); + ir_assert(linkage_field != nullptr, &instruction->base); + IrInstruction *linkage_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, linkage_field); + if (type_is_invalid(linkage_inst->value->type)) + return ira->codegen->invalid_instruction; + + TypeStructField *section_field = find_struct_type_field(options_type, buf_create_from_str("section")); + ir_assert(section_field != nullptr, &instruction->base); + IrInstruction *section_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, section_field); + if (type_is_invalid(section_inst->value->type)) return ira->codegen->invalid_instruction; - } - GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; - if (instruction->linkage != nullptr) { - IrInstruction *linkage_value = instruction->linkage->child; - if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { + // The `section` field is optional, we have to unwrap it first + IrInstruction *non_null_check = ir_analyze_test_non_null(ira, &instruction->base, section_inst); + bool is_non_null; + if (!ir_resolve_bool(ira, non_null_check, &is_non_null)) + return ira->codegen->invalid_instruction; + + IrInstruction *section_str_inst = nullptr; + if (is_non_null) { + section_str_inst = ir_analyze_optional_value_payload_value(ira, &instruction->base, section_inst, false); + if (type_is_invalid(section_str_inst->value->type)) return ira->codegen->invalid_instruction; - } } + // Resolve all the comptime values + Buf *symbol_name = ir_resolve_str(ira, name_inst); + if (!symbol_name) + return ira->codegen->invalid_instruction; + + GlobalLinkageId global_linkage_id; + if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) + return ira->codegen->invalid_instruction; + + Buf *section_name = nullptr; + if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) + return ira->codegen->invalid_instruction; + // TODO: This function needs to be audited. // It's not clear how all the different types are supposed to be handled. // Need comprehensive tests for exporting one thing in one file and declaring an extern var @@ -16721,6 +16757,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio return ira->codegen->invalid_instruction; } + Error err; bool want_var_export = false; switch (target->value->type->id) { case ZigTypeIdInvalid: @@ -16755,6 +16792,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case CallingConventionAAPCS: case CallingConventionAAPCSVFP: add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); + fn_entry->section_name = section_name; break; } } break; @@ -16896,6 +16934,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); ZigVar *var = var_ptr->var; add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id); + var->section_name = section_name; } } |
