feat(ast2ir): 添加数组初始化支持和AST转IR优化

添加了对未知长度数组的自动长度推导功能,支持字符串字面量和复合
初始化的数组长度计算。新增辅助函数resolve_array_length用于计算
数组实际长度,以及emit_array_initialization用于生成数组初始化
代码。

同时将AST转IR过程中的参数改为const引用,提高代码安全性。
新增IR构建器的借用检查机制,防止在借用期间进行重分配操作。

fix(ast): 为AST结构体添加详细注释说明字段用途
This commit is contained in:
zzy
2026-04-13 11:36:52 +08:00
parent 694778e4a0
commit ffb23afaf4
13 changed files with 480 additions and 220 deletions

View File

@@ -10,6 +10,11 @@ void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog) {
builder->cprog = cprog;
scc_ir_ctx_init(&builder->ctx, GET_MODULE(builder));
#ifndef SCC_NO_DEBUG
builder->borrow_depth = 0;
builder->dbg_file = nullptr;
builder->dbg_line = 0;
#endif
}
void scc_ir_builder_drop(scc_ir_builder_t *builder) {
@@ -19,6 +24,7 @@ void scc_ir_builder_drop(scc_ir_builder_t *builder) {
scc_ir_func_ref_t scc_ir_builder_func(scc_ir_builder_t *builder,
scc_ir_type_ref_t type_ref,
const char *name) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_func_ref_t func_ref =
scc_ir_ctx_declare_func(&builder->ctx, type_ref, name);
scc_vec_push(builder->cprog->func_decls, func_ref);
@@ -27,43 +33,108 @@ scc_ir_func_ref_t scc_ir_builder_func(scc_ir_builder_t *builder,
scc_ir_type_ref_t scc_ir_builder_type(scc_ir_builder_t *builder,
const scc_ir_type_t *type_desc) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
return scc_ir_ctx_get_type(&builder->ctx, type_desc);
}
scc_ir_value_ref_t scc_ir_builder_const_string(scc_ir_builder_t *builder,
const char *str, usize len) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_type_ref_t u8_type = scc_ir_builder_type_u8(builder);
scc_ir_type_t array_type = {
.tag = SCC_IR_TYPE_ARRAY,
.data.array.base = u8_type,
.data.array.len = len - 1, // 包含 nullptr 结尾
};
scc_ir_type_ref_t array_type_ref =
scc_ir_ctx_get_type(&builder->ctx, &array_type);
// 5. 创建聚合节点
scc_ir_value_t const_array_value = {
.tag = SCC_IR_VALUE_TAG_CONST_ARRAY,
.type = array_type_ref,
.data.const_array.base_type = u8_type,
};
char *buff = scc_malloc(len - 1);
Assert(buff);
// FIXME content to real string
for (usize i = 1; i < len - 1; i++) {
buff[i - 1] = str[i];
}
buff[len - 2] = '\0';
scc_vec_unsafe_from_buffer(const_array_value.data.const_array.fields,
(u8 *)buff, len - 1);
scc_ir_value_ref_t const_array_ref =
scc_ir_module_add_value(builder->ctx.module, &const_array_value);
Assert(const_array_ref != SCC_IR_REF_nullptr);
// 3. 创建全局变量节点,类型为指针,初始值指向常量数组
scc_ir_value_ref_t global_value_ref =
scc_ir_builder_global_alloca(builder, array_type_ref, const_array_ref);
// scc_hashtable_insert(builder);
scc_ir_value_ref_t pointer_to_global_value = scc_ir_module_add_value(
builder->ctx.module,
&(scc_ir_value_t){
.tag = SCC_IR_VALUE_TAG_GET_ELEM_PTR,
.data.get_elem_ptr.src_addr = global_value_ref,
.data.get_elem_ptr.index = SCC_IR_VALUE_TAG_NULLPTR,
});
scc_ir_builder_add_instr(builder, pointer_to_global_value);
return pointer_to_global_value;
}
void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
scc_ir_func_ref_t func_ref,
const char **param_names) {
// 创建函数并设置为当前函数
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
builder->current_func = func_ref;
scc_ir_func_t *func_ptr =
scc_ir_module_get_func(GET_MODULE(builder), func_ref);
scc_ir_type_t *func_type =
scc_ir_module_get_type(GET_MODULE(builder), func_ptr->type);
// 借用 func_ptr 和 func_type 以获取参数类型列表
scc_ir_func_t *func_ptr = nullptr;
scc_ir_type_t *func_type = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, func_ptr,
scc_ir_module_get_func(GET_MODULE(builder), func_ref));
SCC_IR_BUILDER_BEGIN_BORROW(
builder, func_type,
scc_ir_module_get_type(GET_MODULE(builder), func_ptr->type));
if (func_type == nullptr || func_type->tag != SCC_IR_TYPE_FUNC) {
LOG_ERROR("Invalid function type");
SCC_IR_BUILDER_END_BORROW(builder); // func_type
SCC_IR_BUILDER_END_BORROW(builder); // func_ptr
return;
}
if (func_ptr == nullptr) {
LOG_ERROR("Invalid function reference");
SCC_IR_BUILDER_END_BORROW(builder); // func_type
SCC_IR_BUILDER_END_BORROW(builder); // func_ptr
return;
}
if (scc_vec_size(func_ptr->bblocks) != 0 ||
scc_vec_size(func_ptr->params) != 0) {
LOG_FATAL("Multiple function definitions");
SCC_IR_BUILDER_END_BORROW(builder); // func_type
SCC_IR_BUILDER_END_BORROW(builder); // func_ptr
return;
}
scc_ir_type_ref_vec_t params = func_type->data.function.params;
func_type = nullptr;
scc_vec_foreach(params, i) {
scc_ir_type_ref_t param_type = scc_vec_at(params, i);
// 释放借用,因为下面要调用 add_value可能 realloc
SCC_IR_BUILDER_END_BORROW(builder); // func_type
SCC_IR_BUILDER_END_BORROW(builder); // func_ptr
// 预先分配所有参数值(临时数组,避免在循环中 push 到 func_ptr->params 时
// func_ptr 失效)
usize param_count = scc_vec_size(params);
scc_ir_value_ref_t *param_refs =
scc_malloc(sizeof(scc_ir_value_ref_t) * param_count);
for (usize i = 0; i < param_count; i++) {
scc_ir_type_ref_t param_type = scc_vec_at(params, i);
scc_ir_value_t param_node = {0};
param_node.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF; // 参数节点标记
param_node.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF;
param_node.type = scc_ir_module_add_type(
GET_MODULE(builder),
&(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR,
@@ -71,36 +142,48 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
param_node.name = param_names ? param_names[i] : nullptr;
param_node.data.arg_ref.idx = i;
scc_vec_init(param_node.used_by);
scc_ir_value_ref_t param_ref =
param_refs[i] =
scc_ir_module_add_value(GET_MODULE(builder), &param_node);
scc_vec_push(func_ptr->params, param_ref);
}
return;
// 重新借用 func_ptr 以添加参数到函数
SCC_IR_BUILDER_BEGIN_BORROW(
builder, func_ptr,
scc_ir_module_get_func(GET_MODULE(builder), func_ref));
for (usize i = 0; i < param_count; i++) {
scc_vec_push(func_ptr->params, param_refs[i]);
}
SCC_IR_BUILDER_END_BORROW(builder); // func_ptr
}
void scc_ir_builder_end_func(scc_ir_builder_t *builder) {
scc_ir_func_t *func_ptr =
scc_ir_module_get_func(GET_MODULE(builder), builder->current_func);
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_func_t *func_ptr = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, func_ptr,
scc_ir_module_get_func(GET_MODULE(builder), builder->current_func));
if (func_ptr == nullptr) {
LOG_FATAL("Invalid function reference");
SCC_IR_BUILDER_END_BORROW(builder);
return;
}
if (scc_vec_size(func_ptr->bblocks) == 0) {
// FIXME
scc_vec_push(builder->cprog->func_decls, builder->current_func);
} else {
scc_vec_push(builder->cprog->func_defs, builder->current_func);
}
SCC_IR_BUILDER_END_BORROW(builder);
builder->current_func = 0;
}
scc_ir_func_ref_t scc_ir_builder_current_func(scc_ir_builder_t *builder) {
// 只读操作,无需检查借用
return builder->current_func;
}
scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder,
const char *label) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_bblock_t bblock = {0};
if (label) {
bblock.label = label;
@@ -109,27 +192,33 @@ scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder,
scc_ir_bblock_ref_t bblock_ref =
scc_ir_module_add_bblock(GET_MODULE(builder), &bblock);
scc_ir_func_t *current_func =
scc_ir_module_get_func(GET_MODULE(builder), builder->current_func);
// 将基本块添加到当前函数
scc_ir_func_t *current_func = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, current_func,
scc_ir_module_get_func(GET_MODULE(builder), builder->current_func));
if (current_func) {
scc_vec_push(current_func->bblocks, bblock_ref);
}
SCC_IR_BUILDER_END_BORROW(builder);
return bblock_ref;
}
scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder,
const char *label) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
builder->current_bblock = scc_ir_builder_bblock(builder, label);
return builder->current_bblock;
}
void scc_ir_builder_end_bblock(scc_ir_builder_t *builder) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
builder->current_bblock = 0;
}
void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder,
scc_ir_bblock_ref_t bblock) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
builder->current_bblock = bblock;
}
@@ -139,19 +228,23 @@ scc_ir_func_ref_t scc_ir_builder_current_bblock(scc_ir_builder_t *builder) {
void scc_ir_builder_add_instr(scc_ir_builder_t *builder,
scc_ir_value_ref_t instr) {
scc_ir_bblock_t *current_bblock =
scc_ir_module_get_bblock(GET_MODULE(builder), builder->current_bblock);
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_bblock_t *current_bblock = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, current_bblock,
scc_ir_module_get_bblock(GET_MODULE(builder), builder->current_bblock));
if (current_bblock) {
scc_vec_push(current_bblock->instrs, instr);
} else {
LOG_ERROR("Current basic block is not set");
}
SCC_IR_BUILDER_END_BORROW(builder);
}
scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder,
scc_ir_type_ref_t type,
scc_ir_value_ref_t value) {
// FIXME MAYBE MEMORY LEAK
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
char *name = scc_malloc(32);
scc_ir_value_ref_t global_value_ref = scc_ir_module_add_value(
builder->ctx.module, &(scc_ir_value_t){
@@ -161,7 +254,6 @@ scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder,
.data.global_alloc.value = value,
});
scc_snprintf(name, 32, "$G%u", global_value_ref);
scc_vec_push(builder->cprog->global_vals, global_value_ref);
return global_value_ref;
}
@@ -169,6 +261,7 @@ scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder,
scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
scc_ir_type_ref_t type,
const char *name) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t alloc_node = {0};
alloc_node.tag = SCC_IR_VALUE_TAG_ALLOC;
alloc_node.type = scc_ir_module_add_type(
@@ -178,7 +271,6 @@ scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &alloc_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -187,6 +279,7 @@ scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder,
scc_ir_type_ref_t type,
const char *name,
usize arg_idx) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t value = {0};
value.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF;
value.type = type;
@@ -195,31 +288,36 @@ scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder,
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &value);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
scc_ir_value_ref_t target) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t load_node = {0};
load_node.tag = SCC_IR_VALUE_TAG_LOAD;
load_node.data.load.target = target;
// 设置类型为指针指向的类型
scc_ir_value_t *ptr_node =
scc_ir_module_get_value(GET_MODULE(builder), target);
// 借用 ptr_node 和 ptr_type 获取类型信息
scc_ir_value_t *ptr_node = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, ptr_node,
scc_ir_module_get_value(GET_MODULE(builder), target));
if (ptr_node) {
scc_ir_type_t *ptr_type =
scc_ir_module_get_type(GET_MODULE(builder), ptr_node->type);
scc_ir_type_t *ptr_type = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, ptr_type,
scc_ir_module_get_type(GET_MODULE(builder), ptr_node->type));
if (ptr_type && ptr_type->tag == SCC_IR_TYPE_PTR) {
load_node.type = ptr_type->data.pointer.base;
}
SCC_IR_BUILDER_END_BORROW(builder); // ptr_type
}
SCC_IR_BUILDER_END_BORROW(builder); // ptr_node
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &load_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -227,6 +325,7 @@ scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder,
scc_ir_value_ref_t target,
scc_ir_value_ref_t value) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
Assert(target != SCC_IR_REF_nullptr && value != SCC_IR_REF_nullptr);
scc_ir_value_t store_node = {0};
store_node.tag = SCC_IR_VALUE_TAG_STORE;
@@ -235,7 +334,6 @@ scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder,
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &store_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -243,35 +341,44 @@ scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder,
scc_ir_value_ref_t scc_ir_builder_get_elem_ptr(scc_ir_builder_t *builder,
scc_ir_value_ref_t target,
scc_ir_value_ref_t index) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t get_ptr_node = {0};
get_ptr_node.tag = SCC_IR_VALUE_TAG_GET_ELEM_PTR;
get_ptr_node.data.get_elem_ptr.src_addr = target;
get_ptr_node.data.get_elem_ptr.index = index;
// 类型应与源地址相同(都是指针)
scc_ir_type_t *type =
scc_ir_module_get_type_by_value(GET_MODULE(builder), target);
Assert(type != nullptr);
if (type->tag == SCC_IR_TYPE_PTR) {
scc_ir_type_t *base_type = scc_ir_module_get_type(
GET_MODULE(builder), type->data.pointer.base);
// 借用类型信息
scc_ir_type_t *type_ref = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, type_ref,
scc_ir_module_get_type_by_value(GET_MODULE(builder), target));
Assert(type_ref != nullptr);
scc_ir_type_t type = *type_ref; // 拷贝一份,避免后续借用
SCC_IR_BUILDER_END_BORROW(builder); // type_ref
if (type.tag == SCC_IR_TYPE_PTR) {
scc_ir_type_t *base_type = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, base_type,
scc_ir_module_get_type(GET_MODULE(builder),
type_ref->data.pointer.base));
if (base_type->tag == SCC_IR_TYPE_ARRAY) {
// FIXME GEP maybe multiple levels
get_ptr_node.type = scc_ir_builder_type(
builder, &(scc_ir_type_t){
.tag = SCC_IR_TYPE_PTR,
.data.pointer.base = base_type->data.array.base,
});
scc_ir_type_t type = (scc_ir_type_t){
.tag = SCC_IR_TYPE_PTR,
.data.pointer.base = base_type->data.array.base,
};
SCC_IR_BUILDER_END_BORROW(builder); // base_type
get_ptr_node.type = scc_ir_builder_type(builder, &type);
} else {
get_ptr_node.type = scc_ir_builder_type(builder, type);
SCC_IR_BUILDER_END_BORROW(builder); // base_type
get_ptr_node.type = scc_ir_builder_type(builder, &type);
}
} else {
get_ptr_node.type = scc_ir_builder_type(builder, type);
get_ptr_node.type = scc_ir_builder_type(builder, &type);
}
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &get_ptr_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -280,22 +387,24 @@ scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder,
scc_ir_op_type_t op,
scc_ir_value_ref_t lhs,
scc_ir_value_ref_t rhs) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t binop_node = {0};
binop_node.tag = SCC_IR_VALUE_TAG_OP;
binop_node.data.op.op = op;
binop_node.data.op.lhs = lhs;
binop_node.data.op.rhs = rhs;
// 类型通常与操作数相同(对于算术运算)
scc_ir_value_t *lhs_node =
scc_ir_module_get_value(GET_MODULE(builder), lhs);
// 借用 lhs_node 获取类型
scc_ir_value_t *lhs_node = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, lhs_node, scc_ir_module_get_value(GET_MODULE(builder), lhs));
if (lhs_node) {
binop_node.type = lhs_node->type;
}
SCC_IR_BUILDER_END_BORROW(builder); // lhs_node
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &binop_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -304,34 +413,29 @@ scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder,
scc_ir_op_type_t op,
scc_ir_value_ref_t lhs,
scc_ir_value_ref_t rhs) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t cmp_node = {0};
cmp_node.tag = SCC_IR_VALUE_TAG_OP;
cmp_node.data.op.op = op;
cmp_node.data.op.lhs = lhs;
cmp_node.data.op.rhs = rhs;
// 比较操作的结果通常是布尔值
cmp_node.type =
0; // FIXME scc_ir_module_get_builtin_i32(GET_MODULE(builder));
cmp_node.type = 0; // FIXME
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &cmp_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder,
scc_ir_bblock_ref_t target) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t jump_node = {0};
jump_node.tag = SCC_IR_VALUE_TAG_JUMP;
jump_node.data.jump.target_bblock = target;
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &jump_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -340,6 +444,7 @@ scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder,
scc_ir_value_ref_t cond,
scc_ir_bblock_ref_t true_target,
scc_ir_bblock_ref_t false_target) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t branch_node = {0};
branch_node.tag = SCC_IR_VALUE_TAG_BRANCH;
branch_node.data.branch.cond = cond;
@@ -348,7 +453,6 @@ scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder,
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &branch_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
@@ -357,6 +461,7 @@ scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder,
scc_ir_func_ref_t callee,
const scc_ir_value_ref_t *args,
usize arg_count) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t call_node = {0};
call_node.tag = SCC_IR_VALUE_TAG_CALL;
call_node.data.call.callee = callee;
@@ -366,45 +471,50 @@ scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder,
scc_vec_push(call_node.data.call.args, args[i]);
}
// 设置返回类型为被调用函数的返回类型
scc_ir_func_t *callee_func =
scc_ir_module_get_func(GET_MODULE(builder), callee);
// 借用 callee_func 和 func_type 获取返回类型
scc_ir_func_t *callee_func = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, callee_func,
scc_ir_module_get_func(GET_MODULE(builder), callee));
if (callee_func) {
scc_ir_type_t *func_type =
scc_ir_module_get_type(GET_MODULE(builder), callee_func->type);
scc_ir_type_t *func_type = nullptr;
SCC_IR_BUILDER_BEGIN_BORROW(
builder, func_type,
scc_ir_module_get_type(GET_MODULE(builder), callee_func->type));
if (func_type && func_type->tag == SCC_IR_TYPE_FUNC) {
call_node.type = func_type->data.function.ret_type;
}
SCC_IR_BUILDER_END_BORROW(builder); // func_type
}
SCC_IR_BUILDER_END_BORROW(builder); // callee_func
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &call_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder,
scc_ir_value_ref_t value) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t ret_node = {0};
ret_node.tag = SCC_IR_VALUE_TAG_RET;
ret_node.data.ret.ret_val = value;
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &ret_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) {
SCC_IR_BUILDER_CHECK_NO_BORROW(builder);
scc_ir_value_t ret_node = {0};
ret_node.tag = SCC_IR_VALUE_TAG_RET;
ret_node.data.ret.ret_val = 0; // 无返回值
ret_node.data.ret.ret_val = 0;
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &ret_node);
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}