refactor(argparse): 将null替换为nullptr以提高C++兼容性

- 在argparse库中将所有null指针常量替换为nullptr
- 更新头文件和源文件中的指针初始化和比较操作
- 修改测试文件中的相关断言检查
- 更新AST定义文件中的注释说明
This commit is contained in:
zzy
2026-04-05 20:18:09 +08:00
parent 27d86d5685
commit 4144f7841c
76 changed files with 1430 additions and 998 deletions

View File

@@ -0,0 +1,3 @@
#include <scc_ir.h>
int scc_ir2mcode_type_width(scc_ir_module_t *ctx, scc_ir_type_t *type);

View File

@@ -0,0 +1,50 @@
// frame_manager.c
#include "frame_manager.h"
#include <assert.h>
#include <stdlib.h>
struct frame_manager {
int shadow_space; // 影子空间大小(字节)
int saved_reg_size; // 已分配的保存寄存器区域大小
int local_size; // 已分配的局部变量区域大小
int align; // 栈对齐要求
};
void frame_manager_init(frame_manager_t *fm, int shadow_space, int align) {
fm->shadow_space = shadow_space;
fm->saved_reg_size = 0;
fm->local_size = 0;
fm->align = align;
}
int frame_alloc_slot(frame_manager_t *fm, int size) {
int offset = fm->local_size;
fm->local_size += size;
return offset; // 返回虚拟偏移从0开始
}
int frame_alloc_saved_reg(frame_manager_t *fm, int reg_width) {
int offset = fm->saved_reg_size;
fm->saved_reg_size += reg_width;
return offset;
}
int frame_total_size(frame_manager_t *fm) {
int total = fm->shadow_space + fm->saved_reg_size + fm->local_size;
// 对齐到 align 字节
return (total + fm->align - 1) & ~(fm->align - 1);
}
int frame_slot_offset(frame_manager_t *fm, int slot_idx) {
// 布局: RBP 指向保存的 RBP向下依次是
// [影子空间] [保存寄存器区] [局部变量区]
// 局部变量区的起始地址 = RBP - (8 + shadow_space + saved_reg_size)
// 其中 8 是 push rbp 占用的空间(返回地址在 RBP+8但 RBP 本身指向保存的
// RBP
int base = 8 + fm->shadow_space + fm->saved_reg_size;
return base + slot_idx; // 返回正数,表示从 RBP 向下的字节数
}
int frame_shadow_space(frame_manager_t *fm) { return fm->shadow_space; }
int frame_saved_reg_size(frame_manager_t *fm) { return fm->saved_reg_size; }

View File

@@ -2,22 +2,10 @@
#include <amd64/scc_amd64_abi.h>
#include <reg_alloc.h>
#include <scc_ir2mcode.h>
#include <type_manager.h>
#define GET_MODULE(ctx) (&(ctx->cprog->module))
static int scc_type_width(scc_ir_type_t *type) {
/* clang-format off */
switch (type->tag) {
case SCC_IR_TYPE_i8: case SCC_IR_TYPE_u8: return 1;
case SCC_IR_TYPE_i16: case SCC_IR_TYPE_u16: return 2;
case SCC_IR_TYPE_i32: case SCC_IR_TYPE_u32: return 4;
case SCC_IR_TYPE_i64: case SCC_IR_TYPE_u64: return 8;
case SCC_IR_TYPE_PTR: return 8;
default: return 8; // 默认64位
}
/* clang-format on */
}
static bool scc_type_is_signed(scc_ir_type_t *type) {
return (type->tag == SCC_IR_TYPE_i8 || type->tag == SCC_IR_TYPE_i16 ||
type->tag == SCC_IR_TYPE_i32 || type->tag == SCC_IR_TYPE_i64);
@@ -25,9 +13,9 @@ static bool scc_type_is_signed(scc_ir_type_t *type) {
static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
scc_ir_value_ref_t node_ref) {
Assert(ctx != null && loc != null);
Assert(ctx != nullptr && loc != nullptr);
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (node == null) {
if (node == nullptr) {
LOG_FATAL("invalid node ref");
UNREACHABLE();
return;
@@ -140,7 +128,7 @@ typedef SCC_VEC(patch_t) patch_vec_t;
static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
patch_vec_t *patches) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (node == null) {
if (node == nullptr) {
LOG_ERROR("invalid node ref");
return;
}
@@ -172,7 +160,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
GET_MODULE(ctx), node->data.load.target);
scc_ir_type_t *base_type = scc_ir_module_get_type(
GET_MODULE(ctx), ptr_type->data.pointer.base);
int width = scc_type_width(base_type);
int width = scc_ir2mcode_type_width(GET_MODULE(ctx), base_type);
bool is_signed = scc_type_is_signed(base_type);
// 间接加载到 RAX
@@ -202,7 +190,9 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
scc_mcode_amd64_mov_r64_m64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
} else {
UNREACHABLE();
LOG_WARN("unsupported type width: %d", width);
scc_mcode_amd64_mov_r64_m64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
}
// 存储结果
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
@@ -224,7 +214,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
GET_MODULE(ctx), node->data.store.target);
scc_ir_type_t *base_type = scc_ir_module_get_type(
GET_MODULE(ctx), ptr_type->data.pointer.base);
int width = scc_type_width(base_type);
int width = scc_ir2mcode_type_width(GET_MODULE(ctx), base_type);
// 根据宽度生成存储指令
if (width == 1) {
@@ -242,30 +232,47 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
}
break;
}
///< 获取指针
///< 获取指针
case SCC_IR_VALUE_TAG_GET_PTR: {
scc_reg_loc_t loc;
scc_reg_loc_t loc_res;
parse_location(ctx, &loc_res, node_ref);
scc_ir_value_t *src_addr = scc_ir_module_get_value(
GET_MODULE(ctx), node->data.get_ptr.src_addr);
Assert(src_addr != null);
if (src_addr->tag != SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
Panic();
Assert(src_addr != nullptr);
if (src_addr->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
// 全局变量RIP相对寻址
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode, SCC_AMD64_RAX,
0);
usize sym_idx =
sccf_builder_get_symbol_idx(ctx->builder, src_addr->name);
Assert(sym_idx != 0);
sccf_builder_add_reloc(
ctx->builder,
(sccf_reloc_t){
.reloc_type = SCCF_RELOC_TYPE_REL,
.offset = scc_vec_size(ctx->sect_mcode.mcode) - 4,
.addend = 4,
.sect_type = SCCF_SECT_DATA,
.sym_idx = sym_idx,
});
} else if (src_addr->tag == SCC_IR_VALUE_TAG_ALLOC) {
// 栈上变量:地址为 rbp - offset
scc_reg_loc_t src_loc;
parse_location(ctx, &src_loc, node->data.get_ptr.src_addr);
// src_loc.kind 应为 SCC_REG_KIND_STACK_ADDRidx 是虚拟偏移(正数)
scc_mcode_amd64_lea_r64_m64_disp32(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RBP, -src_loc.idx - 8);
} else {
// 其他情况(如链式 getptr源地址值已经存储在某个位置直接加载到
// RAX
scc_reg_loc_t src_loc;
parse_location(ctx, &src_loc, node->data.get_ptr.src_addr);
load_value_to_reg(&ctx->sect_mcode, &src_loc, SCC_AMD64_RAX);
}
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode, SCC_AMD64_RAX, 0);
usize sym_idx =
sccf_builder_get_symbol_idx(ctx->builder, src_addr->name);
Assert(sym_idx != 0);
sccf_builder_add_reloc(
ctx->builder, (sccf_reloc_t){
.reloc_type = SCCF_RELOC_TYPE_REL,
.offset = scc_vec_size(ctx->sect_mcode.mcode) - 4,
.addend = 4,
.sect_type = SCCF_SECT_DATA,
.sym_idx = sym_idx,
});
parse_location(ctx, &loc, node_ref);
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX);
break;
}
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array)
@@ -555,7 +562,7 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
scc_ir_bblock_t *bblock =
scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref);
if (bblock == null) {
if (bblock == nullptr) {
LOG_FATAL("<invalid block>\n");
return;
}
@@ -593,7 +600,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
Assert(galloc->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC);
scc_ir_value_t *value = scc_ir_module_get_value(
GET_MODULE(ctx), galloc->data.global_alloc.value);
Assert(value != null);
Assert(value != nullptr);
sccf_sym_t sym = (sccf_sym_t){
.sccf_sect_offset = scc_vec_size(ctx->sect_data),
.sccf_sect_type = SCCF_SECT_DATA,
@@ -654,7 +661,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
}
sccf_sym_t *sym =
sccf_builder_get_symbol_unsafe(ctx->builder, func->name);
Assert(sym != null);
Assert(sym != nullptr);
sym->sccf_sect_offset = scc_vec_size(ctx->sect_mcode.mcode);
parse_function(ctx, func);
}

View File

@@ -1,4 +1,5 @@
#include "reg_alloc.h"
#include <reg_alloc.h>
#include <type_manager.h>
u32 hash_func(const void *key) { return (usize)key; }
int equal_func(const void *key1, const void *key2) {
@@ -39,12 +40,12 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i);
scc_ir_bblock_t *bblock =
scc_ir_module_get_bblock(ctx->ir_module, bblock_ref);
Assert(bblock != null);
Assert(bblock != nullptr);
scc_vec_foreach(bblock->instrs, j) {
scc_ir_value_ref_t node_ref = scc_vec_at(bblock->instrs, j);
scc_ir_value_t *node =
scc_ir_module_get_value(ctx->ir_module, node_ref);
Assert(node != null);
Assert(node != nullptr);
loc.kind = SCC_REG_KIND_UNDEF;
switch (node->tag) {
case SCC_IR_VALUE_TAG_LOAD:
@@ -65,8 +66,17 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
// 为 alloc 分配栈偏移,但不作为普通值存储
loc.kind =
SCC_REG_KIND_STACK_ADDR; // 实际不需要存储到 reg_loc_vec
scc_ir_type_t *type =
scc_ir_module_get_type(ctx->ir_module, node->type);
Assert(type != nullptr);
loc.idx = ctx->alloc_stack_size;
ctx->alloc_stack_size += 8; // 根据类型大小调整
Assert(type->tag == SCC_IR_TYPE_PTR);
int len = scc_ir2mcode_type_width(
ctx->ir_module,
scc_ir_module_get_type(ctx->ir_module,
type->data.pointer.base));
len = len % 8 == 0 ? len : len + 8 - len % 8;
ctx->alloc_stack_size += len;
// 记录偏移
scc_vec_push(ctx->reg_loc_vec, loc);

View File

@@ -0,0 +1,23 @@
#include <type_manager.h>
int scc_ir2mcode_type_width(scc_ir_module_t *ctx, scc_ir_type_t *type) {
/* clang-format off */
if (ctx == nullptr || type == nullptr) {
Panic("Invalid argument");
return 0;
}
switch (type->tag) {
case SCC_IR_TYPE_i8: case SCC_IR_TYPE_u8: return 1;
case SCC_IR_TYPE_i16: case SCC_IR_TYPE_u16: return 2;
case SCC_IR_TYPE_i32: case SCC_IR_TYPE_u32: return 4;
case SCC_IR_TYPE_i64: case SCC_IR_TYPE_u64: return 8;
case SCC_IR_TYPE_PTR: return 8;
case SCC_IR_TYPE_ARRAY:
return scc_ir2mcode_type_width(
ctx,
scc_ir_module_get_type(ctx, type->data.array.base)
) * type->data.array.len;
default: return 8; // 默认64位
}
/* clang-format on */
}

View File

@@ -24,7 +24,7 @@ void test_example(const char *input, cbool need_sema, const char *name) {
scc_sema_init(&sema_callbacks);
scc_parser_init(&parser, tok_ring, &sema_callbacks);
} else {
scc_parser_init(&parser, tok_ring, null);
scc_parser_init(&parser, tok_ring, nullptr);
}
scc_ast_translation_unit_t *tu = scc_parse_translation_unit(&parser);