feat(argparse): 支持列表类型参数解析
当参数指定为列表类型时,验证和处理逻辑现在会检查 vec_store 是否为空或大小为0,而不是检查 str_store。 fix(hir): 初始化聚合类型值的数据结构 在 HIR 值初始化过程中,为聚合类型添加适当的初始化逻辑, 确保其字段向量被正确初始化。 refactor(hir_builder): 优化指针类型创建和GEP操作实现 - 简化全局分配器中的指针类型创建代码 - 扩展 GEP 操作以支持结构体和联合体字段访问 - 添加字段偏移计算支持 feat(hir_dump): 增强HIR类型和值的线性转储功能 - 实现类型定义的线性转储输出 - 改进结构体和联合体的转储格式 - 优化聚合值的转储表示 perf(hir_layout): 优化类型布局计算性能 改进结构体、联合体和聚合类型的对齐和大小计算算法, 提高字段偏移计算的准确性。 fix(hir_module): 完善模块资源清理机制 在模块析构时正确释放结构体和联合体类型的字段向量内存。 docs(lir): 更新文档注释中的空值表示 将初始化数据参数的空值描述从 NULL 统一为 nullptr。 refactor(hir2lir): 改进HIR到LIR的类型转换逻辑 - 重构类型到LIR大小扩展的转换函数 - 修复STORE指令的类型推导逻辑 - 增强GEP指令的规模因子和偏移量计算 - 添加对结构体/联合体字段访问的支持 refactor(x86_isel): 优化x86-64地址加载指令生成 改进LOAD_ADDR指令生成,更好地支持结构体字段访问的零比例因子。 docs(ir2mcode): 统一空值表示文档注释 更新初始化数据参数的空值描述为nullptr。 refactor(lexer): 简化词法分析器非空白标记预览逻辑 优化非空白标记预览函数,减少不必要的标记消费和销毁操作。
This commit is contained in:
@@ -44,7 +44,7 @@ scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *lir_module,
|
||||
* @param mod 模块
|
||||
* @param name 符号名
|
||||
* @param kind 种类 (DATA 或 EXTERN)
|
||||
* @param init_data 初始化数据 (若为 DATA 定义;若为 NULL 则零初始化)
|
||||
* @param init_data 初始化数据 (若为 DATA 定义;若为 nullptr 则零初始化)
|
||||
* @param size 数据大小 (若为 EXTERN 可为 0)
|
||||
* @param align 对齐要求
|
||||
* @param attr 属性
|
||||
|
||||
@@ -38,8 +38,15 @@ static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx,
|
||||
static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
scc_hir_value_ref_t value_ref);
|
||||
|
||||
static void ir_type_to_lir_size_ext(scc_hir_type_t *type, u8 *out_size,
|
||||
static void ir_type_to_lir_size_ext(scc_hir_module_t *mod,
|
||||
scc_hir_type_ref_t type_ref, u8 *out_size,
|
||||
scc_lir_ext_t *out_ext) {
|
||||
scc_hir_type_t *type = scc_hir_module_get_type(mod, type_ref);
|
||||
if (!type) {
|
||||
*out_size = 0;
|
||||
*out_ext = SCC_LIR_EXT_NONE;
|
||||
return;
|
||||
}
|
||||
switch (type->tag) {
|
||||
case SCC_HIR_TYPE_i8:
|
||||
*out_size = SCC_LIR_SIZE_8;
|
||||
@@ -90,6 +97,11 @@ static void ir_type_to_lir_size_ext(scc_hir_type_t *type, u8 *out_size,
|
||||
*out_size = 0;
|
||||
*out_ext = SCC_LIR_EXT_NONE;
|
||||
break;
|
||||
case SCC_HIR_TYPE_STRUCT:
|
||||
case SCC_HIR_TYPE_UNION:
|
||||
*out_size = (u8)scc_hir_module_type_size(mod, type_ref);
|
||||
*out_ext = SCC_LIR_EXT_NONE;
|
||||
break;
|
||||
default:
|
||||
Panic("unsupported IR type in lowering at %d", type->tag);
|
||||
}
|
||||
@@ -311,12 +323,10 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
if (scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)value_ref))
|
||||
return;
|
||||
|
||||
scc_hir_type_t *ty = scc_hir_module_get_type(ctx->hir_module, value->type);
|
||||
u8 size_bits = 0;
|
||||
scc_lir_ext_t ext = SCC_LIR_EXT_NONE;
|
||||
if (ty != nullptr) {
|
||||
ir_type_to_lir_size_ext(ty, &size_bits, &ext);
|
||||
}
|
||||
ir_type_to_lir_size_ext(ctx->hir_module, value->type, &size_bits, &ext);
|
||||
scc_hir_type_t *ty = scc_hir_module_get_type(ctx->hir_module, value->type);
|
||||
bool is_float = (ext == SCC_LIR_EXT_FLOAT);
|
||||
|
||||
int dst_vreg = get_vreg_for_value(ctx, value_ref);
|
||||
@@ -361,15 +371,11 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
/* 修复: 使用目标指针的元素类型确定 store 宽度而非源值类型 */
|
||||
scc_hir_type_t *ptr_type = scc_hir_module_get_type_by_value(
|
||||
ctx->hir_module, value->data.store.target);
|
||||
scc_hir_type_ref_t store_type = value->data.store.value;
|
||||
if (ptr_type && ptr_type->tag == SCC_HIR_TYPE_PTR) {
|
||||
scc_hir_type_t *elem_type = scc_hir_module_get_type(
|
||||
ctx->hir_module, ptr_type->data.pointer.base);
|
||||
ir_type_to_lir_size_ext(elem_type, &size_bits, &ext);
|
||||
} else {
|
||||
ty = scc_hir_module_get_type_by_value(ctx->hir_module,
|
||||
value->data.store.value);
|
||||
ir_type_to_lir_size_ext(ty, &size_bits, &ext);
|
||||
store_type = ptr_type->data.pointer.base;
|
||||
}
|
||||
ir_type_to_lir_size_ext(ctx->hir_module, store_type, &size_bits, &ext);
|
||||
scc_lir_instr_t instr = {.op = SCC_LIR_STORE,
|
||||
.ext = ext,
|
||||
.size_bits = size_bits,
|
||||
@@ -378,25 +384,50 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: {
|
||||
// 1. 获取基址和索引的 LIR 操作数
|
||||
scc_lir_val_t base =
|
||||
ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.src_addr);
|
||||
scc_lir_val_t index =
|
||||
ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.index);
|
||||
|
||||
// 2. 获取元素类型和大小
|
||||
scc_hir_type_t *ptr_type =
|
||||
scc_hir_module_get_type(ctx->hir_module, value->type);
|
||||
scc_hir_type_ref_t pointee = SCC_CFG_ID_nullptr;
|
||||
if (ptr_type->tag == SCC_HIR_TYPE_PTR) {
|
||||
pointee = ptr_type->data.pointer.base;
|
||||
} else if (ptr_type->tag == SCC_HIR_TYPE_ARRAY) {
|
||||
// 数组名退化为指针,元素类型为数组的元素类型
|
||||
pointee = ptr_type->data.array.base;
|
||||
} else {
|
||||
Panic("GET_ELEM_PTR on non-pointer/array type");
|
||||
// 获取 src_addr 的原始指针类型,判断是否为结构体字段访问
|
||||
scc_hir_type_t *src_type = scc_hir_module_get_type_by_value(
|
||||
ctx->hir_module, value->data.get_elem_ptr.src_addr);
|
||||
int scale = 0, offset = 0;
|
||||
|
||||
if (src_type && src_type->tag == SCC_HIR_TYPE_PTR) {
|
||||
scc_hir_type_ref_t pointee_ref = src_type->data.pointer.base;
|
||||
scc_hir_type_t *pointee =
|
||||
scc_hir_module_get_type(ctx->hir_module, pointee_ref);
|
||||
if (pointee && (pointee->tag == SCC_HIR_TYPE_STRUCT ||
|
||||
pointee->tag == SCC_HIR_TYPE_UNION)) {
|
||||
// 结构体/联合体字段 GEP:使用字段字节偏移
|
||||
int field_idx = 0;
|
||||
scc_hir_value_t *idx_val = scc_hir_module_get_value(
|
||||
ctx->hir_module, value->data.get_elem_ptr.index);
|
||||
if (idx_val && idx_val->tag == SCC_HIR_VALUE_TAG_INTEGER) {
|
||||
field_idx = (int)idx_val->data.integer.data.digit;
|
||||
}
|
||||
offset = scc_hir_field_offset(ctx->hir_module, pointee_ref,
|
||||
field_idx, ctx->hir_module->abi) /
|
||||
8;
|
||||
} else if (pointee && pointee->tag == SCC_HIR_TYPE_ARRAY) {
|
||||
// 数组 GEP:index * elem_size
|
||||
scc_hir_type_ref_t elem_ref = pointee->data.array.base;
|
||||
int elem_size_bits =
|
||||
scc_hir_module_type_size(ctx->hir_module, elem_ref);
|
||||
scale = elem_size_bits / 8;
|
||||
} else {
|
||||
// 其他类型:按元素大小缩放
|
||||
int elem_size_bits =
|
||||
scc_hir_module_type_size(ctx->hir_module, pointee_ref);
|
||||
scale = elem_size_bits / 8;
|
||||
}
|
||||
} else if (src_type && src_type->tag == SCC_HIR_TYPE_ARRAY) {
|
||||
scc_hir_type_ref_t elem_ref = src_type->data.array.base;
|
||||
int elem_size_bits =
|
||||
scc_hir_module_type_size(ctx->hir_module, elem_ref);
|
||||
scale = elem_size_bits / 8;
|
||||
}
|
||||
int elem_size_bits = scc_hir_module_type_size(ctx->hir_module, pointee);
|
||||
|
||||
int dst_vreg = get_vreg_for_value(ctx, value_ref);
|
||||
scc_lir_instr_t instr = {
|
||||
@@ -405,9 +436,8 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.arg0 = base,
|
||||
.arg1 = index,
|
||||
// FIXME
|
||||
.metadata.addr.scale = elem_size_bits / 8,
|
||||
.metadata.addr.offset = 0,
|
||||
.metadata.addr.scale = scale,
|
||||
.metadata.addr.offset = offset,
|
||||
};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
} break;
|
||||
@@ -556,11 +586,10 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
}
|
||||
case SCC_HIR_BUILTIN_TAG_VA_ARG: {
|
||||
// 需要从类型中获取大小和对齐以及是否为浮点
|
||||
scc_hir_type_t *ty =
|
||||
scc_hir_module_get_type(ctx->hir_module, b->func.va_arg.type);
|
||||
u8 size = 0;
|
||||
scc_lir_ext_t ext = SCC_LIR_EXT_NONE;
|
||||
ir_type_to_lir_size_ext(ty, &size, &ext);
|
||||
ir_type_to_lir_size_ext(ctx->hir_module, b->func.va_arg.type, &size,
|
||||
&ext);
|
||||
bool is_float = (ext == SCC_LIR_EXT_FLOAT);
|
||||
scc_lir_val_t ap = ir_value_to_lir_operand(ctx, b->func.va_arg.ap);
|
||||
scc_lir_instr_t instr = {
|
||||
@@ -598,6 +627,13 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_FUNC_ARG_REF:
|
||||
case SCC_HIR_VALUE_TAG_BLOCK_ARG_REF:
|
||||
case SCC_HIR_VALUE_TAG_INTEGER:
|
||||
case SCC_HIR_VALUE_TAG_DECIMAL:
|
||||
case SCC_HIR_VALUE_TAG_NULLPTR:
|
||||
case SCC_HIR_VALUE_TAG_ARRAY:
|
||||
case SCC_HIR_VALUE_TAG_AGGREGATE:
|
||||
case SCC_HIR_VALUE_TAG_GLOBAL_ALLOC:
|
||||
// 常量/全局值:不需要生成指令,由 ir_value_to_lir_operand 处理
|
||||
break;
|
||||
default:
|
||||
Panic("unsupported opcode %d", value->tag);
|
||||
@@ -672,7 +708,11 @@ void scc_hir2lir(scc_lir_module_t *module, scc_hir_cprog_t *cprog) {
|
||||
&cprog->module, galloc->data.global_alloc.value);
|
||||
scc_lir_symbol_id_t id = SCC_CFG_ID_nullptr;
|
||||
|
||||
int size = scc_hir_module_type_size(&cprog->module, val->type);
|
||||
scc_hir_type_t *gtype =
|
||||
scc_hir_module_get_type(&cprog->module, galloc->type);
|
||||
Assert(gtype->tag == SCC_HIR_TYPE_PTR);
|
||||
int size =
|
||||
scc_hir_module_type_size(&cprog->module, gtype->data.pointer.base);
|
||||
Assert(size > 0);
|
||||
if (val == nullptr) {
|
||||
// TODO char == 8 bit
|
||||
|
||||
Reference in New Issue
Block a user