- 将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用于处理可变参数 - 添加数组和聚合类型初始化的辅助函数
103 lines
4.5 KiB
C
103 lines
4.5 KiB
C
#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++;
|
||
}
|
||
}
|