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:
9
libs/abi/cbuild.toml
Normal file
9
libs/abi/cbuild.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "scc_abi"
|
||||
version = "0.1.0"
|
||||
authors = []
|
||||
description = ""
|
||||
|
||||
# dependencies = []
|
||||
# features = {}
|
||||
# default_features = []
|
||||
105
libs/abi/include/scc_type_abi.h
Normal file
105
libs/abi/include/scc_type_abi.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @file scc_abi_type.h
|
||||
* @brief 目标无关的类型布局描述接口
|
||||
* @note 本模块仅定义接口。
|
||||
*/
|
||||
|
||||
#ifndef __SCC_ABI_TYPE_H__
|
||||
#define __SCC_ABI_TYPE_H__
|
||||
|
||||
#include <scc_core.h>
|
||||
|
||||
/**
|
||||
* @brief ABI 基础类型类别枚举。
|
||||
*
|
||||
* 用于快速查询目标预定义的基本类型属性。复杂类型(指针、数组、结构体)
|
||||
* 通过组合与递归计算。
|
||||
*/
|
||||
typedef enum scc_abi_base_type_kind {
|
||||
SCC_ABI_TYPE_VOID,
|
||||
SCC_ABI_TYPE_CHAR,
|
||||
SCC_ABI_TYPE_I_CHAR,
|
||||
SCC_ABI_TYPE_U_CHAR,
|
||||
SCC_ABI_TYPE_I_SHORT,
|
||||
SCC_ABI_TYPE_U_SHORT,
|
||||
SCC_ABI_TYPE_I_INT,
|
||||
SCC_ABI_TYPE_U_INT,
|
||||
SCC_ABI_TYPE_I_LONG,
|
||||
SCC_ABI_TYPE_U_LONG,
|
||||
SCC_ABI_TYPE_I_LONG_LONG,
|
||||
SCC_ABI_TYPE_U_LONG_LONG,
|
||||
SCC_ABI_TYPE_PTR,
|
||||
SCC_ABI_TYPE_FLOAT,
|
||||
SCC_ABI_TYPE_DOUBLE,
|
||||
SCC_ABI_TYPE_USIZE,
|
||||
SCC_ABI_TYPE_ISIZE,
|
||||
/* 可扩展:I128, F16, F128, VECTOR, ... */
|
||||
} scc_abi_base_type_kind_t;
|
||||
|
||||
/**
|
||||
* @brief 单个类型的布局信息。
|
||||
*/
|
||||
typedef struct scc_abi_type_layout {
|
||||
int size; /**< 类型占用的字节数 */
|
||||
int alignment; /**< 类型的对齐要求(字节边界) */
|
||||
} scc_abi_type_layout_t;
|
||||
|
||||
typedef struct {
|
||||
scc_abi_base_type_kind_t kind;
|
||||
scc_abi_type_layout_t layout;
|
||||
} scc_abi_base_type_impl_t;
|
||||
#define SCC_ABI_BASE_TYPE_IMPL(type, bytes_size, alians) \
|
||||
[type] = { \
|
||||
.kind = type, \
|
||||
.layout.size = bytes_size, \
|
||||
.layout.alignment = alians, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 单个结构体字段的布局信息。
|
||||
* 由目标布局算法填充,用于 IR 的 getelementptr 常量索引计算。
|
||||
*/
|
||||
typedef struct scc_abi_field_layout {
|
||||
int offset; /**< 字段相对于结构体基址的字节偏移 */
|
||||
int size; /**< 字段自身大小 */
|
||||
int alignment; /**< 字段的对齐要求 */
|
||||
} scc_abi_field_layout_t;
|
||||
|
||||
typedef SCC_VEC(scc_abi_field_layout_t) scc_abi_field_layout_vec_t;
|
||||
|
||||
/**
|
||||
* @brief 获取基本类型的布局信息。
|
||||
*
|
||||
* 目标必须实现此函数,为每个 scc_abi_base_type_kind_t 返回正确的
|
||||
* size/alignment。
|
||||
*
|
||||
* @param kind 基本类型类别
|
||||
* @param layout 输出参数,存放布局信息
|
||||
* @return 成功返回 0,若 kind 不支持则返回 -1
|
||||
*/
|
||||
static inline void
|
||||
scc_abi_get_base_type_layout(const scc_abi_base_type_impl_t *impls,
|
||||
scc_abi_base_type_kind_t kind,
|
||||
scc_abi_type_layout_t *layout) {
|
||||
if (impls[kind].kind != kind)
|
||||
Panic("invalid base type kind");
|
||||
*layout = impls[kind].layout;
|
||||
}
|
||||
|
||||
typedef struct scc_abi_type_calc scc_abi_type_calc_t;
|
||||
|
||||
void scc_abi_compute_ast_type_layout(const scc_abi_type_calc_t *ctx, void *type,
|
||||
scc_abi_type_layout_t *layout);
|
||||
|
||||
typedef struct scc_abi_type_calc {
|
||||
void *ctx;
|
||||
const scc_abi_base_type_impl_t *impls;
|
||||
/// @brief 可以是系统内置的结构,比如 struct int128_t
|
||||
void (*compute_type_layout)(const scc_abi_type_calc_t *ctx, void *type,
|
||||
scc_abi_type_layout_t *layout);
|
||||
/// @brief
|
||||
void (*compute_field_layout)(const scc_abi_type_calc_t *ctx, void *type,
|
||||
scc_abi_field_layout_vec_t *field_layouts);
|
||||
} scc_abi_type_calc_t;
|
||||
|
||||
#endif /* __SCC_ABI_TYPE_H__ */
|
||||
4
libs/abi/include/target/scc_abi_dummy.h
Normal file
4
libs/abi/include/target/scc_abi_dummy.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef __SCC_ABI_DUMMY_H__
|
||||
#define __SCC_ABI_DUMMY_H__
|
||||
|
||||
#endif /* __SCC_ABI_DUMMY_H__ */
|
||||
40
libs/abi/include/target/scc_abi_win_x64_pc.h
Normal file
40
libs/abi/include/target/scc_abi_win_x64_pc.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef __SCC_ABI_WIN_X64_PC_H__
|
||||
#define __SCC_ABI_WIN_X64_PC_H__
|
||||
/**
|
||||
* @brief Windows x64 ABI Type
|
||||
* @details
|
||||
* https://learn.microsoft.com/zh-cn/cpp/build/x64-software-conventions?view=msvc-180
|
||||
*/
|
||||
|
||||
#include "../scc_type_abi.h"
|
||||
|
||||
static const scc_abi_base_type_impl_t scc_abi_base_type_impls[] = {
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_VOID, 0, 0),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_CHAR, 1, 1),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_I_CHAR, 1, 1),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_U_CHAR, 1, 1),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_I_SHORT, 2, 2),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_U_SHORT, 2, 2),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_I_INT, 4, 4),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_U_INT, 4, 4),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_I_LONG, 4, 4),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_U_LONG, 4, 4),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_I_LONG_LONG, 8, 8),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_U_LONG_LONG, 8, 8),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_PTR, 8, 8),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_FLOAT, 4, 4),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_DOUBLE, 8, 8),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_USIZE, 8, 8),
|
||||
SCC_ABI_BASE_TYPE_IMPL(SCC_ABI_TYPE_ISIZE, 8, 8),
|
||||
};
|
||||
|
||||
static const scc_abi_type_calc_t scc_ast_abi_impl = {
|
||||
.impls = scc_abi_base_type_impls,
|
||||
.ctx = nullptr,
|
||||
.compute_type_layout = scc_abi_compute_ast_type_layout,
|
||||
.compute_field_layout = nullptr,
|
||||
};
|
||||
#ifdef SCC_ABI_IMPLIMENT
|
||||
#endif
|
||||
|
||||
#endif /* __SCC_ABI_WIN_X64_PC_H__ */
|
||||
62
libs/abi/src/scc_type_abi.c
Normal file
62
libs/abi/src/scc_type_abi.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <scc_ast.h>
|
||||
#include <scc_ir.h>
|
||||
#include <scc_type_abi.h>
|
||||
|
||||
void scc_abi_compute_ast_type_layout(const scc_abi_type_calc_t *ctx, void *type,
|
||||
scc_abi_type_layout_t *layout) {
|
||||
scc_ast_type_t *ast_type = type;
|
||||
scc_abi_base_type_kind_t kind = SCC_ABI_TYPE_VOID;
|
||||
switch (ast_type->builtin.type) {
|
||||
case SCC_AST_BUILTIN_TYPE_VOID:
|
||||
kind = SCC_ABI_TYPE_VOID;
|
||||
case SCC_AST_BUILTIN_TYPE_CHAR:
|
||||
kind = SCC_ABI_TYPE_CHAR;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR:
|
||||
kind = SCC_ABI_TYPE_U_CHAR;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_SIGNED_CHAR:
|
||||
kind = SCC_ABI_TYPE_I_CHAR;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_SHORT:
|
||||
kind = SCC_ABI_TYPE_I_SHORT;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_SIGNED_SHORT:
|
||||
kind = SCC_ABI_TYPE_I_SHORT;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT:
|
||||
kind = SCC_ABI_TYPE_U_SHORT;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_INT:
|
||||
kind = SCC_ABI_TYPE_I_INT;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_SIGNED_INT:
|
||||
kind = SCC_ABI_TYPE_I_INT;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_UNSIGNED_INT:
|
||||
kind = SCC_ABI_TYPE_U_INT;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_LONG:
|
||||
kind = SCC_ABI_TYPE_I_LONG;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_SIGNED_LONG:
|
||||
kind = SCC_ABI_TYPE_I_LONG;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG:
|
||||
kind = SCC_ABI_TYPE_U_LONG;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_LONG_LONG:
|
||||
kind = SCC_ABI_TYPE_I_LONG_LONG;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG:
|
||||
kind = SCC_ABI_TYPE_I_LONG_LONG;
|
||||
break;
|
||||
case SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG:
|
||||
kind = SCC_ABI_TYPE_U_LONG_LONG;
|
||||
break;
|
||||
default:
|
||||
Panic("Unsupported AST type: %d", ast_type->builtin.type);
|
||||
break;
|
||||
}
|
||||
scc_abi_get_base_type_layout(ctx->impls, kind, layout);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ description = ""
|
||||
dependencies = [
|
||||
{ name = "scc_ast", path = "../ast" },
|
||||
{ name = "scc_ir", path = "../ir" },
|
||||
{ name = "scc_abi", path = "../abi" },
|
||||
]
|
||||
# features = {}
|
||||
# default_features = []
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,19 @@ scc_ir_type_ref_t scc_ir_builder_type(scc_ir_builder_t *builder,
|
||||
void scc_ir_builder_add_instr(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t instr);
|
||||
|
||||
scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder,
|
||||
scc_ir_type_ref_t type,
|
||||
scc_ir_value_ref_t value);
|
||||
|
||||
/**
|
||||
* @brief 创建alloca指令(在当前基本块中)
|
||||
* @param type 分配的类型
|
||||
* @param name 变量名(可为nullptr)
|
||||
*/
|
||||
scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
|
||||
scc_ir_type_ref_t type,
|
||||
const char *name);
|
||||
|
||||
#define SCC_IR_BUILDER_TYPE_FUNC(scc_type) \
|
||||
[[maybe_unused]] static inline scc_ir_type_ref_t \
|
||||
scc_ir_builder_type_##scc_type(scc_ir_builder_t *builder) { \
|
||||
@@ -122,25 +135,15 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
|
||||
buff[i - 1] = str[i];
|
||||
}
|
||||
buff[len - 2] = '\0';
|
||||
scc_vec_unsafe_from_buffer(const_array_value.data.const_array.elements,
|
||||
scc_vec_unsafe_from_buffer(const_array_value.data.const_array.fields,
|
||||
(u8 *)buff, len - 1);
|
||||
scc_ir_value_ref_t const_array_ref =
|
||||
scc_ir_module_add_value(builder->ctx.module, &const_array_value);
|
||||
Assert(const_array_ref != SCC_IR_REF_nullptr);
|
||||
|
||||
// 3. 创建全局变量节点,类型为指针,初始值指向常量数组
|
||||
char *name = scc_malloc(32);
|
||||
// FIXME MAYBE MEMORY LEAK
|
||||
|
||||
scc_ir_value_ref_t global_value_ref = scc_ir_module_add_value(
|
||||
builder->ctx.module, &(scc_ir_value_t){
|
||||
.name = name,
|
||||
.tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC,
|
||||
.type = array_type_ref,
|
||||
.data.global_alloc.value = const_array_ref,
|
||||
});
|
||||
scc_snprintf(name, 32, "$G%u", global_value_ref);
|
||||
scc_vec_push(builder->cprog->global_vals, global_value_ref);
|
||||
scc_ir_value_ref_t global_value_ref =
|
||||
scc_ir_builder_global_alloca(builder, array_type_ref, const_array_ref);
|
||||
// scc_hashtable_insert(builder);
|
||||
|
||||
scc_ir_value_ref_t pointer_to_global_value = scc_ir_module_add_value(
|
||||
@@ -203,15 +206,6 @@ scc_ir_func_ref_t scc_ir_builder_current_bblock(scc_ir_builder_t *builder);
|
||||
void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder,
|
||||
scc_ir_bblock_ref_t bblock);
|
||||
|
||||
/**
|
||||
* @brief 创建alloca指令(在当前基本块中)
|
||||
* @param type 分配的类型
|
||||
* @param name 变量名(可为nullptr)
|
||||
*/
|
||||
scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
|
||||
scc_ir_type_ref_t type,
|
||||
const char *name);
|
||||
|
||||
scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder,
|
||||
scc_ir_type_ref_t type,
|
||||
const char *name, usize arg_idx);
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef SCC_VEC(u8) scc_ir_buffer_t;
|
||||
|
||||
typedef struct scc_ir_value scc_ir_value_t;
|
||||
typedef ir_handle_t scc_ir_value_ref_t;
|
||||
typedef SCC_VEC(scc_ir_value_ref_t) scc_ir_node_ref_vec_t;
|
||||
typedef SCC_VEC(scc_ir_value_ref_t) scc_ir_value_ref_vec_t;
|
||||
|
||||
typedef struct scc_ir_type scc_ir_type_t;
|
||||
typedef ir_handle_t scc_ir_type_ref_t;
|
||||
@@ -63,7 +63,7 @@ struct scc_ir_type {
|
||||
scc_ir_type_ref_t base;
|
||||
} pointer;
|
||||
struct {
|
||||
scc_ir_type_ref_vec_t elements;
|
||||
scc_ir_type_ref_vec_t fields;
|
||||
} aggregate;
|
||||
struct {
|
||||
scc_ir_type_ref_vec_t params;
|
||||
@@ -74,14 +74,14 @@ struct scc_ir_type {
|
||||
|
||||
struct scc_ir_bblock {
|
||||
scc_ir_label_t label;
|
||||
scc_ir_node_ref_vec_t instrs;
|
||||
scc_ir_value_ref_vec_t instrs;
|
||||
// ir_arr_t used_by;
|
||||
}; // basic block
|
||||
|
||||
struct scc_ir_func {
|
||||
scc_ir_label_t name;
|
||||
scc_ir_type_ref_t type;
|
||||
scc_ir_node_ref_vec_t params;
|
||||
scc_ir_value_ref_vec_t params;
|
||||
scc_ir_bblock_ref_vec_t bblocks;
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@ typedef enum {
|
||||
struct scc_ir_value {
|
||||
scc_ir_type_ref_t type;
|
||||
scc_ir_label_t name;
|
||||
scc_ir_node_ref_vec_t used_by;
|
||||
scc_ir_value_ref_vec_t used_by;
|
||||
scc_ir_value_tag_t tag;
|
||||
union {
|
||||
scc_ir_builtin_t builtin;
|
||||
@@ -234,10 +234,10 @@ struct scc_ir_value {
|
||||
scc_ir_const_float_t const_float;
|
||||
struct {
|
||||
scc_ir_value_ref_t base_type;
|
||||
scc_ir_buffer_t elements;
|
||||
scc_ir_buffer_t fields;
|
||||
} const_array;
|
||||
struct {
|
||||
scc_ir_node_ref_vec_t elements;
|
||||
scc_ir_value_ref_vec_t fields;
|
||||
} aggregate;
|
||||
struct {
|
||||
usize idx;
|
||||
@@ -276,7 +276,7 @@ struct scc_ir_value {
|
||||
} jump;
|
||||
struct {
|
||||
scc_ir_func_ref_t callee; // TODO function pointer call
|
||||
scc_ir_node_ref_vec_t args;
|
||||
scc_ir_value_ref_vec_t args;
|
||||
} call;
|
||||
struct {
|
||||
scc_ir_value_ref_t ret_val;
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
typedef struct scc_ir_cprog {
|
||||
scc_ir_module_t module;
|
||||
scc_ir_node_ref_vec_t global_vals; /* 全局变量 */
|
||||
scc_ir_func_ref_vec_t func_defs; /* 所有函数定义 */
|
||||
scc_ir_func_ref_vec_t func_decls; /* 所有函数包括定义的声明 */
|
||||
scc_ir_value_ref_vec_t global_vals; /* 全局变量 */
|
||||
scc_ir_func_ref_vec_t func_defs; /* 所有函数定义 */
|
||||
scc_ir_func_ref_vec_t func_decls; /* 所有函数包括定义的声明 */
|
||||
} scc_ir_cprog_t;
|
||||
|
||||
void scc_ir_cprog_init(scc_ir_cprog_t *in);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "ir_def.h"
|
||||
#include <ir_builder.h>
|
||||
#include <ir_prog.h>
|
||||
|
||||
@@ -147,6 +148,24 @@ void scc_ir_builder_add_instr(scc_ir_builder_t *builder,
|
||||
}
|
||||
}
|
||||
|
||||
scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder,
|
||||
scc_ir_type_ref_t type,
|
||||
scc_ir_value_ref_t value) {
|
||||
// FIXME MAYBE MEMORY LEAK
|
||||
char *name = scc_malloc(32);
|
||||
scc_ir_value_ref_t global_value_ref = scc_ir_module_add_value(
|
||||
builder->ctx.module, &(scc_ir_value_t){
|
||||
.name = name,
|
||||
.tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC,
|
||||
.type = type,
|
||||
.data.global_alloc.value = value,
|
||||
});
|
||||
scc_snprintf(name, 32, "$G%u", global_value_ref);
|
||||
|
||||
scc_vec_push(builder->cprog->global_vals, global_value_ref);
|
||||
return global_value_ref;
|
||||
}
|
||||
|
||||
scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
|
||||
scc_ir_type_ref_t type,
|
||||
const char *name) {
|
||||
@@ -160,9 +179,7 @@ scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &alloc_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -178,7 +195,7 @@ scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder,
|
||||
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &value);
|
||||
// 添加到当前基本块
|
||||
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
@@ -203,9 +220,7 @@ scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &load_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -221,9 +236,7 @@ scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &store_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -259,9 +272,7 @@ scc_ir_value_ref_t scc_ir_builder_get_elem_ptr(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &get_ptr_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -285,9 +296,7 @@ scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &binop_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -323,9 +332,7 @@ scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &jump_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -342,9 +349,7 @@ scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &branch_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -375,9 +380,7 @@ scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &call_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -390,9 +393,7 @@ scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder,
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &ret_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -404,7 +405,6 @@ scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) {
|
||||
scc_ir_value_ref_t value_ref =
|
||||
scc_ir_module_add_value(GET_MODULE(builder), &ret_node);
|
||||
|
||||
// 添加到当前基本块
|
||||
scc_ir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
@@ -535,9 +535,9 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx,
|
||||
break;
|
||||
case SCC_IR_VALUE_TAG_AGGREGATE:
|
||||
// 聚合类型:递归输出每个元素(每个占一行)
|
||||
scc_vec_foreach(value->data.aggregate.elements, i) {
|
||||
scc_vec_foreach(value->data.aggregate.fields, i) {
|
||||
scc_ir_dump_value_linear(
|
||||
ctx, scc_vec_at(value->data.aggregate.elements, i));
|
||||
ctx, scc_vec_at(value->data.aggregate.fields, i));
|
||||
scc_tree_dump_append(ctx->dump_ctx, "\n");
|
||||
}
|
||||
return;
|
||||
@@ -618,8 +618,8 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx,
|
||||
scc_tree_dump_append(ctx->dump_ctx, "const_array ");
|
||||
scc_ir_dump_type_linear(ctx, value->data.const_array.base_type);
|
||||
scc_tree_dump_append(ctx->dump_ctx, " [");
|
||||
scc_vec_foreach(value->data.const_array.elements, i) {
|
||||
u8 ch = scc_vec_at(value->data.const_array.elements, i);
|
||||
scc_vec_foreach(value->data.const_array.fields, i) {
|
||||
u8 ch = scc_vec_at(value->data.const_array.fields, i);
|
||||
scc_tree_dump_append_fmt(ctx->dump_ctx, " `%c`, ", ch ? ch : ' ');
|
||||
}
|
||||
scc_tree_dump_append(ctx->dump_ctx, " ]");
|
||||
|
||||
@@ -33,6 +33,10 @@ void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) {
|
||||
scc_vec_init(in->data.function.params);
|
||||
in->data.function.ret_type = 0;
|
||||
break;
|
||||
case SCC_IR_TYPE_UNION:
|
||||
case SCC_IR_TYPE_STRUCT:
|
||||
scc_vec_init(in->data.aggregate.fields);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
@@ -674,9 +674,9 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
.sccf_sym_type = SCCF_SYM_TYPE_DATA,
|
||||
.sccf_sym_vis = SCCF_SYM_VIS_DEFAULT,
|
||||
};
|
||||
scc_vec_foreach(value->data.const_array.elements, j) {
|
||||
scc_vec_foreach(value->data.const_array.fields, j) {
|
||||
scc_vec_push(ctx->sect_data,
|
||||
scc_vec_at(value->data.const_array.elements, j));
|
||||
scc_vec_at(value->data.const_array.fields, j));
|
||||
}
|
||||
usize sym_idx =
|
||||
sccf_builder_add_symbol(ctx->builder, galloc->name, &sym);
|
||||
|
||||
Reference in New Issue
Block a user