在scc_type_abi.c文件中,void类型的case分支缺少break语句, 导致执行流程错误地进入下一个case分支。 feat(ast): 为参数声明添加索引字段 在ast_def.h头文件中为参数声明结构体添加param_idx字段, 用于跟踪参数在函数参数列表中的位置索引。 feat(ast): 更新参数初始化函数以支持索引参数 修改scc_ast.h中的scc_ast_decl_param_init函数签名, 添加参数索引idx参数,并将该值存储到参数声明结构体中。 feat(ast2ir): 添加IR转换上下文的值使用提示选项 在ast2ir.h中为scc_ast2ir_ctx_t结构体添加hint_using_value字段, 控制参数转换时是使用值还是分配内存的方式。 fix(ast2ir): 正确处理void类型到IR的转换 当遇到大小为0的类型(如void)时,直接返回void类型, 而不是尝试匹配其他大小分支。 refactor(ast2ir): 统一基本块引用类型为value_ref 将逻辑表达式、条件语句、循环语句中的基本块引用类型 从bblock_ref_t改为value_ref_t,保持类型一致性。 fix(ast2ir): 修正函数引用空值检查 使用SCC_IR_REF_nullptr常量替代0进行函数引用的空值检查, 提高代码的可读性和正确性。 refactor(ast2ir): 简化参数处理逻辑 移除不必要的函数参数获取和命名设置逻辑, 通过递归调用scc_ast2ir_decl来处理参数声明。 feat(ast2ir): 实现参数声明到IR的转换 为参数声明添加完整的IR转换逻辑,包括类型转换、 参数引用创建和内存分配处理。 refactor(ast2ir): 更新哈希表初始化接口 适配新的哈希表初始化函数签名,添加userdata参数支持, 并初始化hint_using_value字段为false。 refactor(ir): 移除函数参数的预分配逻辑 删除IR构建器中函数参数的预分配和循环添加逻辑, 简化函数开始构建的处理流程。 refactor(ir): 更新类型哈希表键值处理 修改类型哈希表的哈希和比较函数以接受模块参数, 正确处理空引用情况并支持新的键值传递方式。 fix(ir): 修复IR转储中的字符串格式 移除IR函数转储时多余的换行符,确保输出格式正确。 refactor(ir): 更新模块哈希表初始化 适配哈希表初始化接口变更,添加userdata参数, 并为各种向量预留UID 0作为无效引用。 fix(ir): 修复模块清理中的循环起始索引 将模块清理循环的起始索引从0改为1,跳过预留的 无效引用项,避免访问空指针。 refactor(ir): 调整向量和哈希表操作顺序 调整模块中向量push和哈希表set的操作顺序, 确保数据一致性和正确的UID分配。 chore(build): 移除ir2mcode模块相关文件 移除ir2mcode相关的头文件和源文件,这些组件 将在后续重构中重新设计或替换。
603 lines
24 KiB
C
603 lines
24 KiB
C
#ifndef __SCC_AST_H__
|
||
#define __SCC_AST_H__
|
||
|
||
#include "ast_def.h"
|
||
#include "ast_dump.h"
|
||
|
||
// decls can be nullptr but maybe warning
|
||
static inline void
|
||
scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit,
|
||
scc_ast_decl_vec_t *decls, scc_pos_t loc) {
|
||
Assert(translation_unit != nullptr);
|
||
translation_unit->base.type = SCC_AST_TRANSLATION_UNIT;
|
||
translation_unit->base.loc = loc;
|
||
if (decls == nullptr) {
|
||
scc_vec_init(translation_unit->declarations);
|
||
} else {
|
||
translation_unit->declarations = *decls;
|
||
scc_vec_init(*decls);
|
||
}
|
||
}
|
||
|
||
static inline void scc_ast_decl_list_init(scc_ast_decl_t *decl,
|
||
scc_ast_decl_vec_t *list_move,
|
||
scc_pos_t loc) {
|
||
Assert(decl != nullptr && list_move != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = SCC_AST_DECL_LIST;
|
||
decl->name = nullptr;
|
||
decl->list.vars = *list_move;
|
||
scc_vec_init(*list_move);
|
||
}
|
||
|
||
// name and var_init can be nullptr
|
||
static inline void scc_ast_decl_unsafe_val_init(scc_ast_decl_t *decl,
|
||
scc_ast_type_t *type,
|
||
const char *name,
|
||
scc_ast_expr_t *var_init,
|
||
scc_pos_t loc) {
|
||
Assert(decl != nullptr && type != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = SCC_AST_DECL_VAR;
|
||
decl->name = name;
|
||
decl->var.type = type;
|
||
decl->var.init = var_init;
|
||
}
|
||
|
||
// var_init can be nullptr
|
||
static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl,
|
||
scc_ast_type_t *type, const char *name,
|
||
scc_ast_expr_t *var_init,
|
||
scc_pos_t loc) {
|
||
Assert(decl != nullptr && name != nullptr && type != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = SCC_AST_DECL_VAR;
|
||
decl->name = name;
|
||
decl->var.type = type;
|
||
decl->var.init = var_init;
|
||
}
|
||
|
||
// body can be nullptr
|
||
static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl,
|
||
scc_ast_type_t *type,
|
||
const char *name,
|
||
scc_ast_stmt_t *body, scc_pos_t loc) {
|
||
Assert(decl != nullptr && name != nullptr && type != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = SCC_AST_DECL_FUNC;
|
||
decl->name = name;
|
||
decl->func.type = type;
|
||
Assert(type->base.type == SCC_AST_TYPE_FUNCTION);
|
||
decl->func.body = body;
|
||
}
|
||
|
||
// name can be nullptr
|
||
static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl,
|
||
scc_ast_type_t *type,
|
||
const char *name, int idx,
|
||
scc_pos_t loc) {
|
||
Assert(decl != nullptr && type != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = SCC_AST_DECL_PARAM;
|
||
decl->name = name;
|
||
decl->param.type = type;
|
||
decl->param.param_idx = idx;
|
||
}
|
||
|
||
static inline void _scc_ast_decl_record_init(scc_ast_decl_t *decl,
|
||
scc_ast_node_kind_t type,
|
||
const char *name,
|
||
scc_ast_decl_vec_t *fields_move,
|
||
scc_pos_t loc) {
|
||
Assert(decl != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = type;
|
||
decl->name = name;
|
||
if (fields_move == nullptr) {
|
||
scc_vec_init(decl->record.fields);
|
||
} else {
|
||
decl->record.fields = *fields_move;
|
||
scc_vec_init(*fields_move);
|
||
}
|
||
}
|
||
|
||
// name and fields can be nullptr
|
||
static inline void scc_ast_decl_struct_init(scc_ast_decl_t *decl,
|
||
const char *name,
|
||
scc_ast_decl_vec_t *fields_move,
|
||
scc_pos_t loc) {
|
||
_scc_ast_decl_record_init(decl, SCC_AST_DECL_STRUCT, name, fields_move,
|
||
loc);
|
||
}
|
||
|
||
// name and fields can be nullptr
|
||
static inline void scc_ast_decl_union_init(scc_ast_decl_t *decl,
|
||
const char *name,
|
||
scc_ast_decl_vec_t *fields_move,
|
||
scc_pos_t loc) {
|
||
_scc_ast_decl_record_init(decl, SCC_AST_DECL_UNION, name, fields_move, loc);
|
||
}
|
||
|
||
// name and fields can be nullptr
|
||
static inline void scc_ast_decl_enum_init(scc_ast_decl_t *decl,
|
||
const char *name,
|
||
scc_ast_decl_vec_t *fields_move,
|
||
scc_pos_t loc) {
|
||
_scc_ast_decl_record_init(decl, SCC_AST_DECL_ENUM, name, fields_move, loc);
|
||
}
|
||
|
||
static inline void scc_ast_decl_typedef_init(scc_ast_decl_t *decl,
|
||
const char *name,
|
||
scc_ast_type_t *type,
|
||
scc_pos_t loc) {
|
||
Assert(decl != nullptr && name != nullptr && type != nullptr);
|
||
decl->base.loc = loc;
|
||
decl->base.type = SCC_AST_DECL_TYPEDEF;
|
||
decl->name = name;
|
||
decl->typedef_decl.type = type;
|
||
}
|
||
|
||
// items can be nullptr
|
||
static inline void scc_ast_stmt_compound_init(
|
||
scc_ast_stmt_t *stmt, scc_ast_block_item_vec_t *items_move, scc_pos_t loc) {
|
||
Assert(stmt != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_COMPOUND;
|
||
if (items_move == nullptr) {
|
||
scc_vec_init(stmt->compound.block_items);
|
||
} else {
|
||
stmt->compound.block_items = *items_move;
|
||
scc_vec_init(*items_move);
|
||
}
|
||
}
|
||
|
||
// expr can be nullptr
|
||
static inline void scc_ast_stmt_expr_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *expr, scc_pos_t loc) {
|
||
Assert(stmt != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_EXPR;
|
||
stmt->expr.expr = expr;
|
||
}
|
||
|
||
// opt_else can be nullptr
|
||
static inline void scc_ast_stmt_if_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_stmt_t *then,
|
||
scc_ast_stmt_t *opt_else,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr && cond != nullptr && then != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_IF;
|
||
stmt->if_stmt.cond = cond;
|
||
stmt->if_stmt.then_stmt = then;
|
||
stmt->if_stmt.opt_else_stmt = opt_else;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_while_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_stmt_t *body,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr && cond != nullptr && body != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_WHILE;
|
||
stmt->while_stmt.cond = cond;
|
||
stmt->while_stmt.body = body;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_do_while_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_stmt_t *body,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr && cond != nullptr && body != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_DO_WHILE;
|
||
stmt->while_stmt.cond = cond;
|
||
stmt->while_stmt.body = body;
|
||
}
|
||
|
||
// FIXME
|
||
static inline void scc_ast_stmt_for_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_node_t *init,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_expr_t *incr,
|
||
scc_ast_stmt_t *body, scc_pos_t loc) {
|
||
Assert(stmt != nullptr && body != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_FOR;
|
||
stmt->for_stmt.init = init;
|
||
stmt->for_stmt.cond = cond;
|
||
stmt->for_stmt.incr = incr;
|
||
stmt->for_stmt.body = body;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_switch_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_stmt_t *body,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr && cond != nullptr && body != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_SWITCH;
|
||
stmt->switch_stmt.cond = cond;
|
||
stmt->switch_stmt.body = body;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_case_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_stmt_t *body, scc_pos_t loc) {
|
||
Assert(stmt != nullptr && cond != nullptr && body != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_CASE;
|
||
stmt->case_stmt.expr = cond;
|
||
stmt->case_stmt.stmt = body;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_default_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_stmt_t *body,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr && body != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_DEFAULT;
|
||
stmt->default_stmt.stmt = body;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_BREAK;
|
||
stmt->jump._target = nullptr;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_continue_init(scc_ast_stmt_t *stmt,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_CONTINUE;
|
||
stmt->jump._target = nullptr;
|
||
}
|
||
|
||
// expr can be nullptr
|
||
static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt,
|
||
scc_ast_expr_t *expr,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_RETURN;
|
||
stmt->return_stmt.expr = expr;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_goto_init(scc_ast_stmt_t *stmt,
|
||
const char *label, scc_pos_t loc) {
|
||
Assert(stmt != nullptr && label != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_GOTO;
|
||
stmt->goto_stmt.label = label;
|
||
stmt->goto_stmt._target = nullptr;
|
||
}
|
||
|
||
static inline void scc_ast_stmt_label_init(scc_ast_stmt_t *stmt,
|
||
const char *label,
|
||
scc_ast_stmt_t *body,
|
||
scc_pos_t loc) {
|
||
Assert(stmt != nullptr);
|
||
stmt->base.loc = loc;
|
||
stmt->base.type = SCC_AST_STMT_LABEL;
|
||
stmt->label_stmt.label = label;
|
||
stmt->label_stmt.stmt = body;
|
||
}
|
||
|
||
static inline void scc_ast_expr_binary_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_op_t op,
|
||
scc_ast_expr_t *lhs,
|
||
scc_ast_expr_t *rhs,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && lhs != nullptr && rhs != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_BINARY;
|
||
expr->binary.op = op;
|
||
expr->binary.lhs = lhs;
|
||
expr->binary.rhs = rhs;
|
||
}
|
||
|
||
static inline void scc_ast_expr_unary_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_op_t op,
|
||
scc_ast_expr_t *operand,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && operand != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_UNARY;
|
||
expr->unary.op = op;
|
||
expr->unary.operand = operand;
|
||
}
|
||
|
||
static inline void scc_ast_expr_cond_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_t *cond,
|
||
scc_ast_expr_t *then_expr,
|
||
scc_ast_expr_t *else_expr,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && cond != nullptr && then_expr != nullptr &&
|
||
else_expr != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_COND;
|
||
expr->cond.cond = cond;
|
||
expr->cond.then_expr = then_expr;
|
||
expr->cond.else_expr = else_expr;
|
||
}
|
||
|
||
// args can be nullptr
|
||
static inline void scc_ast_expr_call_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_t *callee,
|
||
scc_ast_expr_vec_t *args,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && callee != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_CALL;
|
||
expr->call.callee = callee;
|
||
if (args == nullptr) {
|
||
scc_vec_init(expr->call.args);
|
||
} else {
|
||
expr->call.args = *args;
|
||
}
|
||
}
|
||
|
||
// SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标
|
||
static inline void scc_ast_expr_array_subscript_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_t *array,
|
||
scc_ast_expr_t *index,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && array != nullptr && index != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_ARRAY_SUBSCRIPT;
|
||
expr->subscript.array = array;
|
||
expr->subscript.index = index;
|
||
}
|
||
|
||
static inline void _scc_ast_expr_member_init(scc_ast_expr_t *expr,
|
||
scc_ast_node_kind_t type,
|
||
scc_ast_expr_t *object,
|
||
const char *member,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && object != nullptr && member != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = type;
|
||
expr->member.base = object;
|
||
expr->member.name = member;
|
||
expr->member._target_idx = 0;
|
||
}
|
||
|
||
static inline void scc_ast_expr_member_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_t *object,
|
||
const char *member, scc_pos_t loc) {
|
||
_scc_ast_expr_member_init(expr, SCC_AST_EXPR_MEMBER, object, member, loc);
|
||
}
|
||
|
||
static inline void scc_ast_expr_ptr_member_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_t *object,
|
||
const char *member,
|
||
scc_pos_t loc) {
|
||
_scc_ast_expr_member_init(expr, SCC_AST_EXPR_PTR_MEMBER, object, member,
|
||
loc);
|
||
}
|
||
|
||
static inline void scc_ast_expr_cast_init(scc_ast_expr_t *expr,
|
||
scc_ast_type_t *type,
|
||
scc_ast_expr_t *operand,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && type != nullptr && operand != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_CAST;
|
||
expr->cast.type = type;
|
||
expr->cast.expr = operand;
|
||
}
|
||
|
||
// type and target_expr can be nullptr but it only one of them can be nullptr
|
||
static inline void scc_ast_expr_sizeof_init(scc_ast_expr_t *expr,
|
||
scc_ast_type_t *type,
|
||
scc_ast_expr_t *target_expr,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_SIZE_OF;
|
||
expr->attr_of.type = type;
|
||
expr->attr_of.expr = target_expr;
|
||
}
|
||
|
||
// type and target_expr can be nullptr but it only one of them can be nullptr
|
||
static inline void scc_ast_expr_alignof_init(scc_ast_expr_t *expr,
|
||
scc_ast_type_t *type,
|
||
scc_ast_expr_t *target_expr,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type =
|
||
SCC_AST_EXPR_SIZE_OF; // 注意:这里使用了 SIZE_OF,可能需要改为 ALIGN_OF
|
||
expr->attr_of.type = type;
|
||
expr->attr_of.expr = target_expr;
|
||
}
|
||
|
||
// lhs_exprs and rhs_exprs can be nullptr
|
||
static inline void scc_ast_expr_compound_init(scc_ast_expr_t *expr,
|
||
scc_ast_expr_t *base,
|
||
scc_ast_expr_vec_t *lhs_exprs,
|
||
scc_ast_expr_vec_t *rhs_exprs,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && base != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_COMPOUND;
|
||
expr->compound.base = base;
|
||
|
||
if (lhs_exprs == nullptr) {
|
||
scc_vec_init(expr->compound.lhs_exprs);
|
||
} else {
|
||
expr->compound.lhs_exprs = *lhs_exprs;
|
||
scc_vec_init(*lhs_exprs);
|
||
}
|
||
|
||
if (rhs_exprs == nullptr) {
|
||
scc_vec_init(expr->compound.rhs_exprs);
|
||
} else {
|
||
expr->compound.rhs_exprs = *rhs_exprs;
|
||
scc_vec_init(*rhs_exprs);
|
||
}
|
||
}
|
||
|
||
static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr,
|
||
scc_ast_node_kind_t type,
|
||
const char *value, cbool owned,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && value != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = type;
|
||
expr->literal.lexme = value;
|
||
expr->literal.owned = owned;
|
||
}
|
||
|
||
static inline void scc_ast_expr_literal_int_init(scc_ast_expr_t *expr,
|
||
const char *value, cbool owned,
|
||
scc_pos_t loc) {
|
||
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_INT_LITERAL, value, owned,
|
||
loc);
|
||
}
|
||
|
||
static inline void scc_ast_expr_literal_float_init(scc_ast_expr_t *expr,
|
||
const char *value,
|
||
cbool owned, scc_pos_t loc) {
|
||
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_FLOAT_LITERAL, value, owned,
|
||
loc);
|
||
}
|
||
static inline void scc_ast_expr_literal_char_init(scc_ast_expr_t *expr,
|
||
const char *value,
|
||
cbool owned, scc_pos_t loc) {
|
||
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_CHAR_LITERAL, value, owned,
|
||
loc);
|
||
}
|
||
static inline void scc_ast_expr_literal_string_init(scc_ast_expr_t *expr,
|
||
const char *value,
|
||
cbool owned,
|
||
scc_pos_t loc) {
|
||
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_STRING_LITERAL, value, owned,
|
||
loc);
|
||
}
|
||
|
||
static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr,
|
||
const char *name,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && name != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_IDENTIFIER;
|
||
expr->identifier.name = name;
|
||
expr->identifier._target = nullptr;
|
||
}
|
||
|
||
static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr,
|
||
scc_ast_type_t *type,
|
||
scc_pos_t loc) {
|
||
Assert(expr != nullptr && type != nullptr);
|
||
expr->base.loc = loc;
|
||
expr->base.type = SCC_AST_EXPR_LVALUE;
|
||
expr->lvalue.type = type;
|
||
}
|
||
|
||
// have defined builtin type
|
||
static inline void scc_ast_type_builtin_init(scc_ast_type_t *type,
|
||
scc_ast_builtin_type_t builtin,
|
||
scc_pos_t loc) {
|
||
Assert(type != nullptr);
|
||
type->base.loc = loc;
|
||
type->base.type = SCC_AST_TYPE_BUILTIN;
|
||
type->builtin.type = builtin;
|
||
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
||
}
|
||
|
||
static inline void scc_ast_type_pointer_init(scc_ast_type_t *type,
|
||
scc_ast_type_t *pointee,
|
||
scc_pos_t loc) {
|
||
Assert(type != nullptr && pointee != nullptr);
|
||
type->base.loc = loc;
|
||
type->base.type = SCC_AST_TYPE_POINTER;
|
||
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
||
type->pointer.pointee = pointee;
|
||
}
|
||
|
||
// size can be nullptr
|
||
static inline void scc_ast_type_array_init(scc_ast_type_t *type,
|
||
scc_ast_type_t *element,
|
||
scc_ast_expr_t *size,
|
||
scc_pos_t loc) {
|
||
Assert(type != nullptr && element != nullptr);
|
||
type->base.loc = loc;
|
||
type->base.type = SCC_AST_TYPE_ARRAY;
|
||
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
||
type->array.element = element;
|
||
type->array.size = size;
|
||
}
|
||
|
||
// return_type and params can be nullptr
|
||
static inline void scc_ast_type_function_init(scc_ast_type_t *type,
|
||
scc_ast_type_t *return_type,
|
||
scc_ast_decl_vec_t *params,
|
||
scc_pos_t loc) {
|
||
Assert(type != nullptr);
|
||
type->base.loc = loc;
|
||
type->base.type = SCC_AST_TYPE_FUNCTION;
|
||
type->function.return_type = return_type;
|
||
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
||
if (params == nullptr) {
|
||
scc_vec_init(type->function.params);
|
||
} else {
|
||
type->function.params = *params;
|
||
scc_vec_init(*params);
|
||
}
|
||
}
|
||
|
||
static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
|
||
scc_ast_node_kind_t type_kind,
|
||
const char *name,
|
||
scc_ast_decl_t *decl,
|
||
scc_pos_t loc) {
|
||
Assert(type != nullptr);
|
||
type->base.loc = loc;
|
||
type->base.type = type_kind;
|
||
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
||
type->record.name = name;
|
||
type->record.decl = decl;
|
||
}
|
||
|
||
// name and decl can be nullptr
|
||
static inline void scc_ast_type_struct_init(scc_ast_type_t *type,
|
||
const char *name,
|
||
scc_ast_decl_t *decl,
|
||
scc_pos_t loc) {
|
||
_scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, decl, loc);
|
||
}
|
||
|
||
// name and decl can be nullptr
|
||
static inline void scc_ast_type_union_init(scc_ast_type_t *type,
|
||
const char *name,
|
||
scc_ast_decl_t *decl,
|
||
scc_pos_t loc) {
|
||
_scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, decl, loc);
|
||
}
|
||
|
||
// name and decl can be nullptr
|
||
static inline void scc_ast_type_enum_init(scc_ast_type_t *type,
|
||
const char *name,
|
||
scc_ast_decl_t *decl, scc_pos_t loc) {
|
||
_scc_ast_type_record_init(type, SCC_AST_TYPE_ENUM, name, decl, loc);
|
||
}
|
||
|
||
static inline void scc_ast_type_typedef_init(scc_ast_type_t *type,
|
||
const char *name,
|
||
scc_ast_decl_t *target,
|
||
scc_pos_t loc) {
|
||
Assert(type != nullptr && target != nullptr);
|
||
type->base.loc = loc;
|
||
type->base.type = SCC_AST_TYPE_TYPEDEF;
|
||
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
||
type->typedef_type.name = name;
|
||
type->typedef_type.decl = target;
|
||
}
|
||
|
||
#endif /* __SCC_AST_H__ */
|