@@ -494,6 +494,49 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
494
494
// use the ABI alignment, which is fine.
495
495
}
496
496
497
+ if (!type_has_bits (fn_type->data .fn .fn_type_id .return_type )) {
498
+ // nothing to do
499
+ } else if (fn_type->data .fn .fn_type_id .return_type ->id == TypeTableEntryIdPointer ||
500
+ fn_type->data .fn .fn_type_id .return_type ->id == TypeTableEntryIdFn)
501
+ {
502
+ addLLVMAttr (fn_table_entry->llvm_value , 0 , " nonnull" );
503
+ } else if (handle_is_ptr (fn_type->data .fn .fn_type_id .return_type ) &&
504
+ calling_convention_does_first_arg_return (fn_type->data .fn .fn_type_id .cc ))
505
+ {
506
+ addLLVMArgAttr (fn_table_entry->llvm_value , 0 , " sret" );
507
+ addLLVMArgAttr (fn_table_entry->llvm_value , 0 , " nonnull" );
508
+ }
509
+
510
+
511
+ // set parameter attributes
512
+ for (size_t param_i = 0 ; param_i < fn_type->data .fn .fn_type_id .param_count ; param_i += 1 ) {
513
+ FnGenParamInfo *gen_info = &fn_type->data .fn .gen_param_info [param_i];
514
+ size_t gen_index = gen_info->gen_index ;
515
+ bool is_byval = gen_info->is_byval ;
516
+
517
+ if (gen_index == SIZE_MAX) {
518
+ continue ;
519
+ }
520
+
521
+ FnTypeParamInfo *param_info = &fn_type->data .fn .fn_type_id .param_info [param_i];
522
+
523
+ TypeTableEntry *param_type = gen_info->type ;
524
+ if (param_info->is_noalias ) {
525
+ addLLVMArgAttr (fn_table_entry->llvm_value , (unsigned )gen_index, " noalias" );
526
+ }
527
+ if ((param_type->id == TypeTableEntryIdPointer && param_type->data .pointer .is_const ) || is_byval) {
528
+ addLLVMArgAttr (fn_table_entry->llvm_value , (unsigned )gen_index, " readonly" );
529
+ }
530
+ if (param_type->id == TypeTableEntryIdPointer) {
531
+ addLLVMArgAttr (fn_table_entry->llvm_value , (unsigned )gen_index, " nonnull" );
532
+ }
533
+ // Note: byval is disabled on windows due to an LLVM bug:
534
+ // https://github.com/zig-lang/zig/issues/536
535
+ if (is_byval && g->zig_target .os != ZigLLVM_Win32) {
536
+ addLLVMArgAttr (fn_table_entry->llvm_value , (unsigned )gen_index, " byval" );
537
+ }
538
+ }
539
+
497
540
return fn_table_entry->llvm_value ;
498
541
}
499
542
@@ -4298,59 +4341,6 @@ static void do_code_gen(CodeGen *g) {
4298
4341
var->value_ref = global_value;
4299
4342
}
4300
4343
4301
- // Generate function prototypes
4302
- for (size_t fn_proto_i = 0 ; fn_proto_i < g->fn_protos .length ; fn_proto_i += 1 ) {
4303
- FnTableEntry *fn_table_entry = g->fn_protos .at (fn_proto_i);
4304
-
4305
- TypeTableEntry *fn_type = fn_table_entry->type_entry ;
4306
- FnTypeId *fn_type_id = &fn_type->data .fn .fn_type_id ;
4307
-
4308
- LLVMValueRef fn_val = fn_llvm_value (g, fn_table_entry);
4309
-
4310
- if (!type_has_bits (fn_type->data .fn .fn_type_id .return_type )) {
4311
- // nothing to do
4312
- } else if (fn_type->data .fn .fn_type_id .return_type ->id == TypeTableEntryIdPointer ||
4313
- fn_type->data .fn .fn_type_id .return_type ->id == TypeTableEntryIdFn)
4314
- {
4315
- addLLVMAttr (fn_val, 0 , " nonnull" );
4316
- } else if (handle_is_ptr (fn_type->data .fn .fn_type_id .return_type ) &&
4317
- calling_convention_does_first_arg_return (fn_type->data .fn .fn_type_id .cc ))
4318
- {
4319
- addLLVMArgAttr (fn_val, 0 , " sret" );
4320
- addLLVMArgAttr (fn_val, 0 , " nonnull" );
4321
- }
4322
-
4323
-
4324
- // set parameter attributes
4325
- for (size_t param_i = 0 ; param_i < fn_type_id->param_count ; param_i += 1 ) {
4326
- FnGenParamInfo *gen_info = &fn_type->data .fn .gen_param_info [param_i];
4327
- size_t gen_index = gen_info->gen_index ;
4328
- bool is_byval = gen_info->is_byval ;
4329
-
4330
- if (gen_index == SIZE_MAX) {
4331
- continue ;
4332
- }
4333
-
4334
- FnTypeParamInfo *param_info = &fn_type_id->param_info [param_i];
4335
-
4336
- TypeTableEntry *param_type = gen_info->type ;
4337
- if (param_info->is_noalias ) {
4338
- addLLVMArgAttr (fn_val, (unsigned )gen_index, " noalias" );
4339
- }
4340
- if ((param_type->id == TypeTableEntryIdPointer && param_type->data .pointer .is_const ) || is_byval) {
4341
- addLLVMArgAttr (fn_val, (unsigned )gen_index, " readonly" );
4342
- }
4343
- if (param_type->id == TypeTableEntryIdPointer) {
4344
- addLLVMArgAttr (fn_val, (unsigned )gen_index, " nonnull" );
4345
- }
4346
- // Note: byval is disabled on windows due to an LLVM bug:
4347
- // https://github.com/zig-lang/zig/issues/536
4348
- if (is_byval && g->zig_target .os != ZigLLVM_Win32) {
4349
- addLLVMArgAttr (fn_val, (unsigned )gen_index, " byval" );
4350
- }
4351
- }
4352
- }
4353
-
4354
4344
// Generate function definitions.
4355
4345
for (size_t fn_i = 0 ; fn_i < g->fn_defs .length ; fn_i += 1 ) {
4356
4346
FnTableEntry *fn_table_entry = g->fn_defs .at (fn_i);
0 commit comments