Files
scc/libs/ast2ir/src/scc_ast2ir_utils.c
zzy 31d7e91ef1 refactor(ast2ir): 重构ABI类型系统并修复union结构问题
- 将scc_ast_def.h中的attr_of从union改为struct以修复结构定义问题
- 添加type_abi依赖到ast2ir模块的cbuild.toml配置文件中
- 重命名scc_ast2ir.h中的abi字段为type_abi,并更新相关初始化函数签名
- 移除废弃的scc_abi_type.h和相关平台ABI头文件
- 添加辅助函数is_variadic_marker和fixed_param_count用于处理可变参数
- 添加数组和聚合类型初始化的辅助函数
2026-06-01 12:14:13 +08:00

103 lines
4.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <scc_ast2ir.h>
// 辅助函数:生成数组初始化代码
void emit_array_initialization(scc_ast2ir_ctx_t *ctx,
scc_hir_value_ref_t array_ptr,
const scc_hir_type_t *array_type,
const scc_ast_expr_t *init_expr) {
Assert(array_type->tag == SCC_HIR_TYPE_ARRAY);
scc_hir_type_ref_t elem_type_ref = array_type->data.array.base;
const scc_hir_type_t *elem_type =
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), elem_type_ref);
usize array_len = array_type->data.array.len;
// 字符串字面量初始化:直接 memcpy
if (init_expr->base.type == SCC_AST_EXPR_STRING_LITERAL) {
scc_hir_value_ref_t str_val = scc_ast2ir_expr(ctx, init_expr, false);
scc_ap_t len_ap;
scc_ap_set_int(&len_ap, array_len);
scc_hir_value_ref_t len_ref = scc_hir_builder_integer(
&ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &len_ap);
scc_hir_builder_builtin_memcpy(&ctx->builder, array_ptr, str_val,
len_ref);
return;
}
// 复合初始化:逐个元素 store
if (init_expr->base.type != SCC_AST_EXPR_COMPOUND) {
Panic("unsupported initializer for array");
}
// 遍历初始化列表
usize idx = 0;
scc_vec_foreach(init_expr->compound.rhs_exprs, i) {
scc_ast_expr_t *elem_expr =
scc_vec_at(init_expr->compound.rhs_exprs, i);
Assert(elem_expr != nullptr);
if (idx >= array_len)
break; // 防止溢出
// 生成元素地址array_ptr + idx * elem_size
scc_ap_t offset_ap;
scc_ap_set_int(&offset_ap, idx);
scc_hir_value_ref_t idx_val = scc_hir_builder_integer(
&ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &offset_ap);
scc_hir_value_ref_t elem_ptr =
scc_hir_builder_get_elem_ptr(&ctx->builder, array_ptr, idx_val);
// 递归处理:如果元素本身是数组且初始化表达式是复合初始化,需要嵌套处理
if (elem_type->tag == SCC_HIR_TYPE_ARRAY &&
elem_expr->base.type == SCC_AST_EXPR_COMPOUND) {
// 递归调用自身,但注意 elem_ptr 已经是子数组的首地址
emit_array_initialization(ctx, elem_ptr, elem_type, elem_expr);
} else {
// 标量元素:计算右值并 store
scc_hir_value_ref_t val = scc_ast2ir_expr(ctx, elem_expr, false);
scc_hir_builder_store(&ctx->builder, elem_ptr, val);
}
idx++;
}
// 如果初始化列表元素少于数组长度剩余元素默认零初始化C 标准要求)
// 这里简单忽略,实际可生成 memset 循环,但为简化暂不处理
}
void emit_aggregate_initialization(scc_ast2ir_ctx_t *ctx,
scc_hir_value_ref_t base_ptr,
const scc_hir_type_t *type,
const scc_ast_expr_t *init_expr) {
Assert(type->tag == SCC_HIR_TYPE_STRUCT || type->tag == SCC_HIR_TYPE_UNION);
if (init_expr->base.type != SCC_AST_EXPR_COMPOUND) {
Panic("expected compound initializer");
}
usize idx = 0;
scc_vec_foreach(init_expr->compound.rhs_exprs, i) {
if (idx >= type->data.aggregate.fields.size)
break;
scc_ast_expr_t *field_init =
scc_vec_at(init_expr->compound.rhs_exprs, i);
scc_hir_type_ref_t field_type_ref =
scc_vec_at(type->data.aggregate.fields, idx);
const scc_hir_type_t *field_type =
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), field_type_ref);
scc_ap_t idx_ap;
scc_ap_set_int(&idx_ap, idx);
scc_hir_value_ref_t idx_val = scc_hir_builder_integer(
&ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &idx_ap);
scc_hir_value_ref_t field_ptr =
scc_hir_builder_get_elem_ptr(&ctx->builder, base_ptr, idx_val);
if (field_type->tag == SCC_HIR_TYPE_ARRAY) {
emit_array_initialization(ctx, field_ptr, field_type, field_init);
} else if (field_type->tag == SCC_HIR_TYPE_STRUCT ||
field_type->tag == SCC_HIR_TYPE_UNION) {
emit_aggregate_initialization(ctx, field_ptr, field_type,
field_init);
} else {
scc_hir_value_ref_t val = scc_ast2ir_expr(ctx, field_init, false);
scc_hir_builder_store(&ctx->builder, field_ptr, val);
}
idx++;
}
}