refactor(argparse): 将null替换为nullptr以提高C++兼容性
- 在argparse库中将所有null指针常量替换为nullptr - 更新头文件和源文件中的指针初始化和比较操作 - 修改测试文件中的相关断言检查 - 更新AST定义文件中的注释说明
This commit is contained in:
3
libs/ir2mcode/include/type_manager.h
Normal file
3
libs/ir2mcode/include/type_manager.h
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
#include <scc_ir.h>
|
||||
int scc_ir2mcode_type_width(scc_ir_module_t *ctx, scc_ir_type_t *type);
|
||||
@@ -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; }
|
||||
|
||||
@@ -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_ADDR,idx 是虚拟偏移(正数)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
23
libs/ir2mcode/src/type_manager.c
Normal file
23
libs/ir2mcode/src/type_manager.c
Normal 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 */
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user