| ... | ... | @@ -2074,11 +2074,11 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A |
| 2074 | 2074 | } |
| 2075 | 2075 | |
| 2076 | 2076 | static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2077 | | TldVar *tld_var, IrInstruction *value) |
| 2077 | Tld *tld, IrInstruction *value) |
| 2078 | 2078 | { |
| 2079 | 2079 | IrInstructionSetGlobalAlign *instruction = ir_build_instruction<IrInstructionSetGlobalAlign>( |
| 2080 | 2080 | irb, scope, source_node); |
| 2081 | | instruction->tld_var = tld_var; |
| 2081 | instruction->tld = tld; |
| 2082 | 2082 | instruction->value = value; |
| 2083 | 2083 | |
| 2084 | 2084 | ir_ref_instruction(value, irb->current_basic_block); |
| ... | ... | @@ -2087,11 +2087,11 @@ static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, As |
| 2087 | 2087 | } |
| 2088 | 2088 | |
| 2089 | 2089 | static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2090 | | TldVar *tld_var, IrInstruction *value) |
| 2090 | Tld *tld, IrInstruction *value) |
| 2091 | 2091 | { |
| 2092 | 2092 | IrInstructionSetGlobalSection *instruction = ir_build_instruction<IrInstructionSetGlobalSection>( |
| 2093 | 2093 | irb, scope, source_node); |
| 2094 | | instruction->tld_var = tld_var; |
| 2094 | instruction->tld = tld; |
| 2095 | 2095 | instruction->value = value; |
| 2096 | 2096 | |
| 2097 | 2097 | ir_ref_instruction(value, irb->current_basic_block); |
| ... | ... | @@ -4192,22 +4192,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4192 | 4192 | buf_ptr(variable_name))); |
| 4193 | 4193 | return irb->codegen->invalid_instruction; |
| 4194 | 4194 | } |
| 4195 | | if (tld->id != TldIdVar) { |
| 4196 | | add_node_error(irb->codegen, node, buf_sprintf("'%s' is not a global variable", |
| 4195 | if (tld->id != TldIdVar && tld->id != TldIdFn) { |
| 4196 | add_node_error(irb->codegen, node, buf_sprintf("'%s' must be global variable or function", |
| 4197 | 4197 | buf_ptr(variable_name))); |
| 4198 | 4198 | return irb->codegen->invalid_instruction; |
| 4199 | 4199 | } |
| 4200 | | TldVar *tld_var = (TldVar *)tld; |
| 4201 | | |
| 4202 | 4200 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4203 | 4201 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| 4204 | 4202 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4205 | 4203 | return arg1_value; |
| 4206 | 4204 | |
| 4207 | 4205 | if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) { |
| 4208 | | return ir_build_set_global_align(irb, scope, node, tld_var, arg1_value); |
| 4206 | return ir_build_set_global_align(irb, scope, node, tld, arg1_value); |
| 4209 | 4207 | } else { |
| 4210 | | return ir_build_set_global_section(irb, scope, node, tld_var, arg1_value); |
| 4208 | return ir_build_set_global_section(irb, scope, node, tld, arg1_value); |
| 4211 | 4209 | } |
| 4212 | 4210 | } |
| 4213 | 4211 | } |
| ... | ... | @@ -9472,7 +9470,7 @@ static bool is_power_of_2(uint64_t x) { |
| 9472 | 9470 | static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, |
| 9473 | 9471 | IrInstructionSetGlobalAlign *instruction) |
| 9474 | 9472 | { |
| 9475 | | TldVar *tld_var = instruction->tld_var; |
| 9473 | Tld *tld = instruction->tld; |
| 9476 | 9474 | IrInstruction *align_value = instruction->value->other; |
| 9477 | 9475 | |
| 9478 | 9476 | uint64_t scalar_align; |
| ... | ... | @@ -9484,15 +9482,31 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, |
| 9484 | 9482 | return ira->codegen->builtin_types.entry_invalid; |
| 9485 | 9483 | } |
| 9486 | 9484 | |
| 9485 | AstNode **set_global_align_node; |
| 9486 | uint64_t *alignment_ptr; |
| 9487 | if (tld->id == TldIdVar) { |
| 9488 | TldVar *tld_var = (TldVar *)tld; |
| 9489 | set_global_align_node = &tld_var->set_global_align_node; |
| 9490 | alignment_ptr = &tld_var->alignment; |
| 9491 | } else if (tld->id == TldIdFn) { |
| 9492 | TldFn *tld_fn = (TldFn *)tld; |
| 9493 | FnTableEntry *fn_entry = tld_fn->fn_entry; |
| 9494 | set_global_align_node = &fn_entry->set_global_align_node; |
| 9495 | alignment_ptr = &fn_entry->alignment; |
| 9496 | } else { |
| 9497 | // error is caught in pass1 IR gen |
| 9498 | zig_unreachable(); |
| 9499 | } |
| 9500 | |
| 9487 | 9501 | AstNode *source_node = instruction->base.source_node; |
| 9488 | | if (tld_var->set_global_align_node) { |
| 9502 | if (*set_global_align_node) { |
| 9489 | 9503 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 9490 | 9504 | buf_sprintf("alignment set twice")); |
| 9491 | | add_error_note(ira->codegen, msg, tld_var->set_global_align_node, buf_sprintf("first set here")); |
| 9505 | add_error_note(ira->codegen, msg, *set_global_align_node, buf_sprintf("first set here")); |
| 9492 | 9506 | return ira->codegen->builtin_types.entry_invalid; |
| 9493 | 9507 | } |
| 9494 | | tld_var->set_global_align_node = source_node; |
| 9495 | | tld_var->alignment = scalar_align; |
| 9508 | *set_global_align_node = source_node; |
| 9509 | *alignment_ptr = scalar_align; |
| 9496 | 9510 | |
| 9497 | 9511 | ir_build_const_from(ira, &instruction->base, false); |
| 9498 | 9512 | return ira->codegen->builtin_types.entry_void; |
| ... | ... | @@ -9501,21 +9515,37 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, |
| 9501 | 9515 | static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira, |
| 9502 | 9516 | IrInstructionSetGlobalSection *instruction) |
| 9503 | 9517 | { |
| 9504 | | TldVar *tld_var = instruction->tld_var; |
| 9518 | Tld *tld = instruction->tld; |
| 9505 | 9519 | IrInstruction *section_value = instruction->value->other; |
| 9506 | 9520 | |
| 9507 | 9521 | Buf *section_name = ir_resolve_str(ira, section_value); |
| 9508 | 9522 | if (!section_name) |
| 9509 | 9523 | return ira->codegen->builtin_types.entry_invalid; |
| 9510 | 9524 | |
| 9525 | AstNode **set_global_section_node; |
| 9526 | Buf **section_name_ptr; |
| 9527 | if (tld->id == TldIdVar) { |
| 9528 | TldVar *tld_var = (TldVar *)tld; |
| 9529 | set_global_section_node = &tld_var->set_global_section_node; |
| 9530 | section_name_ptr = &tld_var->section_name; |
| 9531 | } else if (tld->id == TldIdFn) { |
| 9532 | TldFn *tld_fn = (TldFn *)tld; |
| 9533 | FnTableEntry *fn_entry = tld_fn->fn_entry; |
| 9534 | set_global_section_node = &fn_entry->set_global_section_node; |
| 9535 | section_name_ptr = &fn_entry->section_name; |
| 9536 | } else { |
| 9537 | // error is caught in pass1 IR gen |
| 9538 | zig_unreachable(); |
| 9539 | } |
| 9540 | |
| 9511 | 9541 | AstNode *source_node = instruction->base.source_node; |
| 9512 | | if (tld_var->set_global_section_node) { |
| 9542 | if (*set_global_section_node) { |
| 9513 | 9543 | ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("section set twice")); |
| 9514 | | add_error_note(ira->codegen, msg, tld_var->set_global_section_node, buf_sprintf("first set here")); |
| 9544 | add_error_note(ira->codegen, msg, *set_global_section_node, buf_sprintf("first set here")); |
| 9515 | 9545 | return ira->codegen->builtin_types.entry_invalid; |
| 9516 | 9546 | } |
| 9517 | | tld_var->set_global_section_node = source_node; |
| 9518 | | tld_var->section_name = section_name; |
| 9547 | *set_global_section_node = source_node; |
| 9548 | *section_name_ptr = section_name; |
| 9519 | 9549 | |
| 9520 | 9550 | ir_build_const_from(ira, &instruction->base, false); |
| 9521 | 9551 | return ira->codegen->builtin_types.entry_void; |