@@ -220,8 +220,8 @@ fn isReservedIdent(ident: []const u8) bool {
220
220
'A' ... 'Z' , '_' = > return true ,
221
221
else = > return false ,
222
222
}
223
- } else if (std . mem .startsWith (u8 , ident , "DUMMYSTRUCTNAME" ) or
224
- std . mem .startsWith (u8 , ident , "DUMMYUNIONNAME" ))
223
+ } else if (mem .startsWith (u8 , ident , "DUMMYSTRUCTNAME" ) or
224
+ mem .startsWith (u8 , ident , "DUMMYUNIONNAME" ))
225
225
{ // windows.h
226
226
return true ;
227
227
} else return reserved_idents .has (ident );
@@ -279,8 +279,6 @@ pub const Function = struct {
279
279
/// by type alignment.
280
280
/// The value is whether the alloc needs to be emitted in the header.
281
281
allocs : std .AutoArrayHashMapUnmanaged (LocalIndex , bool ) = .{},
282
- /// Needed for memory used by the keys of free_locals_map entries.
283
- arena : std.heap.ArenaAllocator ,
284
282
285
283
fn resolveInst (f : * Function , ref : Air.Inst.Ref ) ! CValue {
286
284
if (Air .refToIndex (ref )) | inst | {
@@ -481,7 +479,6 @@ pub const Function = struct {
481
479
f .object .code .deinit ();
482
480
f .object .dg .ctypes .deinit (gpa );
483
481
f .object .dg .fwd_decl .deinit ();
484
- f .arena .deinit ();
485
482
}
486
483
};
487
484
@@ -501,7 +498,7 @@ pub const Object = struct {
501
498
502
499
/// This data is available both when outputting .c code and when outputting an .h file.
503
500
pub const DeclGen = struct {
504
- gpa : std. mem.Allocator ,
501
+ gpa : mem.Allocator ,
505
502
module : * Module ,
506
503
decl : ? * Decl ,
507
504
decl_index : Decl.OptionalIndex ,
@@ -539,6 +536,9 @@ pub const DeclGen = struct {
539
536
if (func .data .owner_decl != decl_index )
540
537
return dg .renderDeclValue (writer , ty , val , func .data .owner_decl , location );
541
538
539
+ if (decl .val .castTag (.variable )) | var_payload |
540
+ try dg .renderFwdDecl (decl_index , var_payload .data );
541
+
542
542
if (ty .isSlice ()) {
543
543
if (location == .StaticInitializer ) {
544
544
try writer .writeByte ('{' );
@@ -1819,8 +1819,23 @@ pub const DeclGen = struct {
1819
1819
try dg .writeCValue (writer , member );
1820
1820
}
1821
1821
1822
- const IdentHasher = std .crypto .auth .siphash .SipHash128 (1 , 3 );
1823
- const ident_hasher_init : IdentHasher = IdentHasher .init (&[_ ]u8 {0 } ** IdentHasher .key_length );
1822
+ fn renderFwdDecl (dg : * DeclGen , decl_index : Decl.Index , variable : * Module.Var ) ! void {
1823
+ const decl = dg .module .declPtr (decl_index );
1824
+ const fwd_decl_writer = dg .fwd_decl .writer ();
1825
+ const is_global = dg .declIsGlobal (.{ .ty = decl .ty , .val = decl .val }) or variable .is_extern ;
1826
+ try fwd_decl_writer .writeAll (if (is_global ) "zig_extern " else "static " );
1827
+ if (variable .is_threadlocal ) try fwd_decl_writer .writeAll ("zig_threadlocal " );
1828
+ if (variable .is_weak_linkage ) try fwd_decl_writer .writeAll ("zig_weak_linkage " );
1829
+ try dg .renderTypeAndName (
1830
+ fwd_decl_writer ,
1831
+ decl .ty ,
1832
+ .{ .decl = decl_index },
1833
+ CQualifiers .init (.{ .@"const" = ! variable .is_mutable }),
1834
+ decl .@"align" ,
1835
+ .complete ,
1836
+ );
1837
+ try fwd_decl_writer .writeAll (";\n " );
1838
+ }
1824
1839
1825
1840
fn renderDeclName (dg : * DeclGen , writer : anytype , decl_index : Decl.Index , export_index : u32 ) ! void {
1826
1841
const decl = dg .module .declPtr (decl_index );
@@ -1829,7 +1844,7 @@ pub const DeclGen = struct {
1829
1844
if (dg .module .decl_exports .get (decl_index )) | exports | {
1830
1845
try writer .writeAll (exports .items [export_index ].options .name );
1831
1846
} else if (decl .isExtern ()) {
1832
- try writer .writeAll (mem .sliceTo (decl .name , 0 ));
1847
+ try writer .writeAll (mem .span (decl .name ));
1833
1848
} else {
1834
1849
// MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
1835
1850
// expand to 3x the length of its input, but let's cut it off at a much shorter limit.
@@ -2396,9 +2411,9 @@ pub fn genErrDecls(o: *Object) !void {
2396
2411
const name_buf = try o .dg .gpa .alloc (u8 , name_prefix .len + max_name_len );
2397
2412
defer o .dg .gpa .free (name_buf );
2398
2413
2399
- std . mem .copy (u8 , name_buf , name_prefix );
2414
+ mem .copy (u8 , name_buf , name_prefix );
2400
2415
for (o .dg .module .error_name_list .items ) | name | {
2401
- std . mem .copy (u8 , name_buf [name_prefix .len .. ], name );
2416
+ mem .copy (u8 , name_buf [name_prefix .len .. ], name );
2402
2417
const identifier = name_buf [0 .. name_prefix .len + name .len ];
2403
2418
2404
2419
var name_ty_pl = Type.Payload.Len { .base = .{ .tag = .array_u8_sentinel_0 }, .data = name .len };
@@ -2644,21 +2659,16 @@ pub fn genDecl(o: *Object) !void {
2644
2659
try genExports (o );
2645
2660
} else if (tv .val .castTag (.variable )) | var_payload | {
2646
2661
const variable : * Module.Var = var_payload .data ;
2647
-
2648
- const is_global = o .dg .declIsGlobal (tv ) or variable .is_extern ;
2649
- const fwd_decl_writer = o .dg .fwd_decl .writer ();
2650
-
2651
- try fwd_decl_writer .writeAll (if (is_global ) "zig_extern " else "static " );
2652
- if (variable .is_threadlocal ) try fwd_decl_writer .writeAll ("zig_threadlocal " );
2653
- try o .dg .renderTypeAndName (fwd_decl_writer , decl .ty , decl_c_value , .{}, decl .@"align" , .complete );
2654
- try fwd_decl_writer .writeAll (";\n " );
2662
+ try o .dg .renderFwdDecl (decl_c_value .decl , variable );
2655
2663
try genExports (o );
2656
2664
2657
2665
if (variable .is_extern ) return ;
2658
2666
2667
+ const is_global = o .dg .declIsGlobal (tv ) or variable .is_extern ;
2659
2668
const w = o .writer ();
2660
2669
if (! is_global ) try w .writeAll ("static " );
2661
2670
if (variable .is_threadlocal ) try w .writeAll ("zig_threadlocal " );
2671
+ if (variable .is_weak_linkage ) try w .writeAll ("zig_weak_linkage " );
2662
2672
if (decl .@"linksection") |section| try w.print("zig_linksection(\" {s }\", " , .{section });
2663
2673
try o .dg .renderTypeAndName (w , tv .ty , decl_c_value , .{}, decl .@"align" , .complete );
2664
2674
if (decl .@"linksection" != null ) try w .writeAll (", read, write)" );
@@ -3396,7 +3406,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3396
3406
var deref = is_ptr ;
3397
3407
const is_array = lowersToArray (ret_ty , target );
3398
3408
const ret_val = if (is_array ) ret_val : {
3399
- const array_local = try f .allocLocal (inst , try lowered_ret_ty . copy ( f . arena . allocator ()) );
3409
+ const array_local = try f .allocLocal (inst , lowered_ret_ty );
3400
3410
try writer .writeAll ("memcpy(" );
3401
3411
try f .writeCValueMember (writer , array_local , .{ .identifier = "array" });
3402
3412
try writer .writeAll (", " );
@@ -4113,7 +4123,7 @@ fn airCall(
4113
4123
var lowered_arg_buf : LowerFnRetTyBuffer = undefined ;
4114
4124
const lowered_arg_ty = lowerFnRetTy (arg_ty , & lowered_arg_buf , target );
4115
4125
4116
- const array_local = try f .allocLocal (inst , try lowered_arg_ty . copy ( f . arena . allocator ()) );
4126
+ const array_local = try f .allocLocal (inst , lowered_arg_ty );
4117
4127
try writer .writeAll ("memcpy(" );
4118
4128
try f .writeCValueMember (writer , array_local , .{ .identifier = "array" });
4119
4129
try writer .writeAll (", " );
@@ -4156,7 +4166,7 @@ fn airCall(
4156
4166
try writer .writeByte (')' );
4157
4167
break :result .none ;
4158
4168
} else {
4159
- const local = try f .allocLocal (inst , try lowered_ret_ty . copy ( f . arena . allocator ()) );
4169
+ const local = try f .allocLocal (inst , lowered_ret_ty );
4160
4170
try f .writeCValue (writer , local , .Other );
4161
4171
try writer .writeAll (" = " );
4162
4172
break :result local ;
@@ -4732,9 +4742,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4732
4742
const locals_begin = @intCast (LocalIndex , f .locals .items .len );
4733
4743
const constraints_extra_begin = extra_i ;
4734
4744
for (outputs ) | output | {
4735
- const extra_bytes = std . mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4736
- const constraint = std . mem .sliceTo (extra_bytes , 0 );
4737
- const name = std . mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4745
+ const extra_bytes = mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4746
+ const constraint = mem .sliceTo (extra_bytes , 0 );
4747
+ const name = mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4738
4748
// This equation accounts for the fact that even if we have exactly 4 bytes
4739
4749
// for the string, we still use the next u32 for the null terminator.
4740
4750
extra_i += (constraint .len + name .len + (2 + 3 )) / 4 ;
@@ -4764,14 +4774,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4764
4774
}
4765
4775
}
4766
4776
for (inputs ) | input | {
4767
- const extra_bytes = std . mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4768
- const constraint = std . mem .sliceTo (extra_bytes , 0 );
4769
- const name = std . mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4777
+ const extra_bytes = mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4778
+ const constraint = mem .sliceTo (extra_bytes , 0 );
4779
+ const name = mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4770
4780
// This equation accounts for the fact that even if we have exactly 4 bytes
4771
4781
// for the string, we still use the next u32 for the null terminator.
4772
4782
extra_i += (constraint .len + name .len + (2 + 3 )) / 4 ;
4773
4783
4774
- if (constraint .len < 1 or std . mem .indexOfScalar (u8 , "=+&%" , constraint [0 ]) != null or
4784
+ if (constraint .len < 1 or mem .indexOfScalar (u8 , "=+&%" , constraint [0 ]) != null or
4775
4785
(constraint [0 ] == '{' and constraint [constraint .len - 1 ] != '}' ))
4776
4786
{
4777
4787
return f .fail ("CBE: constraint not supported: '{s}'" , .{constraint });
@@ -4797,7 +4807,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4797
4807
}
4798
4808
}
4799
4809
for (0.. clobbers_len ) | _ | {
4800
- const clobber = std . mem .sliceTo (std . mem .sliceAsBytes (f .air .extra [extra_i .. ]), 0 );
4810
+ const clobber = mem .sliceTo (mem .sliceAsBytes (f .air .extra [extra_i .. ]), 0 );
4801
4811
// This equation accounts for the fact that even if we have exactly 4 bytes
4802
4812
// for the string, we still use the next u32 for the null terminator.
4803
4813
extra_i += clobber .len / 4 + 1 ;
@@ -4862,16 +4872,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4862
4872
var locals_index = locals_begin ;
4863
4873
try writer .writeByte (':' );
4864
4874
for (outputs , 0.. ) | output , index | {
4865
- const extra_bytes = std . mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4866
- const constraint = std . mem .sliceTo (extra_bytes , 0 );
4867
- const name = std . mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4875
+ const extra_bytes = mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4876
+ const constraint = mem .sliceTo (extra_bytes , 0 );
4877
+ const name = mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4868
4878
// This equation accounts for the fact that even if we have exactly 4 bytes
4869
4879
// for the string, we still use the next u32 for the null terminator.
4870
4880
extra_i += (constraint .len + name .len + (2 + 3 )) / 4 ;
4871
4881
4872
4882
if (index > 0 ) try writer .writeByte (',' );
4873
4883
try writer .writeByte (' ' );
4874
- if (! std . mem .eql (u8 , name , "_" )) try writer .print ("[{s}]" , .{name });
4884
+ if (! mem .eql (u8 , name , "_" )) try writer .print ("[{s}]" , .{name });
4875
4885
const is_reg = constraint [1 ] == '{' ;
4876
4886
try writer .print ("{s}(" , .{fmtStringLiteral (if (is_reg ) "=r" else constraint , null )});
4877
4887
if (is_reg ) {
@@ -4886,16 +4896,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4886
4896
}
4887
4897
try writer .writeByte (':' );
4888
4898
for (inputs , 0.. ) | input , index | {
4889
- const extra_bytes = std . mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4890
- const constraint = std . mem .sliceTo (extra_bytes , 0 );
4891
- const name = std . mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4899
+ const extra_bytes = mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4900
+ const constraint = mem .sliceTo (extra_bytes , 0 );
4901
+ const name = mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4892
4902
// This equation accounts for the fact that even if we have exactly 4 bytes
4893
4903
// for the string, we still use the next u32 for the null terminator.
4894
4904
extra_i += (constraint .len + name .len + (2 + 3 )) / 4 ;
4895
4905
4896
4906
if (index > 0 ) try writer .writeByte (',' );
4897
4907
try writer .writeByte (' ' );
4898
- if (! std . mem .eql (u8 , name , "_" )) try writer .print ("[{s}]" , .{name });
4908
+ if (! mem .eql (u8 , name , "_" )) try writer .print ("[{s}]" , .{name });
4899
4909
4900
4910
const is_reg = constraint [0 ] == '{' ;
4901
4911
const input_val = try f .resolveInst (input );
@@ -4909,7 +4919,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4909
4919
}
4910
4920
try writer .writeByte (':' );
4911
4921
for (0.. clobbers_len ) | clobber_i | {
4912
- const clobber = std . mem .sliceTo (std . mem .sliceAsBytes (f .air .extra [extra_i .. ]), 0 );
4922
+ const clobber = mem .sliceTo (mem .sliceAsBytes (f .air .extra [extra_i .. ]), 0 );
4913
4923
// This equation accounts for the fact that even if we have exactly 4 bytes
4914
4924
// for the string, we still use the next u32 for the null terminator.
4915
4925
extra_i += clobber .len / 4 + 1 ;
@@ -4924,9 +4934,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4924
4934
extra_i = constraints_extra_begin ;
4925
4935
locals_index = locals_begin ;
4926
4936
for (outputs ) | output | {
4927
- const extra_bytes = std . mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4928
- const constraint = std . mem .sliceTo (extra_bytes , 0 );
4929
- const name = std . mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4937
+ const extra_bytes = mem .sliceAsBytes (f .air .extra [extra_i .. ]);
4938
+ const constraint = mem .sliceTo (extra_bytes , 0 );
4939
+ const name = mem .sliceTo (extra_bytes [constraint .len + 1 .. ], 0 );
4930
4940
// This equation accounts for the fact that even if we have exactly 4 bytes
4931
4941
// for the string, we still use the next u32 for the null terminator.
4932
4942
extra_i += (constraint .len + name .len + (2 + 3 )) / 4 ;
@@ -5363,7 +5373,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5363
5373
};
5364
5374
const field_int_ty = Type .initPayload (& field_int_pl .base );
5365
5375
5366
- const temp_local = try f .allocLocal (inst , try field_int_ty . copy ( f . arena . allocator ()) );
5376
+ const temp_local = try f .allocLocal (inst , field_int_ty );
5367
5377
try f .writeCValue (writer , temp_local , .Other );
5368
5378
try writer .writeAll (" = zig_wrap_" );
5369
5379
try f .object .dg .renderTypeForBuiltinFnName (writer , field_int_ty );
@@ -7277,7 +7287,7 @@ fn formatIntLiteral(
7277
7287
var int_buf : Value.BigIntSpace = undefined ;
7278
7288
const int = if (data .val .isUndefDeep ()) blk : {
7279
7289
undef_limbs = try allocator .alloc (BigIntLimb , BigInt .calcTwosCompLimbCount (data .int_info .bits ));
7280
- std . mem .set (BigIntLimb , undef_limbs , undefPattern (BigIntLimb ));
7290
+ mem .set (BigIntLimb , undef_limbs , undefPattern (BigIntLimb ));
7281
7291
7282
7292
var undef_int = BigInt.Mutable {
7283
7293
.limbs = undef_limbs ,
@@ -7372,7 +7382,7 @@ fn formatIntLiteral(
7372
7382
} else {
7373
7383
try data .cty .renderLiteralPrefix (writer , data .kind );
7374
7384
wrap .convertToTwosComplement (int , data .int_info .signedness , c_bits );
7375
- std . mem .set (BigIntLimb , wrap .limbs [wrap .len .. ], 0 );
7385
+ mem .set (BigIntLimb , wrap .limbs [wrap .len .. ], 0 );
7376
7386
wrap .len = wrap .limbs .len ;
7377
7387
const limbs_per_c_limb = @divExact (wrap .len , c_limb_info .count );
7378
7388
0 commit comments