feat(ast2ir): 添加浮点类型支持和复合初始化功能
- 在ABI类型计算中添加FLOAT和DOUBLE类型的映射 - 修复AST操作符注释中的歧义描述 - 为ast2ir上下文添加类型缓存以解决递归结构体定义问题 - 实现复合初始化表达式的支持,包括数组和结构体初始化 - 添加前置和后置自增/自减操作符的IR转换 - 实现三元条件表达式的IR生成 - 添加类型转换(cast)和sizeof操作符的支持 - 重构数组长度推断逻辑并添加类型大小计算函数 - 实现结构体和联合体的递归类型解析 - 添加函数指针调用相关的IR节点类型定义 fix(ast): 修正间接操作符的注释说明 refactor(ast2ir): 优化代码结构并添加必要的断言验证
This commit is contained in:
@@ -68,6 +68,11 @@ void scc_hir_builder_init(scc_hir_builder_t *builder, scc_hir_cprog_t *cprog);
|
||||
*/
|
||||
void scc_hir_builder_drop(scc_hir_builder_t *builder);
|
||||
|
||||
static inline scc_hir_module_t *
|
||||
scc_hir_builder_get_module(scc_hir_builder_t *builder) {
|
||||
return &builder->cprog->module;
|
||||
}
|
||||
|
||||
scc_hir_func_ref_t scc_hir_builder_func(scc_hir_builder_t *builder,
|
||||
scc_hir_type_ref_t type_ref,
|
||||
const char *name);
|
||||
@@ -92,7 +97,7 @@ scc_hir_value_ref_t scc_hir_builder_alloca(scc_hir_builder_t *builder,
|
||||
const char *name);
|
||||
|
||||
#define SCC_HIR_BUILDER_TYPE_FUNC(scc_type) \
|
||||
[[maybe_unused]] static inline scc_hir_type_ref_t \
|
||||
SCC_MAYBE_UNUSED static inline scc_hir_type_ref_t \
|
||||
scc_hir_builder_type_##scc_type(scc_hir_builder_t *builder) { \
|
||||
scc_hir_type_t type_desc; \
|
||||
scc_hir_type_init(&type_desc, SCC_HIR_TYPE_##scc_type); \
|
||||
|
||||
@@ -89,7 +89,9 @@ typedef enum scc_hir_value_tag {
|
||||
SCC_HIR_VALUE_TAG_OP, ///< 二元运算
|
||||
SCC_HIR_VALUE_TAG_BRANCH, ///< 有条件分支
|
||||
SCC_HIR_VALUE_TAG_JUMP, ///< 无条件跳转
|
||||
SCC_HIR_VALUE_TAG_JUMP_INDIRECT, ///< 无条件跳转(地址)
|
||||
SCC_HIR_VALUE_TAG_CALL, ///< 调用函数
|
||||
SCC_HIR_VALUE_TAG_CALL_INDIRECT, ///< 调用函数(地址)
|
||||
SCC_HIR_VALUE_TAG_RET, ///< 函数返回
|
||||
} scc_hir_value_tag_t;
|
||||
|
||||
@@ -222,11 +224,15 @@ struct scc_hir_value {
|
||||
scc_hir_bblock_ref_t true_bblock;
|
||||
scc_hir_bblock_ref_t false_bblock;
|
||||
} branch;
|
||||
struct {
|
||||
union {
|
||||
scc_hir_value_ref_t target_ptr;
|
||||
scc_hir_bblock_ref_t target_bblock;
|
||||
} jump;
|
||||
struct {
|
||||
scc_hir_func_ref_t callee; // TODO function pointer call
|
||||
union {
|
||||
scc_hir_func_ref_t func_ref;
|
||||
scc_hir_value_ref_t ptr_ref;
|
||||
} callee;
|
||||
scc_hir_value_ref_vec_t args;
|
||||
} call;
|
||||
struct {
|
||||
|
||||
@@ -105,7 +105,7 @@ void scc_hir_value_init(scc_hir_value_t *in, const char *name,
|
||||
break;
|
||||
case SCC_HIR_VALUE_TAG_CALL:
|
||||
scc_vec_init(in->data.call.args);
|
||||
in->data.call.callee = 0;
|
||||
in->data.call.callee.func_ref = 0;
|
||||
break;
|
||||
case SCC_HIR_VALUE_TAG_RET:
|
||||
in->data.ret.ret_val = 0;
|
||||
|
||||
@@ -625,7 +625,7 @@ scc_hir_value_ref_t scc_hir_builder_call(scc_hir_builder_t *builder,
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t call_node = {0};
|
||||
call_node.tag = SCC_HIR_VALUE_TAG_CALL;
|
||||
call_node.data.call.callee = callee;
|
||||
call_node.data.call.callee.func_ref = callee;
|
||||
|
||||
scc_vec_init(call_node.data.call.args);
|
||||
for (usize i = 0; i < arg_count; i++) {
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
#include <scc_tree_dump.h>
|
||||
|
||||
#define GET_MODULE(ctx) (&(ctx->cprog->module))
|
||||
|
||||
static void dump_type_with_visited(scc_hir_dump_t *ctx,
|
||||
scc_hir_type_ref_t type_ref,
|
||||
scc_hashtable_t *visited);
|
||||
static const char *get_node_type_str(scc_hir_value_tag_t tag) {
|
||||
static const char *node_types[] = {
|
||||
[SCC_HIR_VALUE_TAG_NULLPTR] = "NullPtr",
|
||||
@@ -168,9 +170,9 @@ static void dump_jump_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) {
|
||||
|
||||
static void dump_call_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) {
|
||||
scc_tree_dump_begin_line(ctx->dump_ctx);
|
||||
if (value->data.call.callee) {
|
||||
scc_hir_func_t *callee =
|
||||
scc_hir_module_get_func(GET_MODULE(ctx), value->data.call.callee);
|
||||
if (value->data.call.callee.func_ref) {
|
||||
scc_hir_func_t *callee = scc_hir_module_get_func(
|
||||
GET_MODULE(ctx), value->data.call.callee.func_ref);
|
||||
scc_tree_dump_value(ctx->dump_ctx, "func='%s'",
|
||||
callee ? (callee->name ? callee->name : "<unnamed>")
|
||||
: "<invalid>");
|
||||
@@ -256,60 +258,12 @@ void scc_hir_dump_value(scc_hir_dump_t *ctx, scc_hir_value_ref_t value_ref) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void scc_hir_dump_type(scc_hir_dump_t *ctx, scc_hir_type_ref_t type_ref) {
|
||||
if (!ctx || !type_ref) {
|
||||
LOG_ERROR("invalid parameter");
|
||||
return;
|
||||
}
|
||||
scc_hir_type_t *type = scc_hir_module_get_type(GET_MODULE(ctx), type_ref);
|
||||
if (!type) {
|
||||
LOG_ERROR("invalid type ref");
|
||||
return;
|
||||
}
|
||||
scc_tree_dump_begin_line(ctx->dump_ctx);
|
||||
scc_tree_dump_node(ctx->dump_ctx, "Type: ");
|
||||
scc_tree_dump_value(ctx->dump_ctx, "%s", get_type_tag_str(type->tag));
|
||||
|
||||
switch (type->tag) {
|
||||
case SCC_HIR_TYPE_PTR:
|
||||
if (type->data.pointer.base) {
|
||||
scc_tree_dump_push(ctx->dump_ctx, true);
|
||||
scc_hir_dump_type(ctx, type->data.pointer.base);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
break;
|
||||
case SCC_HIR_TYPE_ARRAY:
|
||||
if (type->data.array.len > 0) {
|
||||
scc_tree_dump_begin_line(ctx->dump_ctx);
|
||||
scc_tree_dump_node(ctx->dump_ctx, "Array Length: ");
|
||||
scc_tree_dump_value(ctx->dump_ctx, "%zu", type->data.array.len);
|
||||
scc_tree_dump_append(ctx->dump_ctx, "\n");
|
||||
}
|
||||
if (type->data.array.base) {
|
||||
scc_tree_dump_push(ctx->dump_ctx, true);
|
||||
scc_hir_dump_type(ctx, type->data.array.base);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
break;
|
||||
case SCC_HIR_TYPE_FUNC:
|
||||
for (usize i = 0; i < scc_vec_size(type->data.function.params); i++) {
|
||||
cbool is_last = (i + 1 == scc_vec_size(type->data.function.params));
|
||||
scc_tree_dump_push(ctx->dump_ctx, is_last);
|
||||
scc_hir_dump_type(ctx, scc_vec_at(type->data.function.params, i));
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
if (type->data.function.ret_type) {
|
||||
scc_tree_dump_push(ctx->dump_ctx, true);
|
||||
scc_hir_dump_type(ctx, type->data.function.ret_type);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
scc_hashtable_t visited;
|
||||
scc_hashtable_usize_init(&visited);
|
||||
dump_type_with_visited(ctx, type_ref, &visited);
|
||||
scc_hashtable_drop(&visited);
|
||||
}
|
||||
|
||||
void scc_hir_dump_bblock(scc_hir_dump_t *ctx, scc_hir_bblock_ref_t bblock_ref) {
|
||||
if (!ctx || !bblock_ref) {
|
||||
LOG_ERROR("invalid parameter");
|
||||
@@ -379,13 +333,94 @@ void scc_hir_dump_cprog(scc_hir_dump_t *ctx) {
|
||||
}
|
||||
|
||||
// ----- 线性输出(保留原逻辑,改用新 API)-----
|
||||
void scc_hir_dump_type_linear(scc_hir_dump_t *ctx,
|
||||
scc_hir_type_ref_t type_ref) {
|
||||
scc_hir_type_t *type = scc_hir_module_get_type(GET_MODULE(ctx), type_ref);
|
||||
if (!ctx || !type) {
|
||||
|
||||
// 在 scc_hir_dump.c 中添加以下静态辅助函数(放在文件前部,现有函数之前)
|
||||
|
||||
static void dump_type_linear_with_visited(scc_hir_dump_t *ctx,
|
||||
scc_hir_type_ref_t type_ref,
|
||||
scc_hashtable_t *visited);
|
||||
static void dump_type_with_visited(scc_hir_dump_t *ctx,
|
||||
scc_hir_type_ref_t type_ref,
|
||||
scc_hashtable_t *visited) {
|
||||
if (!ctx || !type_ref) {
|
||||
LOG_ERROR("invalid parameter");
|
||||
return;
|
||||
}
|
||||
// 检查循环
|
||||
if (scc_hashtable_get(visited, (void *)(usize)type_ref)) {
|
||||
scc_tree_dump_append(ctx->dump_ctx, " <recursive>");
|
||||
return;
|
||||
}
|
||||
scc_hashtable_set(visited, (void *)(usize)type_ref, (void *)1);
|
||||
|
||||
scc_hir_type_t *type = scc_hir_module_get_type(GET_MODULE(ctx), type_ref);
|
||||
if (!type) {
|
||||
LOG_ERROR("invalid type ref");
|
||||
return;
|
||||
}
|
||||
scc_tree_dump_begin_line(ctx->dump_ctx);
|
||||
scc_tree_dump_node(ctx->dump_ctx, "Type: ");
|
||||
scc_tree_dump_value(ctx->dump_ctx, "%s", get_type_tag_str(type->tag));
|
||||
|
||||
switch (type->tag) {
|
||||
case SCC_HIR_TYPE_PTR:
|
||||
if (type->data.pointer.base) {
|
||||
scc_tree_dump_push(ctx->dump_ctx, true);
|
||||
dump_type_with_visited(ctx, type->data.pointer.base, visited);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
break;
|
||||
case SCC_HIR_TYPE_ARRAY:
|
||||
if (type->data.array.len > 0) {
|
||||
scc_tree_dump_begin_line(ctx->dump_ctx);
|
||||
scc_tree_dump_node(ctx->dump_ctx, "Array Length: ");
|
||||
scc_tree_dump_value(ctx->dump_ctx, "%zu", type->data.array.len);
|
||||
scc_tree_dump_append(ctx->dump_ctx, "\n");
|
||||
}
|
||||
if (type->data.array.base) {
|
||||
scc_tree_dump_push(ctx->dump_ctx, true);
|
||||
dump_type_with_visited(ctx, type->data.array.base, visited);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
break;
|
||||
case SCC_HIR_TYPE_FUNC:
|
||||
for (usize i = 0; i < scc_vec_size(type->data.function.params); i++) {
|
||||
cbool is_last = (i + 1 == scc_vec_size(type->data.function.params));
|
||||
scc_tree_dump_push(ctx->dump_ctx, is_last);
|
||||
dump_type_with_visited(
|
||||
ctx, scc_vec_at(type->data.function.params, i), visited);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
if (type->data.function.ret_type) {
|
||||
scc_tree_dump_push(ctx->dump_ctx, true);
|
||||
dump_type_with_visited(ctx, type->data.function.ret_type, visited);
|
||||
scc_tree_dump_pop(ctx->dump_ctx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_type_linear_with_visited(scc_hir_dump_t *ctx,
|
||||
scc_hir_type_ref_t type_ref,
|
||||
scc_hashtable_t *visited) {
|
||||
if (!ctx || !type_ref) {
|
||||
LOG_ERROR("invalid parameter");
|
||||
return;
|
||||
}
|
||||
// 检查循环
|
||||
if (scc_hashtable_get(visited, (void *)(usize)type_ref)) {
|
||||
scc_tree_dump_append(ctx->dump_ctx, " <recursive>");
|
||||
return;
|
||||
}
|
||||
scc_hashtable_set(visited, (void *)(usize)type_ref, (void *)1);
|
||||
|
||||
scc_hir_type_t *type = scc_hir_module_get_type(GET_MODULE(ctx), type_ref);
|
||||
if (!type) {
|
||||
LOG_ERROR("invalid type ref");
|
||||
return;
|
||||
}
|
||||
switch (type->tag) {
|
||||
case SCC_HIR_TYPE_unknown:
|
||||
case SCC_HIR_TYPE_void:
|
||||
@@ -407,24 +442,25 @@ void scc_hir_dump_type_linear(scc_hir_dump_t *ctx,
|
||||
break;
|
||||
case SCC_HIR_TYPE_ARRAY:
|
||||
scc_tree_dump_append(ctx->dump_ctx, "[");
|
||||
scc_hir_dump_type_linear(ctx, type->data.array.base);
|
||||
dump_type_linear_with_visited(ctx, type->data.array.base, visited);
|
||||
scc_tree_dump_append_fmt(ctx->dump_ctx, ", %zu]", type->data.array.len);
|
||||
break;
|
||||
case SCC_HIR_TYPE_PTR:
|
||||
scc_tree_dump_append(ctx->dump_ctx, "*");
|
||||
scc_hir_dump_type_linear(ctx, type->data.pointer.base);
|
||||
dump_type_linear_with_visited(ctx, type->data.pointer.base, visited);
|
||||
break;
|
||||
case SCC_HIR_TYPE_FUNC:
|
||||
scc_tree_dump_append(ctx->dump_ctx, "(");
|
||||
for (usize i = 0; i < scc_vec_size(type->data.function.params); i++) {
|
||||
if (i > 0)
|
||||
scc_tree_dump_append(ctx->dump_ctx, ", ");
|
||||
scc_hir_dump_type_linear(ctx,
|
||||
scc_vec_at(type->data.function.params, i));
|
||||
dump_type_linear_with_visited(
|
||||
ctx, scc_vec_at(type->data.function.params, i), visited);
|
||||
}
|
||||
if (type->data.function.ret_type) {
|
||||
scc_tree_dump_append(ctx->dump_ctx, ") -> ");
|
||||
scc_hir_dump_type_linear(ctx, type->data.function.ret_type);
|
||||
dump_type_linear_with_visited(ctx, type->data.function.ret_type,
|
||||
visited);
|
||||
} else {
|
||||
scc_tree_dump_append(ctx->dump_ctx, ")");
|
||||
}
|
||||
@@ -434,9 +470,9 @@ void scc_hir_dump_type_linear(scc_hir_dump_t *ctx,
|
||||
scc_tree_dump_append_fmt(ctx->dump_ctx, "%s {",
|
||||
type->tag == SCC_HIR_TYPE_STRUCT ? "struct"
|
||||
: "union");
|
||||
scc_vec_foreach(type->data.aggregate.fields, i) {
|
||||
scc_hir_dump_type_linear(
|
||||
ctx, scc_vec_at(type->data.aggregate.fields, i));
|
||||
for (usize i = 0; i < scc_vec_size(type->data.aggregate.fields); i++) {
|
||||
dump_type_linear_with_visited(
|
||||
ctx, scc_vec_at(type->data.aggregate.fields, i), visited);
|
||||
scc_tree_dump_append(ctx->dump_ctx, ";");
|
||||
}
|
||||
scc_tree_dump_append(ctx->dump_ctx, "}");
|
||||
@@ -447,6 +483,14 @@ void scc_hir_dump_type_linear(scc_hir_dump_t *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
void scc_hir_dump_type_linear(scc_hir_dump_t *ctx,
|
||||
scc_hir_type_ref_t type_ref) {
|
||||
scc_hashtable_t visited;
|
||||
scc_hashtable_usize_init(&visited);
|
||||
dump_type_linear_with_visited(ctx, type_ref, &visited);
|
||||
scc_hashtable_drop(&visited);
|
||||
}
|
||||
|
||||
static void format_ref_or_value(scc_hir_dump_t *ctx,
|
||||
scc_hir_value_ref_t value_ref) {
|
||||
scc_hir_value_t *value =
|
||||
@@ -580,8 +624,8 @@ void scc_hir_dump_value_linear(scc_hir_dump_t *ctx,
|
||||
value->data.jump.target_bblock);
|
||||
break;
|
||||
case SCC_HIR_VALUE_TAG_CALL: {
|
||||
scc_hir_func_t *func =
|
||||
scc_hir_module_get_func(GET_MODULE(ctx), value->data.call.callee);
|
||||
scc_hir_func_t *func = scc_hir_module_get_func(
|
||||
GET_MODULE(ctx), value->data.call.callee.func_ref);
|
||||
scc_tree_dump_append_fmt(ctx->dump_ctx, "call @%s(",
|
||||
func ? (func->name ? func->name : "<unnamed>")
|
||||
: "<invalid>");
|
||||
|
||||
@@ -358,8 +358,8 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
break;
|
||||
}
|
||||
case SCC_HIR_VALUE_TAG_CALL: {
|
||||
scc_hir_func_t *callee =
|
||||
scc_hir_module_get_func(ctx->hir_module, value->data.call.callee);
|
||||
scc_hir_func_t *callee = scc_hir_module_get_func(
|
||||
ctx->hir_module, value->data.call.callee.func_ref);
|
||||
int arg_count = scc_vec_size(value->data.call.args);
|
||||
scc_lir_val_t *lir_args = scc_malloc(sizeof(scc_lir_val_t) * arg_count);
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
|
||||
Reference in New Issue
Block a user