feat(abi): 新增ABI类型布局描述接口和Windows x64实现

- 新增scc_abi包,包含基础类型布局描述接口
- 实现Windows x64 ABI类型布局计算功能
- 定义基本类型枚举和布局信息结构体
- 提供类型布局计算的核心接口函数

refactor(ast2ir): 使用新的ABI接口替换旧的类型转换实现

- 将旧的scc_type_abi_t替换为新的scc_abi_type_calc_t
- 更新AST到IR的类型转换逻辑,使用新的ABI计算接口
- 修改上下文初始化和类型解析相关代码
- 移除废弃的头文件和相关实现

refactor(ir): 统一IR节点引用类型命名并完善构建器功能

- 将scc_ir_node_ref_vec_t重命名为scc_ir_value_ref_vec_t保持一致性
- 更新聚合类型的字段名称从elements到fields
- 添加全局变量分配构建器函数scc_ir_builder_global_alloca
- 清理构建器中多余的注释和代码
This commit is contained in:
zzy
2026-04-12 11:30:31 +08:00
parent 630e22b73b
commit 694778e4a0
19 changed files with 383 additions and 274 deletions

View File

@@ -7,6 +7,7 @@ description = ""
dependencies = [
{ name = "scc_ast", path = "../ast" },
{ name = "scc_ir", path = "../ir" },
{ name = "scc_abi", path = "../abi" },
]
# features = {}
# default_features = []

View File

@@ -1,141 +0,0 @@
#ifndef __SCC_WIN_X64_TYPE_ABI_H__
#define __SCC_WIN_X64_TYPE_ABI_H__
#include "../scc_type_abi.h"
/**
* @brief Windows x64 ABI Type
* @details
* https://learn.microsoft.com/zh-cn/cpp/build/x64-software-conventions?view=msvc-180
*/
static const scc_type_abi_t scc_win_x64_type_abi[] = {
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN,
.ir_type = SCC_IR_TYPE_unknown,
.size = 0,
.alignment = 0,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_VOID,
.ir_type = SCC_IR_TYPE_void,
.size = 0,
.alignment = 0,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_BOOL,
.ir_type = SCC_IR_TYPE_u8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_CHAR,
.ir_type = SCC_IR_TYPE_i8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR,
.ir_type = SCC_IR_TYPE_i8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR,
.ir_type = SCC_IR_TYPE_u8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SHORT,
.ir_type = SCC_IR_TYPE_i16,
.size = 2,
.alignment = 2,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_SHORT,
.ir_type = SCC_IR_TYPE_i16,
.size = 2,
.alignment = 2,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT,
.ir_type = SCC_IR_TYPE_u16,
.size = 2,
.alignment = 2,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_INT,
.ir_type = SCC_IR_TYPE_i32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_INT,
.ir_type = SCC_IR_TYPE_i32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_INT,
.ir_type = SCC_IR_TYPE_u32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_LONG,
.ir_type = SCC_IR_TYPE_i32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG,
.ir_type = SCC_IR_TYPE_i32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG,
.ir_type = SCC_IR_TYPE_u32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_LONG_LONG,
.ir_type = SCC_IR_TYPE_i64,
.size = 8,
.alignment = 8,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG,
.ir_type = SCC_IR_TYPE_i64,
.size = 8,
.alignment = 8,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG,
.ir_type = SCC_IR_TYPE_i64,
.size = 8,
.alignment = 8,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_FLOAT,
.ir_type = SCC_IR_TYPE_f32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_DOUBLE,
.ir_type = SCC_IR_TYPE_f64,
.size = 8,
.alignment = 8,
},
{
// nullptr
.ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN,
.ir_type = SCC_IR_TYPE_unknown,
.size = 0,
.alignment = 0,
},
};
#endif /* __SCC_WIN_X64_TYPE_ABI_H__ */

View File

@@ -8,19 +8,20 @@
typedef struct {
scc_ir_builder_t builder;
scc_hashtable_t decl2ir_ref; ///< decl to ir_ref
scc_hashtable_t symtab; ///< symbol to ir_ref
scc_hashtable_t ast2ir_cache; ///< ast node to ir ref cache
scc_hashtable_t symtab; ///< symbol to ir_ref
// scc_strpool_t strpool; ///< string pool
const scc_type_abi_t *abi;
const scc_abi_type_calc_t *abi;
} scc_ast2ir_ctx_t;
void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi,
void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi,
scc_ir_cprog_t *cprog);
void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx);
void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx,
scc_ast_translation_unit_t *tu);
void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl);
void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl,
cbool is_global);
scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
cbool is_lvalue);
void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt);

View File

@@ -1,14 +0,0 @@
#ifndef __SCC_TYPE_ABI_H__
#define __SCC_TYPE_ABI_H__
#include <ast_def.h>
#include <ir_def.h>
typedef struct {
scc_ast_builtin_type_t ast_type;
scc_ir_type_tag_t ir_type;
usize size;
usize alignment;
} scc_type_abi_t;
#endif /* __SCC_TYPE_ABI_H__ */

View File

@@ -1,5 +1,30 @@
#include "ast_def.h"
#include "ir_builder.h"
#include "ir_def.h"
#include "log.h"
#include <scc_ast2ir.h>
static scc_ir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx,
scc_ast_type_t *ast_type) {
scc_abi_type_layout_t layout;
// 映射内置类型
ctx->abi->compute_type_layout(ctx->abi, ast_type, &layout);
switch (layout.size) {
case 1:
return scc_ir_builder_type_i8(&ctx->builder);
case 2:
return scc_ir_builder_type_i16(&ctx->builder);
case 4:
return scc_ir_builder_type_i32(&ctx->builder);
case 8:
return scc_ir_builder_type_i64(&ctx->builder);
break;
default:
break;
}
return SCC_IR_REF_nullptr;
}
static inline void parse_struct_union_layout(scc_ast_type_t *type) {}
static inline void parse_lexme2const_int(const char *lexme,
@@ -22,27 +47,7 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
switch (ast_type->base.type) {
case SCC_AST_TYPE_BUILTIN: {
// 映射内置类型
scc_ir_type_init(&ir_type, SCC_IR_TYPE_i32);
// TODO: 根据具体内置类型设置
switch (ast_type->builtin.type) {
case SCC_AST_BUILTIN_TYPE_VOID:
return scc_ir_builder_type_void(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_CHAR:
case SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR:
return scc_ir_builder_type_u8(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_SIGNED_CHAR:
return scc_ir_builder_type_i8(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_INT:
case SCC_AST_BUILTIN_TYPE_SIGNED_INT:
return scc_ir_builder_type_i32(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_UNSIGNED_INT:
return scc_ir_builder_type_u32(&ctx->builder);
default:
Panic("Unsupported AST type: %d", ast_type->builtin.type);
break;
}
break;
return parse_base_type(ctx, ast_type);
}
case SCC_AST_TYPE_POINTER: {
scc_ir_type_init(&ir_type, SCC_IR_TYPE_PTR);
@@ -94,11 +99,27 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
ir_type.data.function.params = params;
break;
}
// SCC_AST_TYPE_STRUCT, // 结构体类型
// SCC_AST_TYPE_UNION, // 联合类型
// SCC_AST_TYPE_ENUM, // 枚举类型
case SCC_AST_TYPE_TYPEDEF:
case SCC_AST_TYPE_STRUCT:
case SCC_AST_TYPE_UNION: {
scc_ir_type_init(&ir_type, ast_type->base.type == SCC_AST_TYPE_STRUCT
? SCC_IR_TYPE_STRUCT
: SCC_IR_TYPE_UNION);
scc_vec_foreach(ast_type->record.decl->record.fields, i) {
scc_ast_decl_t *decl_field =
scc_vec_at(ast_type->record.decl->record.fields, i);
Assert(decl_field->base.type == SCC_AST_DECL_VAR);
scc_ir_type_ref_t field_type =
scc_ast2ir_type(ctx, decl_field->var.type);
scc_vec_push(ir_type.data.aggregate.fields, field_type);
}
break;
}
case SCC_AST_TYPE_ENUM:
return parse_base_type(
ctx, &(scc_ast_type_t){.base.type = SCC_AST_TYPE_BUILTIN,
.builtin = SCC_AST_BUILTIN_TYPE_INT});
case SCC_AST_TYPE_TYPEDEF:
return 0;
default:
LOG_FATAL("Unsupported AST type: %d", ast_type->base.type);
return 0;
@@ -401,7 +422,7 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
}
case SCC_AST_EXPR_CALL: {
// 转换参数
scc_ir_node_ref_vec_t args;
scc_ir_value_ref_vec_t args;
scc_vec_init(args);
scc_vec_foreach(expr->call.args, i) {
@@ -441,23 +462,30 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
elem_ptr); // 作为右值:加载值
}
}
// SCC_AST_EXPR_MEMBER, // 成员访问 .
// SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 ->
case SCC_AST_EXPR_MEMBER:
break;
case SCC_AST_EXPR_PTR_MEMBER:
break;
// SCC_AST_EXPR_CAST, // 类型转换
case SCC_AST_EXPR_SIZE_OF: {
scc_ir_const_int_t val;
val.int64 = 1;
// FIXME
TODO();
val.int64 = 1; // HACK
return scc_ir_builder_const_int(
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val);
}
case SCC_AST_EXPR_ALIGN_OF: {
scc_ir_const_int_t val;
val.int64 = 1;
TODO();
val.int64 = 8;
return scc_ir_builder_const_int(
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val);
}
// SCC_AST_EXPR_COMPOUND, // 复合字面量
// SCC_AST_EXPR_LVALUE, // 右值
case SCC_AST_EXPR_COMPOUND:
break;
case SCC_AST_EXPR_LVALUE:
break;
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
case SCC_AST_EXPR_INT_LITERAL: {
// FIXME maybe using some array to int;
@@ -512,7 +540,7 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
}
// FIXME hack hashtable
scc_ir_value_ref_t in = (scc_ir_value_ref_t)(usize)scc_hashtable_get(
&ctx->decl2ir_ref, expr->identifier._target);
&ctx->ast2ir_cache, expr->identifier._target);
Assert(in != 0);
if (is_lvalue) {
return in;
@@ -563,8 +591,8 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ast2ir_stmt(ctx,
SCC_AST_CAST_TO(scc_ast_stmt_t, child_stmt));
} else if (SCC_AST_IS_A(scc_ast_decl_t, child_stmt)) {
scc_ast2ir_decl(ctx,
SCC_AST_CAST_TO(scc_ast_decl_t, child_stmt));
scc_ast2ir_decl(
ctx, SCC_AST_CAST_TO(scc_ast_decl_t, child_stmt), false);
} else {
UNREACHABLE();
}
@@ -667,7 +695,8 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
if (stmt->for_stmt.init) {
if (SCC_AST_IS_A(scc_ast_decl_t, stmt->for_stmt.init)) {
scc_ast2ir_decl(
ctx, SCC_AST_CAST_TO(scc_ast_decl_t, stmt->for_stmt.init));
ctx, SCC_AST_CAST_TO(scc_ast_decl_t, stmt->for_stmt.init),
false);
} else if (SCC_AST_IS_A(scc_ast_expr_t, stmt->for_stmt.init)) {
scc_ast2ir_expr(
ctx, SCC_AST_CAST_TO(scc_ast_expr_t, stmt->for_stmt.init),
@@ -728,7 +757,8 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
* @param ctx
* @param decl
*/
void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl,
cbool is_global) {
if (ctx == nullptr || decl == nullptr) {
LOG_ERROR("Invalid argument");
return;
@@ -738,11 +768,20 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
case SCC_AST_DECL_VAR: {
// 转换类型
scc_ir_type_ref_t ir_type_ref = scc_ast2ir_type(ctx, decl->var.type);
// 创建分配节点
scc_ir_value_ref_t alloc_val_node =
scc_ir_builder_alloca(&ctx->builder, ir_type_ref, decl->name);
scc_hashtable_set(&ctx->decl2ir_ref, decl,
// 创建分配节点
scc_ir_value_ref_t alloc_val_node = SCC_IR_REF_nullptr;
if (is_global) {
// alloc_val_node = scc_ir_builder_global_alloca(
// &ctx->builder, ir_type_ref, decl->name);
return;
} else {
alloc_val_node =
scc_ir_builder_alloca(&ctx->builder, ir_type_ref, decl->name);
}
Assert(alloc_val_node != SCC_IR_REF_nullptr);
scc_hashtable_set(&ctx->ast2ir_cache, decl,
(void *)(usize)alloc_val_node);
// 如果有初始化表达式
@@ -812,7 +851,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
ctx->builder.ctx.module, param_node_ref);
Assert(param_node != nullptr);
param_node->name = param->name;
scc_hashtable_set(&ctx->decl2ir_ref, param,
scc_hashtable_set(&ctx->ast2ir_cache, param,
(void *)(usize)param_node_ref);
}
scc_ast2ir_stmt(ctx, decl->func.body);
@@ -826,7 +865,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
case SCC_AST_DECL_LIST: {
scc_vec_foreach(decl->list.vars, i) {
scc_ast_decl_t *sub_decl = scc_vec_at(decl->list.vars, i);
scc_ast2ir_decl(ctx, sub_decl);
scc_ast2ir_decl(ctx, sub_decl, is_global);
}
break;
}
@@ -835,10 +874,15 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
}
case SCC_AST_DECL_STRUCT:
case SCC_AST_DECL_UNION:
scc_vec_foreach(decl->record.fields, i) {
scc_ast_decl_t *item = scc_vec_at(decl->record.fields, i);
scc_ast2ir_decl(ctx, item);
}
scc_ast_type_t type = {
.base.type =
SCC_AST_DECL_STRUCT ? SCC_AST_TYPE_STRUCT : SCC_AST_TYPE_UNION,
.record.decl = decl,
.record.name = decl->name,
};
scc_ir_type_ref_t type_ref = scc_ast2ir_type(ctx, &type);
scc_ir_builder_global_alloca(&ctx->builder, type_ref,
SCC_IR_REF_nullptr);
break;
case SCC_AST_DECL_ENUM:
scc_ir_const_int_t val;
@@ -852,7 +896,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
}
scc_ir_value_ref_t item_val_ref = scc_ir_builder_const_int(
&ctx->builder, scc_ir_builder_type_i32(&ctx->builder), val);
scc_hashtable_set(&ctx->decl2ir_ref, item,
scc_hashtable_set(&ctx->ast2ir_cache, item,
(void *)(usize)item_val_ref);
val.int32 += 1;
}
@@ -871,7 +915,7 @@ void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx,
scc_vec_foreach(tu->declarations, i) {
scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i);
scc_ast2ir_decl(ctx, decl);
scc_ast2ir_decl(ctx, decl, true);
}
}
@@ -880,18 +924,18 @@ static int scc_cmp_node(const void *key1, const void *key2) {
return (u32)(usize)key1 - (u32)(usize)key2;
}
void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi,
void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi,
scc_ir_cprog_t *cprog) {
Assert(ctx != nullptr);
ctx->abi = abi;
scc_ir_builder_init(&ctx->builder, cprog);
scc_hashtable_init(&ctx->decl2ir_ref, scc_hash_node, scc_cmp_node);
scc_hashtable_init(&ctx->ast2ir_cache, scc_hash_node, scc_cmp_node);
scc_hashtable_init(&ctx->symtab, (scc_hashtable_hash_func_t)scc_strhash32,
(scc_hashtable_equal_func_t)scc_strcmp);
}
void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx) {
scc_ir_builder_drop(&ctx->builder);
scc_hashtable_drop(&ctx->decl2ir_ref);
scc_hashtable_drop(&ctx->ast2ir_cache);
scc_hashtable_drop(&ctx->symtab);
}