Files
scc/libs/parser/tests/test_parse_unit.c
zzy 5a9f816ccf fix(abi): 修复void类型的ABI计算缺少break语句
在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相关的头文件和源文件,这些组件
将在后续重构中重新设计或替换。
2026-04-15 14:52:11 +08:00

880 lines
36 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
void init_func(void);
#define TEST_INIT init_func()
#include "parser_test.h"
static scc_ast_type_t int_type;
static scc_ast_type_t char_type;
static scc_ast_type_t void_type;
static scc_ast_type_t pointer_int_type;
static scc_ast_type_t pointer_char_type;
static scc_ast_type_t pointer_void_type;
static scc_ast_type_t pointer_pointer_int_type;
static scc_ast_type_t va_list_type;
void init_func(void) {
scc_ast_type_builtin_init(&int_type, SCC_AST_BUILTIN_TYPE_INT,
scc_pos_create());
scc_ast_type_builtin_init(&char_type, SCC_AST_BUILTIN_TYPE_CHAR,
scc_pos_create());
scc_ast_type_builtin_init(&void_type, SCC_AST_BUILTIN_TYPE_VOID,
scc_pos_create());
scc_ast_type_pointer_init(&pointer_int_type, &int_type, scc_pos_create());
scc_ast_type_pointer_init(&pointer_char_type, &char_type, scc_pos_create());
scc_ast_type_pointer_init(&pointer_void_type, &void_type, scc_pos_create());
scc_ast_type_pointer_init(&pointer_pointer_int_type, &pointer_int_type,
scc_pos_create());
scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST,
scc_pos_create());
}
static void test_parser_unit(void) {
// 1. 变量声明 int a;
{
scc_ast_decl_t int_decl;
scc_ast_decl_val_init(&int_decl, &int_type, "a", nullptr,
scc_pos_create());
SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration);
}
// 2. 函数声明 int main(void) {}
{
// 构造函数类型:返回 int参数为空
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, nullptr, 0,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create());
// 构造复合语句块(空)
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, nullptr, scc_pos_create());
// 构造函数声明
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
scc_pos_create());
SCC_CHECK_AST(&func_decl.base, "int main(void) {}",
scc_parse_declaration);
}
// 3. 翻译单元包含一个函数定义
{
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, nullptr, 0,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create());
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, nullptr, scc_pos_create());
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
scc_pos_create());
// 构造翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls, scc_pos_create());
SCC_CHECK_AST(&tu.base, "int main(void) {}",
scc_parse_translation_unit);
}
// 4. 带返回语句的函数 int main(void) { return 65536; }
{
// 返回语句中的整数常量
scc_ast_expr_t ret_val;
scc_ast_expr_literal_int_init(&ret_val, "65536", false,
scc_pos_create());
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &ret_val, scc_pos_create());
// 复合语句包含该返回语句
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items,
scc_pos_create()); // items 被移动
// 函数类型
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, nullptr, 0,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create());
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
scc_pos_create());
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls, scc_pos_create());
SCC_CHECK_AST(&tu.base, "int main(void) { return 65536; }",
scc_parse_translation_unit);
}
// 5. 多语句函数(复杂示例)
{
// 变量声明 int a;
scc_ast_decl_t a_decl;
scc_ast_decl_val_init(&a_decl, &int_type, "a", nullptr,
scc_pos_create());
// 变量声明 int b;
scc_ast_decl_t b_decl;
scc_ast_decl_val_init(&b_decl, &int_type, "b", nullptr,
scc_pos_create());
// 表达式 1 + 2 * 3
scc_ast_expr_t lit1, lit2, lit3, mul, add;
scc_ast_expr_literal_int_init(&lit1, "1", false, scc_pos_create());
scc_ast_expr_literal_int_init(&lit2, "2", false, scc_pos_create());
scc_ast_expr_literal_int_init(&lit3, "3", false, scc_pos_create());
scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &lit2, &lit3,
scc_pos_create());
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &lit1, &mul,
scc_pos_create());
// 赋值 a = 1 + 2 * 3;
scc_ast_expr_t a_ref1, assign1;
scc_ast_expr_identifier_init(&a_ref1, "a", scc_pos_create());
scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a_ref1, &add,
scc_pos_create());
scc_ast_stmt_t assign1_stmt;
scc_ast_stmt_expr_init(&assign1_stmt, &assign1, scc_pos_create());
// 赋值 b = 7;
scc_ast_expr_t lit7;
scc_ast_expr_literal_int_init(&lit7, "7", false, scc_pos_create());
scc_ast_expr_t b_ref1, assign2;
scc_ast_expr_identifier_init(&b_ref1, "b", scc_pos_create());
scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &b_ref1, &lit7,
scc_pos_create());
scc_ast_stmt_t assign2_stmt;
scc_ast_stmt_expr_init(&assign2_stmt, &assign2, scc_pos_create());
// 表达式 a - b + 1
scc_ast_expr_t a_ref2, b_ref2, sub, add2, lit1_2;
scc_ast_expr_identifier_init(&a_ref2, "a", scc_pos_create());
scc_ast_expr_identifier_init(&b_ref2, "b", scc_pos_create());
scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a_ref2, &b_ref2,
scc_pos_create());
scc_ast_expr_literal_int_init(&lit1_2, "1", false, scc_pos_create());
scc_ast_expr_binary_init(&add2, SCC_AST_OP_ADD, &sub, &lit1_2,
scc_pos_create());
// 赋值 a = a - b + 1;
scc_ast_expr_t a_ref3, assign3;
scc_ast_expr_identifier_init(&a_ref3, "a", scc_pos_create());
scc_ast_expr_binary_init(&assign3, SCC_AST_OP_ASSIGN, &a_ref3, &add2,
scc_pos_create());
scc_ast_stmt_t assign3_stmt;
scc_ast_stmt_expr_init(&assign3_stmt, &assign3, scc_pos_create());
// return a;
scc_ast_expr_t a_ref4;
scc_ast_expr_identifier_init(&a_ref4, "a", scc_pos_create());
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &a_ref4, scc_pos_create());
// 复合语句块,按顺序放入
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&a_decl);
scc_vec_push(items, (scc_ast_node_t *)&b_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign1_stmt);
scc_vec_push(items, (scc_ast_node_t *)&assign2_stmt);
scc_vec_push(items, (scc_ast_node_t *)&assign3_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items, scc_pos_create());
// 函数类型
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type,
nullptr, scc_pos_create());
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
scc_pos_create());
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls, scc_pos_create());
const char *input = "int main() {\n"
" int a;\n"
" int b;\n"
" a = 1 + 2 * 3;\n"
" b = 7;\n"
" a = a - b + 1;\n"
" return a;\n"
"}\n";
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
// 整数字面量 10
scc_ast_expr_t lit10;
scc_ast_expr_literal_int_init(&lit10, "10", false, scc_pos_create());
// 变量声明 int x = 10;
scc_ast_decl_t x_decl;
scc_ast_decl_val_init(&x_decl, (scc_ast_type_t *)&int_type, "x", &lit10,
scc_pos_create());
// 表达式 x + 1
scc_ast_expr_t x_ref1, lit1, add;
scc_ast_expr_identifier_init(&x_ref1, "x", scc_pos_create());
scc_ast_expr_literal_int_init(&lit1, "1", false, scc_pos_create());
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &x_ref1, &lit1,
scc_pos_create());
// 赋值 x = x + 1
scc_ast_expr_t x_ref2, assign;
scc_ast_expr_identifier_init(&x_ref2, "x", scc_pos_create());
scc_ast_expr_binary_init(&assign, SCC_AST_OP_ASSIGN, &x_ref2, &add,
scc_pos_create());
// 表达式语句
scc_ast_stmt_t assign_stmt;
scc_ast_stmt_expr_init(&assign_stmt, &assign, scc_pos_create());
// return x
scc_ast_expr_t x_ref3;
scc_ast_expr_identifier_init(&x_ref3, "x", scc_pos_create());
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &x_ref3, scc_pos_create());
// 复合语句块
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&x_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items, scc_pos_create());
// 函数类型(返回 int无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type,
nullptr,
scc_pos_create()); // nullptr 表示无参数
// 函数声明 int main() { ... }
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
scc_pos_create());
// 翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls, scc_pos_create());
// 输入源代码
const char *input = "int main() {\n"
" int x = 10;\n"
" x = x + 1;\n"
" return x;\n"
"}\n";
// 比较解析结果与期望 AST
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
scc_ast_decl_vec_t params;
scc_ast_decl_t param0;
scc_ast_decl_param_init(&param0, (scc_ast_type_t *)&int_type, "a", 0,
scc_pos_create());
scc_ast_decl_t param1;
scc_ast_decl_param_init(&param1, (scc_ast_type_t *)&int_type, "b", 1,
scc_pos_create());
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, (scc_ast_type_t *)&va_list_type,
nullptr, 2, scc_pos_create());
scc_ast_decl_t *params_array[] = {&param0, &param1, &param2};
scc_vec_unsafe_from_static_array(params, params_array);
scc_ast_type_t decl_func_type;
scc_ast_type_function_init(&decl_func_type, (scc_ast_type_t *)&int_type,
&params, scc_pos_create());
scc_ast_decl_t decl_func;
scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", nullptr,
scc_pos_create());
SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);",
scc_parse_declaration);
}
{
scc_ast_decl_t typedef_decl;
scc_ast_decl_typedef_init(&typedef_decl, "int32_t", &int_type,
scc_pos_create());
scc_ast_type_t typedef_type;
scc_ast_type_typedef_init(&typedef_type, "int32_t", &typedef_decl,
scc_pos_create());
scc_ast_decl_t i32a_decl;
scc_ast_decl_val_init(&i32a_decl, &typedef_type, "a", nullptr,
scc_pos_create());
scc_ast_node_t *array[] = {&typedef_decl.base, &i32a_decl.base};
scc_ast_stmt_t stmt;
scc_ast_block_item_vec_t items;
scc_vec_unsafe_from_static_array(items, array);
scc_ast_stmt_compound_init(&stmt, &items, scc_pos_create());
SCC_CHECK_AST_WITH_SEMA(&stmt.base, "{typedef int int32_t;int32_t a;}",
scc_parse_statement);
scc_ast_type_t void_ptr;
scc_ast_type_pointer_init(&void_ptr, &void_type, scc_pos_create());
scc_ast_decl_t void_ptr_decl;
scc_ast_decl_typedef_init(&void_ptr_decl, "void_ptr", &void_ptr,
scc_pos_create());
scc_ast_type_t void_ptr_type;
scc_ast_type_typedef_init(&void_ptr_type, "void_ptr", &void_ptr_decl,
scc_pos_create());
scc_ast_decl_t void_ptr_a_decl;
scc_ast_decl_val_init(&void_ptr_a_decl, &void_ptr_type, "a", nullptr,
scc_pos_create());
scc_ast_node_t *array2[] = {&void_ptr_decl.base, &void_ptr_a_decl.base};
scc_vec_unsafe_from_static_array(items, array2);
scc_ast_stmt_compound_init(&stmt, &items, scc_pos_create());
SCC_CHECK_AST_WITH_SEMA(&stmt.base,
"{typedef void* void_ptr; void_ptr a;}",
scc_parse_statement);
SCC_CHECK_AST_WITH_SEMA(&void_ptr_decl.base,
"typedef void * void_ptr; ",
scc_parse_declaration);
}
{
// struct { int x; } (匿名结构体定义)
scc_ast_decl_t field;
scc_ast_decl_val_init(&field, (scc_ast_type_t *)&int_type, "x", nullptr,
scc_pos_create());
scc_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, nullptr, &fields,
scc_pos_create());
SCC_CHECK_AST(&struct_def.base, "struct { int x;};",
scc_parse_declaration);
scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, nullptr, &struct_def,
scc_pos_create());
scc_ast_type_t typedef_type;
scc_ast_type_typedef_init(&typedef_type, "struct_t", &struct_def,
scc_pos_create());
scc_ast_decl_t typedef_decl;
scc_ast_decl_typedef_init(&typedef_decl, "struct_t", &struct_type,
scc_pos_create());
SCC_CHECK_AST_WITH_SEMA(&typedef_decl.base,
"typedef struct { int x; } struct_t;",
scc_parse_declaration);
scc_ast_decl_t typedef_impl_decl;
scc_ast_decl_val_init(&typedef_impl_decl, &typedef_type, "a", nullptr,
scc_pos_create());
scc_ast_node_t *array[] = {&typedef_decl.base, &typedef_impl_decl.base};
scc_ast_stmt_t stmt;
scc_ast_block_item_vec_t items;
scc_vec_unsafe_from_static_array(items, array);
scc_ast_stmt_compound_init(&stmt, &items, scc_pos_create());
SCC_CHECK_AST_WITH_SEMA(
&stmt.base, "{typedef struct { int x; } struct_t; struct_t a;}",
scc_parse_statement);
}
{
scc_ast_decl_t type_decl;
scc_ast_decl_typedef_init(&type_decl, "size_t", &int_type,
scc_pos_create());
scc_ast_type_t type_type;
scc_ast_type_typedef_init(&type_type, "size_t", &type_decl,
scc_pos_create());
scc_ast_decl_t param1;
scc_ast_decl_param_init(&param1, &type_type, "a", 0, scc_pos_create());
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &int_type, "b", 1, scc_pos_create());
scc_ast_decl_t param3;
scc_ast_decl_param_init(&param3, &va_list_type, nullptr, 2,
scc_pos_create());
scc_ast_decl_t *params_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_params;
scc_vec_unsafe_from_static_array(func_params, params_array);
scc_ast_type_t func_type;
scc_ast_type_t return_type;
scc_ast_type_pointer_init(&return_type, &void_type, scc_pos_create());
scc_ast_type_function_init(&func_type, &return_type, &func_params,
scc_pos_create());
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "func", nullptr,
scc_pos_create());
scc_ast_decl_t *decls_array[] = {&type_decl, &func_decl};
scc_ast_translation_unit_t tu;
scc_ast_decl_vec_t decls;
scc_vec_unsafe_from_static_array(decls, decls_array);
scc_ast_translation_unit_init(&tu, &decls, scc_pos_create());
SCC_CHECK_AST_WITH_SEMA(&tu.base,
"typedef int size_t;"
"void *func(size_t a, int b, ...);",
scc_parse_translation_unit);
scc_ast_type_t type_func_ptr_type;
scc_ast_type_pointer_init(&type_func_ptr_type, &func_type,
scc_pos_create());
scc_ast_decl_t type_func_ptr_decl;
scc_ast_decl_typedef_init(&type_func_ptr_decl, "func_t",
&type_func_ptr_type, scc_pos_create());
scc_ast_decl_t *decls_array2[] = {&type_decl, &type_func_ptr_decl};
scc_vec_unsafe_from_static_array(decls, decls_array2);
scc_ast_translation_unit_init(&tu, &decls, scc_pos_create());
SCC_CHECK_AST_WITH_SEMA(
&tu.base,
"typedef int size_t;"
"typedef void *(*func_t)(size_t a, int b, ...);",
scc_parse_translation_unit);
}
{
// 1. 构造参数类型volatile const char *restrict并附加 register
// 存储类
scc_ast_type_t char_type;
scc_ast_type_builtin_init(&char_type, SCC_AST_BUILTIN_TYPE_CHAR,
scc_pos_create());
char_type.quals.is_const = true; // const
char_type.quals.is_volatile = true; // volatile
scc_ast_type_t ptr_to_char;
scc_ast_type_pointer_init(&ptr_to_char, &char_type, scc_pos_create());
ptr_to_char.quals.is_restrict = true; // restrict限定指针
ptr_to_char.quals.is_register = true; // register存储类作用于参数
// 2. 参数声明
scc_ast_decl_t param_decl;
scc_ast_decl_param_init(&param_decl, &ptr_to_char, "fmt", 0,
scc_pos_create());
// 3. 返回类型void *
scc_ast_type_t void_type;
scc_ast_type_builtin_init(&void_type, SCC_AST_BUILTIN_TYPE_VOID,
scc_pos_create());
scc_ast_type_t ptr_to_void;
scc_ast_type_pointer_init(&ptr_to_void, &void_type, scc_pos_create());
// 4. 参数列表
scc_ast_decl_vec_t params;
scc_vec_init(params);
scc_vec_push(params, &param_decl);
// 5. 函数类型(包含 static 和 inline
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &ptr_to_void, &params,
scc_pos_create());
func_type.quals.is_static = true;
func_type.quals.is_inline = true;
// 6. 函数声明
scc_ast_decl_t decl;
scc_ast_decl_func_init(&decl, &func_type, "call", nullptr,
scc_pos_create());
// 7. 与解析结果比较
SCC_CHECK_AST_WITH_SEMA(&decl.base,
"static inline void *call(volatile register "
"const char *restrict fmt);",
scc_parse_declaration);
}
{
scc_ast_expr_t lvalue;
scc_ast_expr_lvalue_init(&lvalue, &void_type, scc_pos_create());
scc_ast_expr_t lhs1;
scc_ast_expr_member_init(&lhs1, &lvalue, "data", scc_pos_create());
scc_ast_expr_t lhs2;
scc_ast_expr_member_init(&lhs2, &lvalue, "size", scc_pos_create());
scc_ast_expr_t lhs3;
scc_ast_expr_member_init(&lhs3, &lvalue, "cap", scc_pos_create());
scc_ast_expr_t rl0;
scc_ast_expr_literal_int_init(&rl0, "0", false, scc_pos_create());
scc_ast_type_t void_ptr;
scc_ast_type_pointer_init(&void_ptr, &void_type, scc_pos_create());
scc_ast_expr_t rhs1;
scc_ast_expr_cast_init(&rhs1, &void_ptr, &rl0, scc_pos_create());
scc_ast_expr_t rhs2;
scc_ast_expr_literal_int_init(&rhs2, "0", false, scc_pos_create());
scc_ast_expr_t rhs3;
scc_ast_expr_literal_int_init(&rhs3, "0", false, scc_pos_create());
scc_ast_expr_vec_t lhs_exprs;
scc_ast_expr_t *lhs_array[] = {&lhs1, &lhs2, &lhs3};
scc_vec_unsafe_from_static_array(lhs_exprs, lhs_array);
scc_ast_expr_vec_t rhs_exprs;
scc_ast_expr_t *rhs_array[] = {&rhs1, &rhs2, &rhs3};
scc_vec_unsafe_from_static_array(rhs_exprs, rhs_array);
scc_ast_expr_t expr;
scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs,
scc_pos_create());
// FIXME use real records type
SCC_CHECK_AST(&expr.base,
"(void){.data = ((void *)0), .size = 0, .cap = 0}",
scc_parse_expression);
scc_ast_stmt_t stmt;
scc_ast_stmt_return_init(&stmt, &expr, scc_pos_create());
SCC_CHECK_AST(
&stmt.base,
"return (void){.data = (void *)0, .size = 0, .cap = 0 }; ",
scc_parse_statement);
scc_ast_expr_t lhs4;
scc_ast_expr_t lhs5;
scc_ast_expr_member_init(&lhs4, &lvalue, "a", scc_pos_create());
scc_ast_expr_member_init(&lhs5, &lhs4, "b", scc_pos_create());
scc_ast_expr_t lhs6;
scc_ast_expr_t lhs7;
scc_ast_expr_member_init(&lhs6, &lvalue, "c", scc_pos_create());
scc_ast_expr_array_subscript_init(&lhs7, &lhs6, &rl0, scc_pos_create());
scc_ast_expr_t *lhs_array_hard[] = {&lhs5, &lhs7};
scc_vec_unsafe_from_static_array(lhs_exprs, lhs_array_hard);
scc_ast_expr_t *rhs_array_hard[] = {&rhs2, &rhs3};
scc_vec_unsafe_from_static_array(rhs_exprs, rhs_array_hard);
scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs,
scc_pos_create());
SCC_CHECK_AST(&expr.base, "(void){.a.b = 0, .c[0] = 0}",
scc_parse_expression);
}
{
// 测试 struct S; 仅标记声明
{
scc_ast_decl_t struct_decl;
scc_ast_decl_vec_t empty_members;
scc_vec_init(empty_members);
scc_ast_decl_struct_init(&struct_decl, "S", &empty_members,
scc_pos_create());
SCC_CHECK_AST(&struct_decl.base, "struct S;",
scc_parse_declaration);
}
// 测试 union U; 仅标记声明
{
scc_ast_decl_t union_decl;
scc_ast_decl_vec_t empty_members;
scc_vec_init(empty_members);
scc_ast_decl_union_init(&union_decl, "U", &empty_members,
scc_pos_create());
SCC_CHECK_AST(&union_decl.base, "union U;", scc_parse_declaration);
}
// 测试 enum E; 仅标记声明
{
scc_ast_decl_t enum_decl;
scc_ast_decl_vec_t empty_enumerators;
scc_vec_init(empty_enumerators);
scc_ast_decl_enum_init(&enum_decl, "E", &empty_enumerators,
scc_pos_create());
SCC_CHECK_AST(&enum_decl.base, "enum E;", scc_parse_declaration);
}
}
{
scc_ast_stmt_t continue_stmt;
scc_ast_stmt_continue_init(&continue_stmt, scc_pos_create());
scc_ast_stmt_t stmt;
scc_ast_stmt_label_init(&stmt, "NEXT", &continue_stmt,
scc_pos_create());
SCC_CHECK_AST(&stmt.base, "NEXT: continue;", scc_parse_statement);
}
{
// 测试 int a = *(int*)b;
{
// 构造类型 int*
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_int, (scc_ast_type_t *)&int_type,
scc_pos_create());
// 标识符 b
scc_ast_expr_t b_expr;
scc_ast_expr_identifier_init(&b_expr, "b", scc_pos_create());
// 类型转换 (int*)b
scc_ast_expr_t cast_expr;
scc_ast_expr_cast_init(&cast_expr, &ptr_to_int, &b_expr,
scc_pos_create());
// 解引用 *(int*)b
scc_ast_expr_t deref_expr;
scc_ast_expr_unary_init(&deref_expr, SCC_AST_OP_INDIRECTION,
&cast_expr, scc_pos_create());
// 声明 int a = *(int*)b;
scc_ast_decl_t decl;
scc_ast_decl_val_init(&decl, (scc_ast_type_t *)&int_type, "a",
&deref_expr, scc_pos_create());
SCC_CHECK_AST(&decl.base, "int a = *(int*)b;",
scc_parse_declaration);
}
// 测试 int a, b;
{
scc_ast_decl_t decl_a, decl_b;
scc_ast_decl_val_init(&decl_a, (scc_ast_type_t *)&int_type, "a",
nullptr, scc_pos_create());
scc_ast_decl_val_init(&decl_b, (scc_ast_type_t *)&int_type, "b",
nullptr, scc_pos_create());
scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec);
scc_vec_push(decl_vec, &decl_a);
scc_vec_push(decl_vec, &decl_b);
scc_ast_decl_t decl_list;
scc_ast_decl_list_init(&decl_list, &decl_vec,
scc_pos_create()); // 假设存在该函数
SCC_CHECK_AST(&decl_list.base, "int a, b;", scc_parse_declaration);
}
// 测试 int a = 1, b = 2;
{
scc_ast_expr_t lit1, lit2;
scc_ast_expr_literal_int_init(&lit1, "1", false, scc_pos_create());
scc_ast_expr_literal_int_init(&lit2, "2", false, scc_pos_create());
scc_ast_decl_t decl_a, decl_b;
scc_ast_decl_val_init(&decl_a, (scc_ast_type_t *)&int_type, "a",
&lit1, scc_pos_create());
scc_ast_decl_val_init(&decl_b, (scc_ast_type_t *)&int_type, "b",
&lit2, scc_pos_create());
scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec);
scc_vec_push(decl_vec, &decl_a);
scc_vec_push(decl_vec, &decl_b);
scc_ast_decl_t decl_list;
scc_ast_decl_list_init(&decl_list, &decl_vec,
scc_pos_create()); // 假设存在该函数
SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;",
scc_parse_declaration);
}
// 测试 "struct list_head *next, *prev;"
{
// 构造 struct list_head 类型(不完整)
scc_ast_type_t struct_list_head;
scc_ast_type_struct_init(&struct_list_head, "list_head", nullptr,
scc_pos_create());
// 构造两个指针类型(分别用于 next 和 prev指向同一结构体
scc_ast_type_t ptr_to_struct1, ptr_to_struct2;
scc_ast_type_pointer_init(&ptr_to_struct1, &struct_list_head,
scc_pos_create());
scc_ast_type_pointer_init(&ptr_to_struct2, &struct_list_head,
scc_pos_create());
// 构造变量声明 next 和 prev
scc_ast_decl_t next_decl, prev_decl;
scc_ast_decl_val_init(&next_decl, &ptr_to_struct1, "next", nullptr,
scc_pos_create());
scc_ast_decl_val_init(&prev_decl, &ptr_to_struct2, "prev", nullptr,
scc_pos_create());
// 构造声明列表
scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec);
scc_vec_push(decl_vec, &next_decl);
scc_vec_push(decl_vec, &prev_decl);
scc_ast_decl_t decl_list;
scc_ast_decl_list_init(&decl_list, &decl_vec, scc_pos_create());
SCC_CHECK_AST(&decl_list.base, "struct list_head *next, *prev;",
scc_parse_declaration);
}
// 测试 "typedef struct { int a; } struct_t, *struct_ptr_t;"
{
// 构造字段 int a;
scc_ast_decl_t field_a;
scc_ast_decl_val_init(&field_a, (scc_ast_type_t *)&int_type, "a",
nullptr, scc_pos_create());
scc_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field_a);
// 构造匿名结构体定义声明
scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, nullptr, &fields,
scc_pos_create()); // fields 被移动
// 构造匿名结构体类型
scc_ast_type_t anon_struct_type;
scc_ast_type_struct_init(&anon_struct_type, nullptr, &struct_def,
scc_pos_create());
// 构造指针类型指向该匿名结构体
scc_ast_type_t ptr_to_anon;
scc_ast_type_pointer_init(&ptr_to_anon, &anon_struct_type,
scc_pos_create());
// 构造 typedef 声明 struct_t
scc_ast_decl_t typedef_struct_t;
scc_ast_decl_typedef_init(&typedef_struct_t, "struct_t",
&anon_struct_type, scc_pos_create());
// 构造 typedef 声明 struct_ptr_t
scc_ast_decl_t typedef_struct_ptr_t;
scc_ast_decl_typedef_init(&typedef_struct_ptr_t, "struct_ptr_t",
&ptr_to_anon, scc_pos_create());
// 构造声明列表
scc_ast_decl_vec_t typedef_vec;
scc_vec_init(typedef_vec);
scc_vec_push(typedef_vec, &typedef_struct_t);
scc_vec_push(typedef_vec, &typedef_struct_ptr_t);
scc_ast_decl_t decl_list;
scc_ast_decl_list_init(&decl_list, &typedef_vec, scc_pos_create());
SCC_CHECK_AST(&decl_list.base,
"typedef struct { int a; } struct_t, *struct_ptr_t;",
scc_parse_declaration);
}
"__scc_builtin_va_arg(ag, int)";
"__scc_builtin_va_arg(ag, long long)";
"typedef struct a;int a;struct a b;";
}
{
// int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针)
// 步骤:
// 1) 数组类型int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false, scc_pos_create());
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int, (scc_ast_type_t *)&int_type,
&size_5, scc_pos_create());
// 2) 函数类型:返回指向数组的指针,无参数
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int,
scc_pos_create());
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, nullptr, 0,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &ptr_to_array, &func_params,
scc_pos_create()); // 无参数
// 3) 指向该函数的指针
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type, scc_pos_create());
scc_ast_decl_t ptr_to_func_decl;
scc_ast_decl_val_init(&ptr_to_func_decl, &ptr_to_func, "foo", nullptr,
scc_pos_create());
SCC_CHECK_AST(&ptr_to_func_decl.base, "int (*(*foo)(void))[5];",
scc_parse_declaration);
scc_ast_decl_t typedef_func_decl;
scc_ast_decl_typedef_init(&typedef_func_decl, "func_t", &ptr_to_func,
scc_pos_create());
scc_ast_type_t typedef_func_type;
scc_ast_type_typedef_init(&typedef_func_type, "func_t",
&typedef_func_decl, scc_pos_create());
scc_ast_decl_t func_hard_decl;
scc_ast_type_t func_hard_type;
scc_ast_decl_t param1;
scc_ast_decl_param_init(&param1, &ptr_to_func, "bar", 0,
scc_pos_create());
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &typedef_func_type, "a", 1,
scc_pos_create());
scc_ast_decl_t param3;
scc_ast_decl_param_init(&param1, &va_list_type, nullptr, 2,
scc_pos_create());
scc_ast_decl_t *func_hard_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_hard_params;
scc_vec_unsafe_from_static_array(func_hard_params, func_hard_array);
scc_ast_type_function_init(&func_hard_type, &ptr_to_array,
&func_hard_params, scc_pos_create());
scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", nullptr,
scc_pos_create());
scc_ast_decl_vec_t decls;
scc_ast_decl_t *decls_array[] = {
&typedef_func_decl,
&func_hard_decl,
};
scc_vec_unsafe_from_static_array(decls, decls_array);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &decls, scc_pos_create());
// SCC_CHECK_AST_WITH_SEMA(
// &tu.base,
// "typedef int (*(*func_t)(void))[5];"
// "int (*(*(bar)(int(*(*foo)(void))[5], func_t a,
// ...))(void))[5];", scc_parse_translation_unit);
}
}
TEST_LIST = {
{"parser_unit", test_parser_unit},
{nullptr, nullptr},
};