- 添加 SCC_AST_DECL_LIST 节点类型用于表示声明列表 - 实现 scc_ast_decl_list_init 函数来初始化声明列表节点 - 重构 scc_parse_declaration 函数以支持逗号分隔的多个变量声明 - 分离类型说明符解析到独立的 scc_parse_declaration_specifiers 函数 - 支持 typedef 和多变量声明如 'int a, b;' 和 'int a = 1, b = 2;' - 在 ast_dump 中添加对声明列表节点的打印支持 refactor(ast): 统一使用 scc_vec_foreach 宏替换手动循环 - 将 ast_dump.c 中的多个手动索引循环改为使用 scc_vec_foreach - 提高代码可读性和安全性 - 避免索引越界错误 fix(parser): 修复语义分析中结构体符号表冲突 - 为结构体、联合体和枚举符号名添加前缀避免命名冲突 - 使用 '$S_'、'$U_'、'$E_' 前缀分别标识结构体、联合体和枚举 refactor(log): 统一终止处理方式 - 将 log_exit 替换为 log_abort 以更准确反映行为 - 更新相关依赖模块的实现 style(parser): 移除未使用的参数和清理代码 - 在 argparse.c 中添加 (void) 参数注释处理未使用的参数 - 清理 parse_expr.c 中未使用的函数声明 - 优化 parse_type.c 中的错误处理流程
571 lines
21 KiB
C
571 lines
21 KiB
C
#ifndef __SCC_AST_H__
|
|
#define __SCC_AST_H__
|
|
|
|
#include "ast_builtin.h"
|
|
#include "ast_def.h"
|
|
#include "ast_dump.h"
|
|
|
|
// decls can be null but maybe warning
|
|
static inline void
|
|
scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit,
|
|
scc_ast_decl_vec_t *decls) {
|
|
Assert(translation_unit != null);
|
|
translation_unit->base.type = SCC_AST_TRANSLATION_UNIT;
|
|
translation_unit->base.loc = scc_pos_create();
|
|
if (decls == null) {
|
|
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) {
|
|
Assert(decl != null && list_move != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_LIST;
|
|
decl->name = null;
|
|
decl->list.vars = *list_move;
|
|
scc_vec_init(*list_move);
|
|
}
|
|
|
|
// name and var_init can be null
|
|
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) {
|
|
Assert(decl != null && type != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_VAR;
|
|
decl->name = name;
|
|
decl->var.type = type;
|
|
decl->var.init = var_init;
|
|
}
|
|
|
|
// var_init can be null
|
|
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) {
|
|
Assert(decl != null && name != null && type != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_VAR;
|
|
decl->name = name;
|
|
decl->var.type = type;
|
|
decl->var.init = var_init;
|
|
}
|
|
|
|
// body can be null
|
|
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) {
|
|
Assert(decl != null && name != null && type != null);
|
|
decl->base.loc = scc_pos_create();
|
|
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 null
|
|
static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl,
|
|
scc_ast_type_t *type,
|
|
const char *name) {
|
|
Assert(decl != null && type != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_PARAM;
|
|
decl->name = name;
|
|
decl->param.type = type;
|
|
}
|
|
|
|
// name and fields can be null
|
|
static inline void scc_ast_decl_struct_init(scc_ast_decl_t *decl,
|
|
const char *name,
|
|
scc_ast_decl_vec_t *fields_move) {
|
|
Assert(decl != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_STRUCT;
|
|
decl->name = name;
|
|
if (fields_move == null) {
|
|
scc_vec_init(decl->record.fields);
|
|
} else {
|
|
decl->record.fields = *fields_move;
|
|
scc_vec_init(*fields_move);
|
|
}
|
|
}
|
|
|
|
// name and fields can be null
|
|
static inline void scc_ast_decl_union_init(scc_ast_decl_t *decl,
|
|
const char *name,
|
|
scc_ast_decl_vec_t *fields_move) {
|
|
Assert(decl != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_UNION;
|
|
decl->name = name;
|
|
if (fields_move == null) {
|
|
scc_vec_init(decl->record.fields);
|
|
} else {
|
|
decl->record.fields = *fields_move;
|
|
scc_vec_init(*fields_move);
|
|
}
|
|
}
|
|
|
|
// name and fields can be null
|
|
static inline void scc_ast_decl_enum_init(scc_ast_decl_t *decl,
|
|
const char *name,
|
|
scc_ast_expr_vec_t *fields_move) {
|
|
Assert(decl != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_ENUM;
|
|
decl->name = name;
|
|
if (fields_move == null) {
|
|
scc_vec_init(decl->enumeration.enumerators);
|
|
} else {
|
|
decl->enumeration.enumerators = *fields_move;
|
|
scc_vec_init(*fields_move);
|
|
}
|
|
}
|
|
|
|
static inline void scc_ast_decl_typedef_init(scc_ast_decl_t *decl,
|
|
const char *name,
|
|
scc_ast_type_t *type) {
|
|
Assert(decl != null && name != null && type != null);
|
|
decl->base.loc = scc_pos_create();
|
|
decl->base.type = SCC_AST_DECL_TYPEDEF;
|
|
decl->name = name;
|
|
decl->typedef_decl.type = type;
|
|
}
|
|
|
|
// items can be null
|
|
static inline void
|
|
scc_ast_stmt_compound_init(scc_ast_stmt_t *stmt,
|
|
scc_ast_block_item_vec_t *items_move) {
|
|
Assert(stmt != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
stmt->base.type = SCC_AST_STMT_COMPOUND;
|
|
if (items_move == null) {
|
|
scc_vec_init(stmt->compound.block_items);
|
|
} else {
|
|
stmt->compound.block_items = *items_move;
|
|
scc_vec_init(*items_move);
|
|
}
|
|
}
|
|
|
|
// expr can be null
|
|
static inline void scc_ast_stmt_expr_init(scc_ast_stmt_t *stmt,
|
|
scc_ast_expr_t *expr) {
|
|
Assert(stmt != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
stmt->base.type = SCC_AST_STMT_EXPR;
|
|
stmt->expr.expr = expr;
|
|
}
|
|
|
|
// opt_else can be null
|
|
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) {
|
|
Assert(stmt != null && cond != null && then != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null && cond != null && body != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null && cond != null && body != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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_type_t *init,
|
|
scc_ast_expr_t *cond,
|
|
scc_ast_expr_t *incr,
|
|
scc_ast_stmt_t *body) {
|
|
Assert(stmt != null && body != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null && cond != null && body != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null && cond != null && body != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null && body != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
stmt->base.type = SCC_AST_STMT_BREAK;
|
|
}
|
|
|
|
static inline void scc_ast_stmt_continue_init(scc_ast_stmt_t *stmt) {
|
|
Assert(stmt != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
stmt->base.type = SCC_AST_STMT_CONTINUE;
|
|
}
|
|
|
|
// expr can be null
|
|
static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt,
|
|
scc_ast_expr_t *expr) {
|
|
Assert(stmt != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(stmt != null && label != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
stmt->base.type = SCC_AST_STMT_GOTO;
|
|
stmt->goto_stmt.label = label;
|
|
stmt->goto_stmt._target = null;
|
|
}
|
|
|
|
static inline void scc_ast_stmt_label_init(scc_ast_stmt_t *stmt,
|
|
const char *label,
|
|
scc_ast_stmt_t *body) {
|
|
Assert(stmt != null);
|
|
stmt->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(expr != null && lhs != null && rhs != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(expr != null && operand != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(expr != null && cond != null && then_expr != null &&
|
|
else_expr != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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 null
|
|
static inline void scc_ast_expr_call_init(scc_ast_expr_t *expr,
|
|
scc_ast_expr_t *callee,
|
|
scc_ast_expr_vec_t *args) {
|
|
Assert(expr != null && callee != null);
|
|
expr->base.loc = scc_pos_create();
|
|
expr->base.type = SCC_AST_EXPR_CALL;
|
|
expr->call.callee = callee;
|
|
expr->call._target = null;
|
|
if (args == null) {
|
|
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) {
|
|
Assert(expr != null && array != null && index != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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_type_t type,
|
|
scc_ast_expr_t *object,
|
|
const char *member) {
|
|
Assert(expr != null && object != null && member != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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_ast_expr_member_init(expr, SCC_AST_EXPR_MEMBER, object, member);
|
|
}
|
|
|
|
static inline void scc_ast_expr_ptr_member_init(scc_ast_expr_t *expr,
|
|
scc_ast_expr_t *object,
|
|
const char *member) {
|
|
_scc_ast_expr_member_init(expr, SCC_AST_EXPR_PTR_MEMBER, object, member);
|
|
}
|
|
|
|
static inline void scc_ast_expr_cast_init(scc_ast_expr_t *expr,
|
|
scc_ast_type_t *type,
|
|
scc_ast_expr_t *operand) {
|
|
Assert(expr != null && type != null && operand != null);
|
|
expr->base.loc = scc_pos_create();
|
|
expr->base.type = SCC_AST_EXPR_CAST;
|
|
expr->cast.type = type;
|
|
expr->cast.expr = operand;
|
|
}
|
|
|
|
// type and target_expr can be null but it only one of them can be null
|
|
static inline void scc_ast_expr_sizeof_init(scc_ast_expr_t *expr,
|
|
scc_ast_type_t *type,
|
|
scc_ast_expr_t *target_expr) {
|
|
Assert(expr != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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 null but it only one of them can be null
|
|
static inline void scc_ast_expr_alignof_init(scc_ast_expr_t *expr,
|
|
scc_ast_type_t *type,
|
|
scc_ast_expr_t *target_expr) {
|
|
Assert(expr != null);
|
|
expr->base.loc = scc_pos_create();
|
|
expr->base.type = SCC_AST_EXPR_SIZE_OF;
|
|
expr->attr_of.type = type;
|
|
expr->attr_of.expr = target_expr;
|
|
}
|
|
|
|
// lhs_exprs and rhs_exprs can be null
|
|
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) {
|
|
Assert(expr != null && base != null);
|
|
expr->base.loc = scc_pos_create();
|
|
expr->base.type = SCC_AST_EXPR_COMPOUND;
|
|
expr->compound.base = base;
|
|
|
|
if (lhs_exprs == null) {
|
|
scc_vec_init(expr->compound.lhs_exprs);
|
|
} else {
|
|
expr->compound.lhs_exprs = *lhs_exprs;
|
|
scc_vec_init(*lhs_exprs);
|
|
}
|
|
|
|
if (rhs_exprs == null) {
|
|
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_type_t type,
|
|
const char *value, cbool owned) {
|
|
Assert(expr != null && value != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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_ast_expr_literal_init(expr, SCC_AST_EXPR_INT_LITERAL, value, owned);
|
|
}
|
|
|
|
static inline void scc_ast_expr_literal_float_init(scc_ast_expr_t *expr,
|
|
const char *value,
|
|
cbool owned) {
|
|
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_FLOAT_LITERAL, value, owned);
|
|
}
|
|
static inline void scc_ast_expr_literal_char_init(scc_ast_expr_t *expr,
|
|
const char *value,
|
|
cbool owned) {
|
|
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_CHAR_LITERAL, value, owned);
|
|
}
|
|
static inline void scc_ast_expr_literal_string_init(scc_ast_expr_t *expr,
|
|
const char *value,
|
|
cbool owned) {
|
|
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_STRING_LITERAL, value, owned);
|
|
}
|
|
|
|
static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr,
|
|
const char *name) {
|
|
Assert(expr != null && name != null);
|
|
expr->base.loc = scc_pos_create();
|
|
expr->base.type = SCC_AST_EXPR_IDENTIFIER;
|
|
expr->identifier.name = name;
|
|
expr->identifier._target = null;
|
|
}
|
|
|
|
static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr,
|
|
scc_ast_type_t *type) {
|
|
Assert(expr != null && type != null);
|
|
expr->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(type != null);
|
|
type->base.loc = scc_pos_create();
|
|
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) {
|
|
Assert(type != null && pointee != null);
|
|
type->base.loc = scc_pos_create();
|
|
type->base.type = SCC_AST_TYPE_POINTER;
|
|
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
|
type->pointer.pointee = pointee;
|
|
}
|
|
|
|
// size can be null
|
|
static inline void scc_ast_type_array_init(scc_ast_type_t *type,
|
|
scc_ast_type_t *element,
|
|
scc_ast_expr_t *size) {
|
|
Assert(type != null && element != null);
|
|
type->base.loc = scc_pos_create();
|
|
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 null
|
|
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) {
|
|
Assert(type != null);
|
|
type->base.loc = scc_pos_create();
|
|
type->base.type = SCC_AST_TYPE_FUNCTION;
|
|
type->function.return_type = return_type;
|
|
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
|
if (params == null) {
|
|
scc_vec_init(type->function.param_types);
|
|
} else {
|
|
type->function.param_types = *params;
|
|
scc_vec_init(*params);
|
|
}
|
|
}
|
|
|
|
static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
|
|
scc_ast_node_type_t type_kind,
|
|
const char *name,
|
|
scc_ast_decl_t *decl) {
|
|
Assert(type != null);
|
|
type->base.loc = scc_pos_create();
|
|
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 null
|
|
static inline void scc_ast_type_struct_init(scc_ast_type_t *type,
|
|
const char *name,
|
|
scc_ast_decl_t *decl) {
|
|
_scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, decl);
|
|
}
|
|
|
|
// name and decl can be null
|
|
static inline void scc_ast_type_union_init(scc_ast_type_t *type,
|
|
const char *name,
|
|
scc_ast_decl_t *decl) {
|
|
_scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, decl);
|
|
}
|
|
|
|
// name and decl can be null
|
|
static inline void scc_ast_type_enum_init(scc_ast_type_t *type,
|
|
const char *name,
|
|
scc_ast_decl_t *decl) {
|
|
Assert(type != null);
|
|
type->base.loc = scc_pos_create();
|
|
type->base.type = SCC_AST_TYPE_ENUM;
|
|
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
|
|
type->enumeration.name = name;
|
|
type->enumeration.decl = decl;
|
|
}
|
|
|
|
static inline void scc_ast_type_typedef_init(scc_ast_type_t *type,
|
|
const char *name,
|
|
scc_ast_decl_t *target) {
|
|
Assert(type != null && target != null);
|
|
type->base.loc = scc_pos_create();
|
|
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__ */
|