refactor(ast2ir): 移除废弃的ABI依赖并优化类型转换处理

移除了对scc_abi包的依赖,将相关头文件从libs/abi移动到libs/ast2ir目录下。
重构了基本类型解析功能,将parse_base_type函数提取为独立的
scc_ast2ir_parse_base_type实现,并支持有符号/无符号类型区分。

feat(ast2ir): 实现整数常量表达式求值器

新增了完整的整数常量表达式求值功能,支持C11标准中的常量表达式规则,
包括字面量、标识符、sizeof/_Alignof、一元/二元运算、条件表达式和
类型转换等操作。该功能用于数组大小和枚举值的编译期计算验证。

refactor(ast2ir): 完善类型提升和算术转换机制

改进了整数提升和寻常算术转换的实现,修复了移位操作的符号处理问题,
添加了无符号比较操作的支持,增强了类型安全检查,统一了错误处理流程。

fix(ast2ir): 修复赋值表达式返回值和数组大小计算问题

修正了赋值表达式的返回值处理,确保返回右侧值而不是存储指令引用。
使用新的常量表达式求值器替代原有的硬编码数组大小计算,提高了
数组声明的正确性。
This commit is contained in:
zzy
2026-05-31 17:30:22 +08:00
parent c4467b8420
commit d2eafa9dc6
27 changed files with 2579 additions and 218 deletions

View File

@@ -12,6 +12,9 @@ typedef struct {
cbool dump_relocs;
cbool dump_hex;
cbool dump_all;
const char *get_section_name;
int get_section_idx;
cbool has_get_section_idx;
int verbose;
} sccfdump_config_t;
@@ -188,6 +191,8 @@ int main(int argc, const char **argv, const char **envp) {
HINT_HEX,
HINT_VERBOSE,
HINT_ALL,
HINT_GET_SECTION,
HINT_GET_SECTION_IDX,
};
static const char *hints_en[] = {
[HINT_PROG_NAME] = "sccfdump",
@@ -201,6 +206,8 @@ int main(int argc, const char **argv, const char **envp) {
[HINT_HEX] = "Dump section hex content",
[HINT_VERBOSE] = "Verbose output (use with -x)",
[HINT_ALL] = "Dump header, sections, symbols and relocs",
[HINT_GET_SECTION] = "Extract raw section data by name (e.g. .text)",
[HINT_GET_SECTION_IDX] = "Extract raw section data by index",
};
static const char *hints_zh[] = {
[HINT_PROG_NAME] = "sccfdump",
@@ -214,6 +221,8 @@ int main(int argc, const char **argv, const char **envp) {
[HINT_HEX] = "转存段的十六进制内容",
[HINT_VERBOSE] = "详细输出(与-x配合使用)",
[HINT_ALL] = "转存文件头、段、符号和重定位",
[HINT_GET_SECTION] = "按名称提取段原始数据(如 .text)",
[HINT_GET_SECTION_IDX] = "按索引提取段原始数据",
};
scc_argparse_lang_t lang = SCC_ARGPARSE_LANG_EN;
@@ -228,6 +237,7 @@ int main(int argc, const char **argv, const char **envp) {
sccfdump_config_t config;
scc_memset(&config, 0, sizeof(config));
config.dump_all = true;
config.get_section_idx = -1;
scc_argparse_t argparse;
scc_argparse_init(&argparse, hints[HINT_PROG_NAME], hints[HINT_DESCRIPTION]);
@@ -275,6 +285,16 @@ int main(int argc, const char **argv, const char **envp) {
scc_argparse_spec_setup_count(&opt_verbose.spec, &config.verbose);
scc_argparse_cmd_add_opt(root, &opt_verbose);
scc_argparse_opt_t opt_get_section;
scc_argparse_opt_init(&opt_get_section, 0, "get-section", hints[HINT_GET_SECTION]);
scc_argparse_spec_setup_string(&opt_get_section.spec, &config.get_section_name);
scc_argparse_cmd_add_opt(root, &opt_get_section);
scc_argparse_opt_t opt_get_section_idx;
scc_argparse_opt_init(&opt_get_section_idx, 0, "get-section-idx", hints[HINT_GET_SECTION_IDX]);
scc_argparse_spec_setup_int(&opt_get_section_idx.spec, &config.get_section_idx);
scc_argparse_cmd_add_opt(root, &opt_get_section_idx);
scc_argparse_arg_t arg_file;
scc_argparse_arg_init(&arg_file, "file", hints[HINT_FILE]);
scc_argparse_spec_setup_string(&arg_file.spec, &config.filepath);
@@ -318,6 +338,60 @@ int main(int argc, const char **argv, const char **envp) {
sccf_parse(&sccf, &buf, 0);
u8 *base = scc_vec_unsafe_get_data(buf);
/* --get-section / --get-section-idx: extract raw data to a file/stdout */
if (config.get_section_name || config.get_section_idx >= 0) {
usize idx = (usize)-1;
if (config.get_section_idx >= 0) {
idx = (usize)config.get_section_idx;
} else {
const sccf_header_t *hdr = (const sccf_header_t *)base;
for (usize i = 0; i < (usize)hdr->sect_header_num; i++) {
const sccf_sect_header_t *sh = sccf_sect_header(base, i);
if (sh && scc_memcmp(sh->name,
config.get_section_name, 8) == 0) {
idx = i;
break;
}
}
if (idx == (usize)-1) {
LOG_ERROR("section not found: %s", config.get_section_name);
scc_vec_free(buf);
return 1;
}
}
const sccf_sect_header_t *sh = sccf_sect_header(base, idx);
if (!sh) {
LOG_ERROR("invalid section index: %d", config.get_section_idx);
scc_vec_free(buf);
return 1;
}
u8 *sdata = sccf_sect_data(base, idx);
if (!sdata || sh->size == 0) {
scc_vec_free(buf);
return 0;
}
if (config.output && scc_strcmp(config.output, "-") == 0) {
scc_fwrite(scc_stdout, sdata, sh->size);
} else if (config.output) {
scc_file_t ofp = scc_fopen(config.output, SCC_FILE_WRITE);
if (!ofp) {
LOG_ERROR("cannot open output: %s", config.output);
scc_vec_free(buf);
return 1;
}
scc_fwrite(ofp, sdata, sh->size);
scc_fclose(ofp);
} else {
scc_fwrite(scc_stdout, sdata, sh->size);
}
scc_vec_free(buf);
return 0;
}
/* --hex without -o: also go to stdout */
if (config.dump_all) {
dump_header(&sccf.header);
dump_sections(base);