@@ -613,6 +613,10 @@ static void destroy_instruction(IrInstruction *inst) {
613
613
return destroy(reinterpret_cast<IrInstructionSpillEnd *>(inst), name);
614
614
case IrInstructionIdVectorExtractElem:
615
615
return destroy(reinterpret_cast<IrInstructionVectorExtractElem *>(inst), name);
616
+ case IrInstructionIdExternWeakSrc:
617
+ return destroy(reinterpret_cast<IrInstructionExternWeakSrc *>(inst), name);
618
+ case IrInstructionIdExternWeakGen:
619
+ return destroy(reinterpret_cast<IrInstructionExternWeakGen *>(inst), name);
616
620
}
617
621
zig_unreachable();
618
622
}
@@ -891,6 +895,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarSrc *) {
891
895
return IrInstructionIdDeclVarSrc;
892
896
}
893
897
898
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionExternWeakSrc *) {
899
+ return IrInstructionIdExternWeakSrc;
900
+ }
901
+
902
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionExternWeakGen *) {
903
+ return IrInstructionIdExternWeakGen;
904
+ }
905
+
894
906
static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarGen *) {
895
907
return IrInstructionIdDeclVarGen;
896
908
}
@@ -1603,6 +1615,32 @@ static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_nod
1603
1615
return special_instruction;
1604
1616
}
1605
1617
1618
+ static IrInstruction *ir_build_extern_weak_src(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name,
1619
+ IrInstruction *ptr_type, ResultLoc *result_loc)
1620
+ {
1621
+ IrInstructionExternWeakSrc *instruction = ir_build_instruction<IrInstructionExternWeakSrc>(irb, scope, source_node);
1622
+ instruction->name = name;
1623
+ instruction->ptr_type = ptr_type;
1624
+ instruction->result_loc = result_loc;
1625
+
1626
+ ir_ref_instruction(name, irb->current_basic_block);
1627
+ ir_ref_instruction(ptr_type, irb->current_basic_block);
1628
+
1629
+ return &instruction->base;
1630
+ }
1631
+
1632
+ static IrInstruction *ir_build_extern_weak_gen(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *name,
1633
+ IrInstruction *result_loc)
1634
+ {
1635
+ IrInstructionExternWeakGen *instruction = ir_build_instruction<IrInstructionExternWeakGen>(irb, scope, source_node);
1636
+ instruction->name = name;
1637
+ instruction->result_loc = result_loc;
1638
+
1639
+ ir_ref_instruction(result_loc, irb->current_basic_block);
1640
+
1641
+ return &instruction->base;
1642
+ }
1643
+
1606
1644
static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type,
1607
1645
IrInstruction *value, CastOp cast_op)
1608
1646
{
@@ -6461,6 +6499,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
6461
6499
IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value);
6462
6500
return ir_lval_wrap(irb, scope, has_decl, lval, result_loc);
6463
6501
}
6502
+ case BuiltinFnIdExternWeak:
6503
+ {
6504
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6505
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
6506
+ if (arg0_value == irb->codegen->invalid_instruction)
6507
+ return arg0_value;
6508
+
6509
+ AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6510
+ IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
6511
+ if (arg1_value == irb->codegen->invalid_instruction)
6512
+ return arg1_value;
6513
+
6514
+ IrInstruction *extern_weak = ir_build_extern_weak_src(irb, scope, node, arg0_value, arg1_value, result_loc);
6515
+ return ir_lval_wrap(irb, scope, extern_weak, lval, result_loc);
6516
+ }
6464
6517
case BuiltinFnIdUnionInit:
6465
6518
{
6466
6519
AstNode *union_type_node = node->data.fn_call_expr.params.at(0);
@@ -26692,6 +26745,44 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
26692
26745
instruction->safety_check_on);
26693
26746
}
26694
26747
26748
+ static IrInstruction *ir_analyze_instruction_extern_weak_src(IrAnalyze *ira, IrInstructionExternWeakSrc *instruction) {
26749
+ IrInstruction *name_value = instruction->name->child;
26750
+ Buf *symbol_name = ir_resolve_str(ira, name_value);
26751
+ if (symbol_name == nullptr)
26752
+ return ira->codegen->invalid_instruction;
26753
+
26754
+ if (buf_len(symbol_name) == 0) {
26755
+ ir_add_error_node(ira, instruction->name->source_node,
26756
+ buf_sprintf("symbol name cannot be empty"));
26757
+ return ira->codegen->invalid_instruction;
26758
+ }
26759
+
26760
+ IrInstruction *ptr_type_value = instruction->ptr_type->child;
26761
+ ZigType *ptr_type = ir_resolve_type(ira, ptr_type_value);
26762
+ if (type_is_invalid(ptr_type))
26763
+ return ira->codegen->invalid_instruction;
26764
+
26765
+ if (ptr_type->id != ZigTypeIdPointer) {
26766
+ ir_add_error_node(ira, instruction->ptr_type->source_node,
26767
+ buf_sprintf("a pointer type is required, got '%s'", buf_ptr(&ptr_type->name)));
26768
+ return ira->codegen->invalid_instruction;
26769
+ }
26770
+
26771
+ ZigType *opt_ptr_type = get_optional_type(ira->codegen, ptr_type);
26772
+
26773
+ IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
26774
+ opt_ptr_type, nullptr, true, false, true);
26775
+ if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) {
26776
+ return result_loc;
26777
+ }
26778
+
26779
+ IrInstruction *result = ir_build_extern_weak_gen(&ira->new_irb, instruction->base.scope,
26780
+ instruction->base.source_node, symbol_name, result_loc);
26781
+ result->value->type = opt_ptr_type;
26782
+
26783
+ return result;
26784
+ }
26785
+
26695
26786
static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) {
26696
26787
size_t buf_i = 0;
26697
26788
// TODO optimize the buf case
@@ -28397,6 +28488,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
28397
28488
case IrInstructionIdVectorExtractElem:
28398
28489
case IrInstructionIdVectorStoreElem:
28399
28490
case IrInstructionIdAsmGen:
28491
+ case IrInstructionIdExternWeakGen:
28400
28492
zig_unreachable();
28401
28493
28402
28494
case IrInstructionIdReturn:
@@ -28583,6 +28675,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
28583
28675
return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
28584
28676
case IrInstructionIdPtrCastSrc:
28585
28677
return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction);
28678
+ case IrInstructionIdExternWeakSrc:
28679
+ return ir_analyze_instruction_extern_weak_src(ira, (IrInstructionExternWeakSrc *)instruction);
28586
28680
case IrInstructionIdIntToPtr:
28587
28681
return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
28588
28682
case IrInstructionIdPtrToInt:
@@ -28875,6 +28969,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
28875
28969
case IrInstructionIdAwaitSrc:
28876
28970
case IrInstructionIdAwaitGen:
28877
28971
case IrInstructionIdSpillBegin:
28972
+ case IrInstructionIdExternWeakSrc:
28973
+ case IrInstructionIdExternWeakGen:
28878
28974
return true;
28879
28975
28880
28976
case IrInstructionIdPhi:
0 commit comments