refactor(argparse): 将null替换为nullptr以提高C++兼容性

- 在argparse库中将所有null指针常量替换为nullptr
- 更新头文件和源文件中的指针初始化和比较操作
- 修改测试文件中的相关断言检查
- 更新AST定义文件中的注释说明
This commit is contained in:
zzy committed 2026-04-05 20:18:09 +08:00
1 parent 27d86d5685
commit 4144f7841c
76 files changed
+1430 -998

No files matched your search

+3 -3
View File
@@ -148,11 +148,11 @@ void scc_argparse_print_error(scc_argparse_context_t *ctx,
static inline void scc_argparse_spec_init(scc_argparse_spec_t *spec) { static inline void scc_argparse_spec_init(scc_argparse_spec_t *spec) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_STRING; spec->value_type = SCC_ARGPARSE_VAL_TYPE_STRING;
spec->raw_value = null; spec->raw_value = nullptr;
spec->store.ptr_store = null; spec->store.ptr_store = nullptr;
spec->choices.count = 0; spec->choices.count = 0;
spec->choices.values = null; spec->choices.values = nullptr;
spec->flag_required = false; spec->flag_required = false;
spec->flag_store_as_count = false; spec->flag_store_as_count = false;
+11 -10
View File
@@ -5,7 +5,7 @@ void scc_argparse_init(scc_argparse_t *parser, const char *program_name,
parser->prog_name = program_name; parser->prog_name = program_name;
parser->version = "0.1.0"; parser->version = "0.1.0";
parser->description = description; parser->description = description;
parser->epilog = null; parser->epilog = nullptr;
parser->lang = SCC_ARGPARSE_LANG_EN; parser->lang = SCC_ARGPARSE_LANG_EN;
parser->need_help = true; parser->need_help = true;
@@ -26,7 +26,7 @@ void scc_argparse_drop(scc_argparse_t *parser) {
static inline scc_argparse_cmd_t *is_subcommand(scc_argparse_cmd_t *cmd, static inline scc_argparse_cmd_t *is_subcommand(scc_argparse_cmd_t *cmd,
const char *name) { const char *name) {
if (!scc_vec_size(cmd->subcmds)) { if (!scc_vec_size(cmd->subcmds)) {
return null; return nullptr;
} }
scc_vec_foreach(cmd->subcmds, i) { scc_vec_foreach(cmd->subcmds, i) {
scc_argparse_cmd_t *subcmd = &scc_vec_at(cmd->subcmds, i); scc_argparse_cmd_t *subcmd = &scc_vec_at(cmd->subcmds, i);
@@ -34,7 +34,7 @@ static inline scc_argparse_cmd_t *is_subcommand(scc_argparse_cmd_t *cmd,
return subcmd; return subcmd;
} }
} }
return null; return nullptr;
} }
static inline void parse_cmd(scc_optparse_t *optparse, static inline void parse_cmd(scc_optparse_t *optparse,
@@ -86,7 +86,7 @@ static inline void parse_cmd(scc_optparse_t *optparse,
scc_optparse_set(optparse, opts->data); scc_optparse_set(optparse, opts->data);
} }
static void push_help(scc_argparse_cmd_t *cmd) { static void push_help(scc_argparse_cmd_t *cmd) {
if (cmd == null) { if (cmd == nullptr) {
return; return;
} }
scc_vec_push(cmd->opts, ((scc_argparse_opt_t){ scc_vec_push(cmd->opts, ((scc_argparse_opt_t){
@@ -144,7 +144,8 @@ static int validate_and_cleanup(scc_argparse_context_t *ctx,
// 检查必需参数是否都已提供 // 检查必需参数是否都已提供
scc_vec_foreach(ctx->current_cmd->args, i) { scc_vec_foreach(ctx->current_cmd->args, i) {
scc_argparse_arg_t *arg = &scc_vec_at(ctx->current_cmd->args, i); scc_argparse_arg_t *arg = &scc_vec_at(ctx->current_cmd->args, i);
if (arg->spec.flag_required && *arg->spec.store.str_store == NULL) { if (arg->spec.flag_required &&
*arg->spec.store.str_store == nullptr) {
errcode = SCC_ARGPARSE_ERR_MISSING_ARG; errcode = SCC_ARGPARSE_ERR_MISSING_ARG;
scc_argparse_print_error(ctx, errcode); scc_argparse_print_error(ctx, errcode);
break; break;
@@ -190,7 +191,7 @@ static int handle_option(scc_argparse_context_t *ctx, scc_argparse_t *parser) {
*opt->spec.store.str_store = ctx->result.value; *opt->spec.store.str_store = ctx->result.value;
} }
// // opt value == null or value != null // // opt value == nullptr or value != nullptr
// scc_argparse_opt_t *org_opt = // scc_argparse_opt_t *org_opt =
// (scc_argparse_opt_t *)opt_res.opt->user_data; // (scc_argparse_opt_t *)opt_res.opt->user_data;
// if (parser->need_help) { // if (parser->need_help) {
@@ -218,7 +219,7 @@ static int handle_positional_arg(scc_argparse_context_t *ctx,
(void)parser; // TODO (void)parser; // TODO
scc_argparse_cmd_t *subcmd = scc_argparse_cmd_t *subcmd =
is_subcommand(ctx->current_cmd, ctx->result.value); is_subcommand(ctx->current_cmd, ctx->result.value);
if (subcmd != NULL) { if (subcmd != nullptr) {
ctx->current_cmd = subcmd; ctx->current_cmd = subcmd;
parse_cmd(&ctx->optparse, &ctx->opts, ctx->current_cmd); parse_cmd(&ctx->optparse, &ctx->opts, ctx->current_cmd);
return SCC_ARGPARSE_ERR_NONE; return SCC_ARGPARSE_ERR_NONE;
@@ -239,7 +240,7 @@ static int handle_positional_arg(scc_argparse_context_t *ctx,
// scc_argparse_cmd_t *cmd = is_subcommand(current_cmd, // scc_argparse_cmd_t *cmd = is_subcommand(current_cmd,
// opt_res.value); // opt_res.value);
// if (cmd != null) { // if (cmd != nullptr) {
// current_cmd = cmd; // current_cmd = cmd;
// parse_cmd(&optparse, &opts, current_cmd); // parse_cmd(&optparse, &opts, current_cmd);
// } else { // } else {
@@ -275,9 +276,9 @@ int scc_argparse_parse(scc_argparse_t *parser, int argc, const char **argv) {
break; break;
} }
if (ctx.result.opt != null) { if (ctx.result.opt != nullptr) {
errcode = handle_option(&ctx, parser); errcode = handle_option(&ctx, parser);
} else if (ctx.result.value != null) { } else if (ctx.result.value != nullptr) {
errcode = handle_positional_arg(&ctx, parser); errcode = handle_positional_arg(&ctx, parser);
} else { } else {
UNREACHABLE(); // 不应到达此处 UNREACHABLE(); // 不应到达此处
+2 -2
View File
@@ -174,8 +174,8 @@ void scc_argparse_print_help(scc_argparse_t *parser, scc_argparse_cmd_t *cmd) {
const char *scc_argparse_find_similar_arg(scc_argparse_cmd_t *cmd, const char *scc_argparse_find_similar_arg(scc_argparse_cmd_t *cmd,
const char *arg) { const char *arg) {
if (arg == null || cmd == null) { if (arg == nullptr || cmd == nullptr) {
return null; return nullptr;
} }
if (arg[0] == '-' && arg[1] == '-' && arg[2] != '\0') { if (arg[0] == '-' && arg[1] == '-' && arg[2] != '\0') {
// opt arg // opt arg
+40 -40
View File
@@ -45,21 +45,21 @@ void test_simple_short_options(void) {
// 解析第一个选项 -h // 解析第一个选项 -h
TEST_CHECK(scc_optparse_parse(&parser, &res) != 0); TEST_CHECK(scc_optparse_parse(&parser, &res) != 0);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'h'); TEST_CHECK(res.opt && res.opt->short_name == 'h');
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
// 解析第二个选项 -v // 解析第二个选项 -v
TEST_CHECK(scc_optparse_parse(&parser, &res) != 0); TEST_CHECK(scc_optparse_parse(&parser, &res) != 0);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'v'); TEST_CHECK(res.opt && res.opt->short_name == 'v');
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
// 没有更多选项 // 没有更多选项
TEST_CHECK(scc_optparse_parse(&parser, &res) == 0); TEST_CHECK(scc_optparse_parse(&parser, &res) == 0);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
} }
void test_simple_position_arg(void) { void test_simple_position_arg(void) {
@@ -70,19 +70,19 @@ void test_simple_position_arg(void) {
// 解析第一个选项 // 解析第一个选项
TEST_CHECK(scc_optparse_parse(&parser, &res) != 0); TEST_CHECK(scc_optparse_parse(&parser, &res) != 0);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "a") == 0); TEST_CHECK(strcmp(res.value, "a") == 0);
// 解析第二个选项 // 解析第二个选项
TEST_CHECK(scc_optparse_parse(&parser, &res) != 0); TEST_CHECK(scc_optparse_parse(&parser, &res) != 0);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "b") == 0); TEST_CHECK(strcmp(res.value, "b") == 0);
// 没有更多选项 // 没有更多选项
TEST_CHECK(scc_optparse_parse(&parser, &res) == 0); TEST_CHECK(scc_optparse_parse(&parser, &res) == 0);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
} }
// 测试3: 带参数的短选项 // 测试3: 带参数的短选项
@@ -95,14 +95,14 @@ void test_short_options_with_args(void) {
// 解析 -f file.txt // 解析 -f file.txt
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'f'); TEST_CHECK(res.opt && res.opt->short_name == 'f');
TEST_CHECK(strcmp(res.value, "file.txt") == 0); TEST_CHECK(strcmp(res.value, "file.txt") == 0);
// 解析 -o output.txt // 解析 -o output.txt
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'o'); TEST_CHECK(res.opt && res.opt->short_name == 'o');
TEST_CHECK(strcmp(res.value, "output.txt") == 0); TEST_CHECK(strcmp(res.value, "output.txt") == 0);
} }
@@ -119,20 +119,20 @@ void test_long_options(void) {
// 解析 --help // 解析 --help
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && strcmp(res.opt->long_name, "help") == 0); TEST_CHECK(res.opt && strcmp(res.opt->long_name, "help") == 0);
// 解析 --file=test.txt // 解析 --file=test.txt
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && strcmp(res.opt->long_name, "file") == 0); TEST_CHECK(res.opt && strcmp(res.opt->long_name, "file") == 0);
TEST_CHECK(strcmp(res.value, "test.txt") == 0); TEST_CHECK(strcmp(res.value, "test.txt") == 0);
// 解析 --output out.txt // 解析 --output out.txt
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && strcmp(res.opt->long_name, "output") == 0); TEST_CHECK(res.opt && strcmp(res.opt->long_name, "output") == 0);
TEST_CHECK(strcmp(res.value, "out.txt") == 0); TEST_CHECK(strcmp(res.value, "out.txt") == 0);
} }
@@ -160,13 +160,13 @@ void test_mixed_options_positional(void) {
// 解析第一个位置参数 // 解析第一个位置参数
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "positional1") == 0); TEST_CHECK(strcmp(res.value, "positional1") == 0);
// 解析第二个位置参数 // 解析第二个位置参数
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "positional2") == 0); TEST_CHECK(strcmp(res.value, "positional2") == 0);
} }
@@ -250,13 +250,13 @@ void test_option_terminator(void) {
// 解析 -f (作为位置参数) // 解析 -f (作为位置参数)
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "-f") == 0); TEST_CHECK(strcmp(res.value, "-f") == 0);
// 解析 file.txt (作为位置参数) // 解析 file.txt (作为位置参数)
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "file.txt") == 0); TEST_CHECK(strcmp(res.value, "file.txt") == 0);
} }
@@ -270,8 +270,8 @@ void test_edge_cases(void) {
INIT_OPTPARSE(argv1); INIT_OPTPARSE(argv1);
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
// 测试空字符串参数 // 测试空字符串参数
const char *argv2[] = {"program", "-f", "", "-o", " "}; const char *argv2[] = {"program", "-f", "", "-o", " "};
@@ -302,23 +302,23 @@ void test_multi_argument_option(void) {
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt && res.opt->short_name == 'l'); TEST_CHECK(res.opt && res.opt->short_name == 'l');
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
// 由于 -l 可以接受多个参数,后续的参数应该作为 -l 的值 // 由于 -l 可以接受多个参数,后续的参数应该作为 -l 的值
// 但根据当前实现,可能需要多次调用 // 但根据当前实现,可能需要多次调用
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(strcmp(res.value, "item1") == 0); TEST_CHECK(strcmp(res.value, "item1") == 0);
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(strcmp(res.value, "item2") == 0); TEST_CHECK(strcmp(res.value, "item2") == 0);
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(strcmp(res.value, "item3") == 0); TEST_CHECK(strcmp(res.value, "item3") == 0);
} }
@@ -344,7 +344,7 @@ void test_long_option_with_equal_no_value(void) {
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NOT_ENOUGH_ARGS); TEST_CHECK(res.error == SCC_OPT_ERROR_NOT_ENOUGH_ARGS);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && strcmp(res.opt->long_name, "file") == 0); TEST_CHECK(res.opt && strcmp(res.opt->long_name, "file") == 0);
} }
@@ -382,14 +382,14 @@ void test_combined_short_with_arg(void) {
// 解析 -v // 解析 -v
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'v'); TEST_CHECK(res.opt && res.opt->short_name == 'v');
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
// 解析 -finput.txt // 解析 -finput.txt
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'f'); TEST_CHECK(res.opt && res.opt->short_name == 'f');
TEST_CHECK(strcmp(res.value, "input.txt") == 0); TEST_CHECK(strcmp(res.value, "input.txt") == 0);
} }
@@ -405,14 +405,14 @@ void test_too_many_arguments(void) {
// 解析 -f file1 // 解析 -f file1
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'f'); TEST_CHECK(res.opt && res.opt->short_name == 'f');
TEST_CHECK(strcmp(res.value, "file1") == 0); TEST_CHECK(strcmp(res.value, "file1") == 0);
// 尝试给 -f 第二个参数,应该返回错误 // 尝试给 -f 第二个参数,应该返回错误
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "file2") == 0); TEST_CHECK(strcmp(res.value, "file2") == 0);
} }
@@ -438,7 +438,7 @@ void test_mixed_short_and_positional(void) {
// 解析位置参数 // 解析位置参数
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "positional") == 0); TEST_CHECK(strcmp(res.value, "positional") == 0);
} }
@@ -471,7 +471,7 @@ void test_complex_multi_argument(void) {
// 第4个参数应该是位置参数 // 第4个参数应该是位置参数
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "extra") == 0); TEST_CHECK(strcmp(res.value, "extra") == 0);
} }
@@ -487,7 +487,7 @@ void test_long_option_multi_args(void) {
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt && strcmp(res.opt->long_name, "list") == 0); TEST_CHECK(res.opt && strcmp(res.opt->long_name, "list") == 0);
TEST_CHECK(res.value == NULL); TEST_CHECK(res.value == nullptr);
// 解析 item1 // 解析 item1
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
@@ -518,7 +518,7 @@ void test_empty_long_name(void) {
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(parser.handle_positional == 1); TEST_CHECK(parser.handle_positional == 1);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "--") == 0); TEST_CHECK(strcmp(res.value, "--") == 0);
} }
@@ -538,7 +538,7 @@ void test_non_dash_prefix(void) {
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE); TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt != NULL); TEST_CHECK(res.opt != nullptr);
TEST_CHECK(res.opt && res.opt->short_name == 'h'); TEST_CHECK(res.opt && res.opt->short_name == 'h');
TEST_CHECK(res.opt && res.opt->prefix == '/'); TEST_CHECK(res.opt && res.opt->prefix == '/');
} }
@@ -550,7 +550,7 @@ void test_default_value(void) {
// scc_optparse_result_t res; // scc_optparse_result_t res;
// static scc_optparse_opt_t default_opts[] = { // static scc_optparse_opt_t default_opts[] = {
// SCC_OPTPARSE_OPT('-', 'o', "output", 0, 1, "default.txt", NULL), // SCC_OPTPARSE_OPT('-', 'o', "output", 0, 1, "default.txt", nullptr),
// SCC_OPTPARSE_OPT_END(), // SCC_OPTPARSE_OPT_END(),
// }; // };
@@ -602,7 +602,7 @@ void test_callback_function(void) {
// // 调用回调函数 // // 调用回调函数
// if (res.opt->invoke) { // if (res.opt->invoke) {
// res.opt->invoke(NULL); // res.opt->invoke(nullptr);
// TEST_CHECK(callback_called == 1); // TEST_CHECK(callback_called == 1);
// } // }
} }
@@ -644,7 +644,7 @@ void test_single_dash(void) {
// 解析单个横杠(通常表示标准输入) // 解析单个横杠(通常表示标准输入)
scc_optparse_parse(&parser, &res); scc_optparse_parse(&parser, &res);
TEST_CHECK(res.opt == NULL); TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "-") == 0); TEST_CHECK(strcmp(res.value, "-") == 0);
// 解析 -- // 解析 --
@@ -724,5 +724,5 @@ TEST_LIST = {
{"test_complex_short_combination", test_complex_short_combination}, {"test_complex_short_combination", test_complex_short_combination},
{"test_single_dash", test_single_dash}, {"test_single_dash", test_single_dash},
{"test_parser_state_reset", test_parser_state_reset}, {"test_parser_state_reset", test_parser_state_reset},
{NULL, NULL}, {nullptr, nullptr},
}; };
+9 -9
View File
@@ -176,7 +176,7 @@ struct scc_ast_type {
} pointer; } pointer;
struct { struct {
scc_ast_type_t *element; scc_ast_type_t *element;
scc_ast_expr_t *size; // 可为 null <=> 不定长数组 scc_ast_expr_t *size; // 可为 nullptr <=> 不定长数组
} array; } array;
struct { struct {
scc_ast_type_t *return_type; scc_ast_type_t *return_type;
@@ -184,7 +184,7 @@ struct scc_ast_type {
} function; } function;
struct { struct {
const char *name; const char *name;
scc_ast_decl_t *decl; // can be null scc_ast_decl_t *decl; // can be nullptr
} record; } record;
struct { struct {
const char *name; const char *name;
@@ -354,7 +354,7 @@ struct scc_ast_stmt {
struct { struct {
scc_ast_expr_t *cond; scc_ast_expr_t *cond;
scc_ast_stmt_t *then_stmt; scc_ast_stmt_t *then_stmt;
scc_ast_stmt_t *opt_else_stmt; // stmt or null scc_ast_stmt_t *opt_else_stmt; // stmt or nullptr
} if_stmt; } if_stmt;
// while do-while 语句 // while do-while 语句
struct { struct {
@@ -363,9 +363,9 @@ struct scc_ast_stmt {
} while_stmt; } while_stmt;
// for 语句 // for 语句
struct { struct {
scc_ast_node_t *init; // expr or decl or null scc_ast_node_t *init; // expr or decl or nullptr
scc_ast_expr_t *cond; // 可为 null scc_ast_expr_t *cond; // 可为 nullptr
scc_ast_expr_t *incr; // 可为 null scc_ast_expr_t *incr; // 可为 nullptr
scc_ast_stmt_t *body; scc_ast_stmt_t *body;
} for_stmt; } for_stmt;
// switch 语句 // switch 语句
@@ -388,7 +388,7 @@ struct scc_ast_stmt {
} jump; } jump;
// return 语句 // return 语句
struct { struct {
scc_ast_expr_t *expr; // 可为 null scc_ast_expr_t *expr; // 可为 nullptr
} return_stmt; } return_stmt;
// goto 语句 // goto 语句
struct { struct {
@@ -416,12 +416,12 @@ struct scc_ast_decl {
// 变量声明 // 变量声明
struct { struct {
scc_ast_type_t *type; scc_ast_type_t *type;
scc_ast_expr_t *init; // 可为 NULL scc_ast_expr_t *init; // 可为 nullptr
} var; } var;
// 函数声明 // 函数声明
struct { struct {
scc_ast_type_t *type; // 函数类型 scc_ast_type_t *type; // 函数类型
scc_ast_stmt_t *body; // 可为 null 表示只有声明 scc_ast_stmt_t *body; // 可为 nullptr 表示只有声明
} func; } func;
// 参数声明 // 参数声明
struct { struct {
+75 -75
View File
@@ -4,14 +4,14 @@
#include "ast_def.h" #include "ast_def.h"
#include "ast_dump.h" #include "ast_dump.h"
// decls can be null but maybe warning // decls can be nullptr but maybe warning
static inline void static inline void
scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit, scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit,
scc_ast_decl_vec_t *decls, scc_pos_t loc) { scc_ast_decl_vec_t *decls, scc_pos_t loc) {
Assert(translation_unit != null); Assert(translation_unit != nullptr);
translation_unit->base.type = SCC_AST_TRANSLATION_UNIT; translation_unit->base.type = SCC_AST_TRANSLATION_UNIT;
translation_unit->base.loc = loc; translation_unit->base.loc = loc;
if (decls == null) { if (decls == nullptr) {
scc_vec_init(translation_unit->declarations); scc_vec_init(translation_unit->declarations);
} else { } else {
translation_unit->declarations = *decls; translation_unit->declarations = *decls;
@@ -22,21 +22,21 @@ scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit,
static inline void scc_ast_decl_list_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_list_init(scc_ast_decl_t *decl,
scc_ast_decl_vec_t *list_move, scc_ast_decl_vec_t *list_move,
scc_pos_t loc) { scc_pos_t loc) {
Assert(decl != null && list_move != null); Assert(decl != nullptr && list_move != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_LIST; decl->base.type = SCC_AST_DECL_LIST;
decl->name = null; decl->name = nullptr;
decl->list.vars = *list_move; decl->list.vars = *list_move;
scc_vec_init(*list_move); scc_vec_init(*list_move);
} }
// name and var_init can be null // name and var_init can be nullptr
static inline void scc_ast_decl_unsafe_val_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_unsafe_val_init(scc_ast_decl_t *decl,
scc_ast_type_t *type, scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_expr_t *var_init, scc_ast_expr_t *var_init,
scc_pos_t loc) { scc_pos_t loc) {
Assert(decl != null && type != null); Assert(decl != nullptr && type != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_VAR; decl->base.type = SCC_AST_DECL_VAR;
decl->name = name; decl->name = name;
@@ -44,12 +44,12 @@ static inline void scc_ast_decl_unsafe_val_init(scc_ast_decl_t *decl,
decl->var.init = var_init; decl->var.init = var_init;
} }
// var_init can be null // var_init can be nullptr
static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl,
scc_ast_type_t *type, const char *name, scc_ast_type_t *type, const char *name,
scc_ast_expr_t *var_init, scc_ast_expr_t *var_init,
scc_pos_t loc) { scc_pos_t loc) {
Assert(decl != null && name != null && type != null); Assert(decl != nullptr && name != nullptr && type != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_VAR; decl->base.type = SCC_AST_DECL_VAR;
decl->name = name; decl->name = name;
@@ -57,12 +57,12 @@ static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl,
decl->var.init = var_init; decl->var.init = var_init;
} }
// body can be null // body can be nullptr
static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl,
scc_ast_type_t *type, scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_stmt_t *body, scc_pos_t loc) { scc_ast_stmt_t *body, scc_pos_t loc) {
Assert(decl != null && name != null && type != null); Assert(decl != nullptr && name != nullptr && type != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_FUNC; decl->base.type = SCC_AST_DECL_FUNC;
decl->name = name; decl->name = name;
@@ -71,11 +71,11 @@ static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl,
decl->func.body = body; decl->func.body = body;
} }
// name can be null // name can be nullptr
static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl,
scc_ast_type_t *type, scc_ast_type_t *type,
const char *name, scc_pos_t loc) { const char *name, scc_pos_t loc) {
Assert(decl != null && type != null); Assert(decl != nullptr && type != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_PARAM; decl->base.type = SCC_AST_DECL_PARAM;
decl->name = name; decl->name = name;
@@ -87,11 +87,11 @@ static inline void _scc_ast_decl_record_init(scc_ast_decl_t *decl,
const char *name, const char *name,
scc_ast_decl_vec_t *fields_move, scc_ast_decl_vec_t *fields_move,
scc_pos_t loc) { scc_pos_t loc) {
Assert(decl != null); Assert(decl != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = type; decl->base.type = type;
decl->name = name; decl->name = name;
if (fields_move == null) { if (fields_move == nullptr) {
scc_vec_init(decl->record.fields); scc_vec_init(decl->record.fields);
} else { } else {
decl->record.fields = *fields_move; decl->record.fields = *fields_move;
@@ -99,7 +99,7 @@ static inline void _scc_ast_decl_record_init(scc_ast_decl_t *decl,
} }
} }
// name and fields can be null // name and fields can be nullptr
static inline void scc_ast_decl_struct_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_struct_init(scc_ast_decl_t *decl,
const char *name, const char *name,
scc_ast_decl_vec_t *fields_move, scc_ast_decl_vec_t *fields_move,
@@ -108,7 +108,7 @@ static inline void scc_ast_decl_struct_init(scc_ast_decl_t *decl,
loc); loc);
} }
// name and fields can be null // name and fields can be nullptr
static inline void scc_ast_decl_union_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_union_init(scc_ast_decl_t *decl,
const char *name, const char *name,
scc_ast_decl_vec_t *fields_move, scc_ast_decl_vec_t *fields_move,
@@ -116,7 +116,7 @@ static inline void scc_ast_decl_union_init(scc_ast_decl_t *decl,
_scc_ast_decl_record_init(decl, SCC_AST_DECL_UNION, name, fields_move, loc); _scc_ast_decl_record_init(decl, SCC_AST_DECL_UNION, name, fields_move, loc);
} }
// name and fields can be null // name and fields can be nullptr
static inline void scc_ast_decl_enum_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_enum_init(scc_ast_decl_t *decl,
const char *name, const char *name,
scc_ast_decl_vec_t *fields_move, scc_ast_decl_vec_t *fields_move,
@@ -128,20 +128,20 @@ static inline void scc_ast_decl_typedef_init(scc_ast_decl_t *decl,
const char *name, const char *name,
scc_ast_type_t *type, scc_ast_type_t *type,
scc_pos_t loc) { scc_pos_t loc) {
Assert(decl != null && name != null && type != null); Assert(decl != nullptr && name != nullptr && type != nullptr);
decl->base.loc = loc; decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_TYPEDEF; decl->base.type = SCC_AST_DECL_TYPEDEF;
decl->name = name; decl->name = name;
decl->typedef_decl.type = type; decl->typedef_decl.type = type;
} }
// items can be null // items can be nullptr
static inline void scc_ast_stmt_compound_init( 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) { scc_ast_stmt_t *stmt, scc_ast_block_item_vec_t *items_move, scc_pos_t loc) {
Assert(stmt != null); Assert(stmt != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_COMPOUND; stmt->base.type = SCC_AST_STMT_COMPOUND;
if (items_move == null) { if (items_move == nullptr) {
scc_vec_init(stmt->compound.block_items); scc_vec_init(stmt->compound.block_items);
} else { } else {
stmt->compound.block_items = *items_move; stmt->compound.block_items = *items_move;
@@ -149,22 +149,22 @@ static inline void scc_ast_stmt_compound_init(
} }
} }
// expr can be null // expr can be nullptr
static inline void scc_ast_stmt_expr_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_expr_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *expr, scc_pos_t loc) { scc_ast_expr_t *expr, scc_pos_t loc) {
Assert(stmt != null); Assert(stmt != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_EXPR; stmt->base.type = SCC_AST_STMT_EXPR;
stmt->expr.expr = expr; stmt->expr.expr = expr;
} }
// opt_else can be null // opt_else can be nullptr
static inline void scc_ast_stmt_if_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_if_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *cond, scc_ast_expr_t *cond,
scc_ast_stmt_t *then, scc_ast_stmt_t *then,
scc_ast_stmt_t *opt_else, scc_ast_stmt_t *opt_else,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null && cond != null && then != null); Assert(stmt != nullptr && cond != nullptr && then != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_IF; stmt->base.type = SCC_AST_STMT_IF;
stmt->if_stmt.cond = cond; stmt->if_stmt.cond = cond;
@@ -176,7 +176,7 @@ static inline void scc_ast_stmt_while_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *cond, scc_ast_expr_t *cond,
scc_ast_stmt_t *body, scc_ast_stmt_t *body,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null); Assert(stmt != nullptr && cond != nullptr && body != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_WHILE; stmt->base.type = SCC_AST_STMT_WHILE;
stmt->while_stmt.cond = cond; stmt->while_stmt.cond = cond;
@@ -187,7 +187,7 @@ static inline void scc_ast_stmt_do_while_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *cond, scc_ast_expr_t *cond,
scc_ast_stmt_t *body, scc_ast_stmt_t *body,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null); Assert(stmt != nullptr && cond != nullptr && body != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_DO_WHILE; stmt->base.type = SCC_AST_STMT_DO_WHILE;
stmt->while_stmt.cond = cond; stmt->while_stmt.cond = cond;
@@ -200,7 +200,7 @@ static inline void scc_ast_stmt_for_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *cond, scc_ast_expr_t *cond,
scc_ast_expr_t *incr, scc_ast_expr_t *incr,
scc_ast_stmt_t *body, scc_pos_t loc) { scc_ast_stmt_t *body, scc_pos_t loc) {
Assert(stmt != null && body != null); Assert(stmt != nullptr && body != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_FOR; stmt->base.type = SCC_AST_STMT_FOR;
stmt->for_stmt.init = init; stmt->for_stmt.init = init;
@@ -213,7 +213,7 @@ static inline void scc_ast_stmt_switch_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *cond, scc_ast_expr_t *cond,
scc_ast_stmt_t *body, scc_ast_stmt_t *body,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null); Assert(stmt != nullptr && cond != nullptr && body != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_SWITCH; stmt->base.type = SCC_AST_STMT_SWITCH;
stmt->switch_stmt.cond = cond; stmt->switch_stmt.cond = cond;
@@ -223,7 +223,7 @@ static inline void scc_ast_stmt_switch_init(scc_ast_stmt_t *stmt,
static inline void scc_ast_stmt_case_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_case_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *cond, scc_ast_expr_t *cond,
scc_ast_stmt_t *body, scc_pos_t loc) { scc_ast_stmt_t *body, scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null); Assert(stmt != nullptr && cond != nullptr && body != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_CASE; stmt->base.type = SCC_AST_STMT_CASE;
stmt->case_stmt.expr = cond; stmt->case_stmt.expr = cond;
@@ -233,7 +233,7 @@ static inline void scc_ast_stmt_case_init(scc_ast_stmt_t *stmt,
static inline void scc_ast_stmt_default_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_default_init(scc_ast_stmt_t *stmt,
scc_ast_stmt_t *body, scc_ast_stmt_t *body,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null && body != null); Assert(stmt != nullptr && body != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_DEFAULT; stmt->base.type = SCC_AST_STMT_DEFAULT;
stmt->default_stmt.stmt = body; stmt->default_stmt.stmt = body;
@@ -241,25 +241,25 @@ static inline void scc_ast_stmt_default_init(scc_ast_stmt_t *stmt,
static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null); Assert(stmt != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_BREAK; stmt->base.type = SCC_AST_STMT_BREAK;
stmt->jump._target = null; stmt->jump._target = nullptr;
} }
static inline void scc_ast_stmt_continue_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_continue_init(scc_ast_stmt_t *stmt,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null); Assert(stmt != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_CONTINUE; stmt->base.type = SCC_AST_STMT_CONTINUE;
stmt->jump._target = null; stmt->jump._target = nullptr;
} }
// expr can be null // expr can be nullptr
static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *expr, scc_ast_expr_t *expr,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null); Assert(stmt != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_RETURN; stmt->base.type = SCC_AST_STMT_RETURN;
stmt->return_stmt.expr = expr; stmt->return_stmt.expr = expr;
@@ -267,18 +267,18 @@ static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt,
static inline void scc_ast_stmt_goto_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_goto_init(scc_ast_stmt_t *stmt,
const char *label, scc_pos_t loc) { const char *label, scc_pos_t loc) {
Assert(stmt != null && label != null); Assert(stmt != nullptr && label != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_GOTO; stmt->base.type = SCC_AST_STMT_GOTO;
stmt->goto_stmt.label = label; stmt->goto_stmt.label = label;
stmt->goto_stmt._target = null; stmt->goto_stmt._target = nullptr;
} }
static inline void scc_ast_stmt_label_init(scc_ast_stmt_t *stmt, static inline void scc_ast_stmt_label_init(scc_ast_stmt_t *stmt,
const char *label, const char *label,
scc_ast_stmt_t *body, scc_ast_stmt_t *body,
scc_pos_t loc) { scc_pos_t loc) {
Assert(stmt != null); Assert(stmt != nullptr);
stmt->base.loc = loc; stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_LABEL; stmt->base.type = SCC_AST_STMT_LABEL;
stmt->label_stmt.label = label; stmt->label_stmt.label = label;
@@ -290,7 +290,7 @@ static inline void scc_ast_expr_binary_init(scc_ast_expr_t *expr,
scc_ast_expr_t *lhs, scc_ast_expr_t *lhs,
scc_ast_expr_t *rhs, scc_ast_expr_t *rhs,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && lhs != null && rhs != null); Assert(expr != nullptr && lhs != nullptr && rhs != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_BINARY; expr->base.type = SCC_AST_EXPR_BINARY;
expr->binary.op = op; expr->binary.op = op;
@@ -302,7 +302,7 @@ static inline void scc_ast_expr_unary_init(scc_ast_expr_t *expr,
scc_ast_expr_op_t op, scc_ast_expr_op_t op,
scc_ast_expr_t *operand, scc_ast_expr_t *operand,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && operand != null); Assert(expr != nullptr && operand != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_UNARY; expr->base.type = SCC_AST_EXPR_UNARY;
expr->unary.op = op; expr->unary.op = op;
@@ -314,8 +314,8 @@ static inline void scc_ast_expr_cond_init(scc_ast_expr_t *expr,
scc_ast_expr_t *then_expr, scc_ast_expr_t *then_expr,
scc_ast_expr_t *else_expr, scc_ast_expr_t *else_expr,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && cond != null && then_expr != null && Assert(expr != nullptr && cond != nullptr && then_expr != nullptr &&
else_expr != null); else_expr != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_COND; expr->base.type = SCC_AST_EXPR_COND;
expr->cond.cond = cond; expr->cond.cond = cond;
@@ -323,16 +323,16 @@ static inline void scc_ast_expr_cond_init(scc_ast_expr_t *expr,
expr->cond.else_expr = else_expr; expr->cond.else_expr = else_expr;
} }
// args can be null // args can be nullptr
static inline void scc_ast_expr_call_init(scc_ast_expr_t *expr, static inline void scc_ast_expr_call_init(scc_ast_expr_t *expr,
scc_ast_expr_t *callee, scc_ast_expr_t *callee,
scc_ast_expr_vec_t *args, scc_ast_expr_vec_t *args,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && callee != null); Assert(expr != nullptr && callee != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_CALL; expr->base.type = SCC_AST_EXPR_CALL;
expr->call.callee = callee; expr->call.callee = callee;
if (args == null) { if (args == nullptr) {
scc_vec_init(expr->call.args); scc_vec_init(expr->call.args);
} else { } else {
expr->call.args = *args; expr->call.args = *args;
@@ -344,7 +344,7 @@ static inline void scc_ast_expr_array_subscript_init(scc_ast_expr_t *expr,
scc_ast_expr_t *array, scc_ast_expr_t *array,
scc_ast_expr_t *index, scc_ast_expr_t *index,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && array != null && index != null); Assert(expr != nullptr && array != nullptr && index != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_ARRAY_SUBSCRIPT; expr->base.type = SCC_AST_EXPR_ARRAY_SUBSCRIPT;
expr->subscript.array = array; expr->subscript.array = array;
@@ -356,7 +356,7 @@ static inline void _scc_ast_expr_member_init(scc_ast_expr_t *expr,
scc_ast_expr_t *object, scc_ast_expr_t *object,
const char *member, const char *member,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && object != null && member != null); Assert(expr != nullptr && object != nullptr && member != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = type; expr->base.type = type;
expr->member.base = object; expr->member.base = object;
@@ -382,31 +382,31 @@ static inline void scc_ast_expr_cast_init(scc_ast_expr_t *expr,
scc_ast_type_t *type, scc_ast_type_t *type,
scc_ast_expr_t *operand, scc_ast_expr_t *operand,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && type != null && operand != null); Assert(expr != nullptr && type != nullptr && operand != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_CAST; expr->base.type = SCC_AST_EXPR_CAST;
expr->cast.type = type; expr->cast.type = type;
expr->cast.expr = operand; expr->cast.expr = operand;
} }
// type and target_expr can be null but it only one of them can be null // 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, static inline void scc_ast_expr_sizeof_init(scc_ast_expr_t *expr,
scc_ast_type_t *type, scc_ast_type_t *type,
scc_ast_expr_t *target_expr, scc_ast_expr_t *target_expr,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null); Assert(expr != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_SIZE_OF; expr->base.type = SCC_AST_EXPR_SIZE_OF;
expr->attr_of.type = type; expr->attr_of.type = type;
expr->attr_of.expr = target_expr; expr->attr_of.expr = target_expr;
} }
// type and target_expr can be null but it only one of them can be null // 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, static inline void scc_ast_expr_alignof_init(scc_ast_expr_t *expr,
scc_ast_type_t *type, scc_ast_type_t *type,
scc_ast_expr_t *target_expr, scc_ast_expr_t *target_expr,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null); Assert(expr != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = expr->base.type =
SCC_AST_EXPR_SIZE_OF; // 注意:这里使用了 SIZE_OF,可能需要改为 ALIGN_OF SCC_AST_EXPR_SIZE_OF; // 注意:这里使用了 SIZE_OF,可能需要改为 ALIGN_OF
@@ -414,25 +414,25 @@ static inline void scc_ast_expr_alignof_init(scc_ast_expr_t *expr,
expr->attr_of.expr = target_expr; expr->attr_of.expr = target_expr;
} }
// lhs_exprs and rhs_exprs can be null // lhs_exprs and rhs_exprs can be nullptr
static inline void scc_ast_expr_compound_init(scc_ast_expr_t *expr, static inline void scc_ast_expr_compound_init(scc_ast_expr_t *expr,
scc_ast_expr_t *base, scc_ast_expr_t *base,
scc_ast_expr_vec_t *lhs_exprs, scc_ast_expr_vec_t *lhs_exprs,
scc_ast_expr_vec_t *rhs_exprs, scc_ast_expr_vec_t *rhs_exprs,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && base != null); Assert(expr != nullptr && base != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_COMPOUND; expr->base.type = SCC_AST_EXPR_COMPOUND;
expr->compound.base = base; expr->compound.base = base;
if (lhs_exprs == null) { if (lhs_exprs == nullptr) {
scc_vec_init(expr->compound.lhs_exprs); scc_vec_init(expr->compound.lhs_exprs);
} else { } else {
expr->compound.lhs_exprs = *lhs_exprs; expr->compound.lhs_exprs = *lhs_exprs;
scc_vec_init(*lhs_exprs); scc_vec_init(*lhs_exprs);
} }
if (rhs_exprs == null) { if (rhs_exprs == nullptr) {
scc_vec_init(expr->compound.rhs_exprs); scc_vec_init(expr->compound.rhs_exprs);
} else { } else {
expr->compound.rhs_exprs = *rhs_exprs; expr->compound.rhs_exprs = *rhs_exprs;
@@ -444,7 +444,7 @@ static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr,
scc_ast_node_type_t type, scc_ast_node_type_t type,
const char *value, cbool owned, const char *value, cbool owned,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && value != null); Assert(expr != nullptr && value != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = type; expr->base.type = type;
expr->literal.lexme = value; expr->literal.lexme = value;
@@ -481,17 +481,17 @@ static inline void scc_ast_expr_literal_string_init(scc_ast_expr_t *expr,
static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr, static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr,
const char *name, const char *name,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && name != null); Assert(expr != nullptr && name != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_IDENTIFIER; expr->base.type = SCC_AST_EXPR_IDENTIFIER;
expr->identifier.name = name; expr->identifier.name = name;
expr->identifier._target = null; expr->identifier._target = nullptr;
} }
static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr, static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr,
scc_ast_type_t *type, scc_ast_type_t *type,
scc_pos_t loc) { scc_pos_t loc) {
Assert(expr != null && type != null); Assert(expr != nullptr && type != nullptr);
expr->base.loc = loc; expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_LVALUE; expr->base.type = SCC_AST_EXPR_LVALUE;
expr->lvalue.type = type; expr->lvalue.type = type;
@@ -501,7 +501,7 @@ static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr,
static inline void scc_ast_type_builtin_init(scc_ast_type_t *type, static inline void scc_ast_type_builtin_init(scc_ast_type_t *type,
scc_ast_builtin_type_t builtin, scc_ast_builtin_type_t builtin,
scc_pos_t loc) { scc_pos_t loc) {
Assert(type != null); Assert(type != nullptr);
type->base.loc = loc; type->base.loc = loc;
type->base.type = SCC_AST_TYPE_BUILTIN; type->base.type = SCC_AST_TYPE_BUILTIN;
type->builtin.type = builtin; type->builtin.type = builtin;
@@ -511,19 +511,19 @@ static inline void scc_ast_type_builtin_init(scc_ast_type_t *type,
static inline void scc_ast_type_pointer_init(scc_ast_type_t *type, static inline void scc_ast_type_pointer_init(scc_ast_type_t *type,
scc_ast_type_t *pointee, scc_ast_type_t *pointee,
scc_pos_t loc) { scc_pos_t loc) {
Assert(type != null && pointee != null); Assert(type != nullptr && pointee != nullptr);
type->base.loc = loc; type->base.loc = loc;
type->base.type = SCC_AST_TYPE_POINTER; type->base.type = SCC_AST_TYPE_POINTER;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->pointer.pointee = pointee; type->pointer.pointee = pointee;
} }
// size can be null // size can be nullptr
static inline void scc_ast_type_array_init(scc_ast_type_t *type, static inline void scc_ast_type_array_init(scc_ast_type_t *type,
scc_ast_type_t *element, scc_ast_type_t *element,
scc_ast_expr_t *size, scc_ast_expr_t *size,
scc_pos_t loc) { scc_pos_t loc) {
Assert(type != null && element != null); Assert(type != nullptr && element != nullptr);
type->base.loc = loc; type->base.loc = loc;
type->base.type = SCC_AST_TYPE_ARRAY; type->base.type = SCC_AST_TYPE_ARRAY;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
@@ -531,17 +531,17 @@ static inline void scc_ast_type_array_init(scc_ast_type_t *type,
type->array.size = size; type->array.size = size;
} }
// return_type and params can be null // return_type and params can be nullptr
static inline void scc_ast_type_function_init(scc_ast_type_t *type, static inline void scc_ast_type_function_init(scc_ast_type_t *type,
scc_ast_type_t *return_type, scc_ast_type_t *return_type,
scc_ast_decl_vec_t *params, scc_ast_decl_vec_t *params,
scc_pos_t loc) { scc_pos_t loc) {
Assert(type != null); Assert(type != nullptr);
type->base.loc = loc; type->base.loc = loc;
type->base.type = SCC_AST_TYPE_FUNCTION; type->base.type = SCC_AST_TYPE_FUNCTION;
type->function.return_type = return_type; type->function.return_type = return_type;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
if (params == null) { if (params == nullptr) {
scc_vec_init(type->function.params); scc_vec_init(type->function.params);
} else { } else {
type->function.params = *params; type->function.params = *params;
@@ -554,7 +554,7 @@ static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_decl_t *decl, scc_ast_decl_t *decl,
scc_pos_t loc) { scc_pos_t loc) {
Assert(type != null); Assert(type != nullptr);
type->base.loc = loc; type->base.loc = loc;
type->base.type = type_kind; type->base.type = type_kind;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
@@ -562,7 +562,7 @@ static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
type->record.decl = decl; type->record.decl = decl;
} }
// name and decl can be null // name and decl can be nullptr
static inline void scc_ast_type_struct_init(scc_ast_type_t *type, static inline void scc_ast_type_struct_init(scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_decl_t *decl, scc_ast_decl_t *decl,
@@ -570,7 +570,7 @@ static inline void scc_ast_type_struct_init(scc_ast_type_t *type,
_scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, decl, loc); _scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, decl, loc);
} }
// name and decl can be null // name and decl can be nullptr
static inline void scc_ast_type_union_init(scc_ast_type_t *type, static inline void scc_ast_type_union_init(scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_decl_t *decl, scc_ast_decl_t *decl,
@@ -578,7 +578,7 @@ static inline void scc_ast_type_union_init(scc_ast_type_t *type,
_scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, decl, loc); _scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, decl, loc);
} }
// name and decl can be null // name and decl can be nullptr
static inline void scc_ast_type_enum_init(scc_ast_type_t *type, static inline void scc_ast_type_enum_init(scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_decl_t *decl, scc_pos_t loc) { scc_ast_decl_t *decl, scc_pos_t loc) {
@@ -589,7 +589,7 @@ static inline void scc_ast_type_typedef_init(scc_ast_type_t *type,
const char *name, const char *name,
scc_ast_decl_t *target, scc_ast_decl_t *target,
scc_pos_t loc) { scc_pos_t loc) {
Assert(type != null && target != null); Assert(type != nullptr && target != nullptr);
type->base.loc = loc; type->base.loc = loc;
type->base.type = SCC_AST_TYPE_TYPEDEF; type->base.type = SCC_AST_TYPE_TYPEDEF;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
+3 -3
View File
@@ -269,7 +269,7 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_t *td) {
break; break;
case SCC_AST_TYPE_ARRAY: case SCC_AST_TYPE_ARRAY:
dump_child_node(td, (scc_ast_node_t *)type->array.element, dump_child_node(td, (scc_ast_node_t *)type->array.element,
type->array.size == NULL); type->array.size == nullptr);
if (type->array.size) if (type->array.size)
dump_child_node(td, (scc_ast_node_t *)type->array.size, true); dump_child_node(td, (scc_ast_node_t *)type->array.size, true);
break; break;
@@ -499,7 +499,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_t *td) {
case SCC_AST_DECL_VAR: case SCC_AST_DECL_VAR:
if (decl->var.type) { if (decl->var.type) {
dump_child_node(td, (scc_ast_node_t *)decl->var.type, dump_child_node(td, (scc_ast_node_t *)decl->var.type,
decl->var.init == NULL); decl->var.init == nullptr);
if (decl->var.init) if (decl->var.init)
dump_child_node(td, (scc_ast_node_t *)decl->var.init, true); dump_child_node(td, (scc_ast_node_t *)decl->var.init, true);
} }
@@ -507,7 +507,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_t *td) {
case SCC_AST_DECL_FUNC: case SCC_AST_DECL_FUNC:
if (decl->func.type) { if (decl->func.type) {
dump_child_node(td, (scc_ast_node_t *)decl->func.type, dump_child_node(td, (scc_ast_node_t *)decl->func.type,
decl->func.body == NULL); decl->func.body == nullptr);
if (decl->func.body) if (decl->func.body)
dump_child_node(td, (scc_ast_node_t *)decl->func.body, true); dump_child_node(td, (scc_ast_node_t *)decl->func.body, true);
} }
+1 -1
View File
@@ -130,7 +130,7 @@ static const scc_type_abi_t scc_win_x64_type_abi[] = {
.alignment = 8, .alignment = 8,
}, },
{ {
// NULL // nullptr
.ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN, .ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN,
.ir_type = SCC_IR_TYPE_unknown, .ir_type = SCC_IR_TYPE_unknown,
.size = 0, .size = 0,
+52 -41
View File
@@ -12,8 +12,8 @@ static inline void parse_lexme2const_int(const char *lexme,
scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_ast_type_t *ast_type) { scc_ast_type_t *ast_type) {
if (ctx == null || ast_type == null) { if (ctx == nullptr || ast_type == nullptr) {
LOG_ERROR("args is null"); LOG_ERROR("args is nullptr");
return 0; return 0;
} }
scc_ir_type_t ir_type; scc_ir_type_t ir_type;
@@ -42,17 +42,13 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
} }
break; break;
} }
case SCC_AST_TYPE_POINTER: { case SCC_AST_TYPE_POINTER: {
scc_ir_type_init(&ir_type, SCC_IR_TYPE_PTR); scc_ir_type_init(&ir_type, SCC_IR_TYPE_PTR);
scc_ir_type_ref_t pointee_type = scc_ir_type_ref_t pointee_type =
scc_ast2ir_type(ctx, ast_type->pointer.pointee); scc_ast2ir_type(ctx, ast_type->pointer.pointee);
ir_type.data.pointer.base = pointee_type; ir_type.data.pointer.base = pointee_type;
break; break;
} }
case SCC_AST_TYPE_ARRAY: { case SCC_AST_TYPE_ARRAY: {
scc_ir_type_init(&ir_type, SCC_IR_TYPE_ARRAY); scc_ir_type_init(&ir_type, SCC_IR_TYPE_ARRAY);
@@ -60,7 +56,6 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_ast2ir_type(ctx, ast_type->array.element); scc_ast2ir_type(ctx, ast_type->array.element);
ir_type.data.array.base = element_type; ir_type.data.array.base = element_type;
// TODO: 处理数组大小表达式
ir_type.data.array.len = 0; ir_type.data.array.len = 0;
if (ast_type->array.size) { if (ast_type->array.size) {
// TODO constant expression // TODO constant expression
@@ -73,7 +68,6 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
} }
break; break;
} }
case SCC_AST_TYPE_FUNCTION: { case SCC_AST_TYPE_FUNCTION: {
scc_ir_type_init(&ir_type, SCC_IR_TYPE_FUNC); scc_ir_type_init(&ir_type, SCC_IR_TYPE_FUNC);
@@ -98,13 +92,11 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
ir_type.data.function.params = params; ir_type.data.function.params = params;
break; break;
} }
// SCC_AST_TYPE_STRUCT, // 结构体类型 // SCC_AST_TYPE_STRUCT, // 结构体类型
// SCC_AST_TYPE_UNION, // 联合类型 // SCC_AST_TYPE_UNION, // 联合类型
// SCC_AST_TYPE_ENUM, // 枚举类型 // SCC_AST_TYPE_ENUM, // 枚举类型
case SCC_AST_TYPE_TYPEDEF: case SCC_AST_TYPE_TYPEDEF:
break; break;
default: default:
LOG_FATAL("Unsupported AST type: %d", ast_type->base.type); LOG_FATAL("Unsupported AST type: %d", ast_type->base.type);
return 0; return 0;
@@ -207,8 +199,8 @@ scc_ir_value_ref_t scc_ast2ir_logical_expr(scc_ast2ir_ctx_t *ctx,
*/ */
scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr, scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
cbool is_lvalue) { cbool is_lvalue) {
if (ctx == null || expr == null) { if (ctx == nullptr || expr == nullptr) {
LOG_ERROR("args is null"); LOG_ERROR("args is nullptr");
return 0; return 0;
} }
@@ -332,7 +324,6 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
// 创建操作节点 // 创建操作节点
return scc_ir_builder_binop(&ctx->builder, op, lhs, rhs); return scc_ir_builder_binop(&ctx->builder, op, lhs, rhs);
} }
case SCC_AST_EXPR_UNARY: { case SCC_AST_EXPR_UNARY: {
if (expr->unary.op == SCC_AST_OP_ADDRESS_OF) { if (expr->unary.op == SCC_AST_OP_ADDRESS_OF) {
return scc_ast2ir_expr(ctx, expr->unary.operand, true); return scc_ast2ir_expr(ctx, expr->unary.operand, true);
@@ -399,13 +390,13 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
LOG_FATAL("Unsupported unary operator: %d", expr->unary.op); LOG_FATAL("Unsupported unary operator: %d", expr->unary.op);
return 0; return 0;
} }
UNREACHABLE();
break;
} }
case SCC_AST_EXPR_COND: { case SCC_AST_EXPR_COND: {
TODO(); TODO();
break; break;
} }
case SCC_AST_EXPR_CALL: { case SCC_AST_EXPR_CALL: {
// 转换参数 // 转换参数
scc_ir_node_ref_vec_t args; scc_ir_node_ref_vec_t args;
@@ -430,7 +421,6 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
scc_vec_free(args); scc_vec_free(args);
return node; return node;
} }
// SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标 // SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标
// SCC_AST_EXPR_MEMBER, // 成员访问 . // SCC_AST_EXPR_MEMBER, // 成员访问 .
// SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 -> // SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 ->
@@ -440,7 +430,6 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
// SCC_AST_EXPR_COMPOUND, // 复合字面量 // SCC_AST_EXPR_COMPOUND, // 复合字面量
// SCC_AST_EXPR_LVALUE, // 右值 // SCC_AST_EXPR_LVALUE, // 右值
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin // SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
case SCC_AST_EXPR_INT_LITERAL: { case SCC_AST_EXPR_INT_LITERAL: {
// FIXME maybe using some array to int; // FIXME maybe using some array to int;
scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder); scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder);
@@ -487,9 +476,8 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
TODO(); TODO();
break; break;
} }
case SCC_AST_EXPR_IDENTIFIER: { case SCC_AST_EXPR_IDENTIFIER: {
if (expr->identifier._target == null) { if (expr->identifier._target == nullptr) {
LOG_ERROR("unknown identifier %s", expr->identifier.name); LOG_ERROR("unknown identifier %s", expr->identifier.name);
} }
// FIXME hack hashtable // FIXME hack hashtable
@@ -499,7 +487,20 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
if (is_lvalue) { if (is_lvalue) {
return in; return in;
} else { } else {
return scc_ir_builder_load(&ctx->builder, in); // 右值:如果是数组类型,退化为指针(返回地址)
scc_ir_type_t *ir_type =
scc_ir_module_get_type_by_value(ctx->builder.ctx.module, in);
Assert(ir_type->tag == SCC_IR_TYPE_PTR);
scc_ir_type_t *target_type = scc_ir_module_get_type(
ctx->builder.ctx.module, ir_type->data.pointer.base);
if (target_type->tag == SCC_IR_TYPE_ARRAY) {
// 生成 getptr 获取数组首地址
return scc_ir_builder_get_ptr(&ctx->builder, in,
SCC_IR_REF_nullptr);
} else {
// 标量类型:加载值
return scc_ir_builder_load(&ctx->builder, in);
}
} }
} }
@@ -516,7 +517,7 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
* @param stmt * @param stmt
*/ */
void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) { void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
if (stmt == null) { if (stmt == nullptr) {
return; return;
} }
@@ -537,12 +538,10 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
} }
break; break;
} }
case SCC_AST_STMT_EXPR: { case SCC_AST_STMT_EXPR: {
scc_ast2ir_expr(ctx, stmt->expr.expr, false); scc_ast2ir_expr(ctx, stmt->expr.expr, false);
break; break;
} }
case SCC_AST_STMT_IF: { case SCC_AST_STMT_IF: {
/* /*
branch cond branch cond
@@ -580,7 +579,6 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_set_current_bblock(&ctx->builder, merge_block); scc_ir_builder_set_current_bblock(&ctx->builder, merge_block);
break; break;
} }
case SCC_AST_STMT_WHILE: { case SCC_AST_STMT_WHILE: {
scc_ir_bblock_ref_t cond_block = scc_ir_bblock_ref_t cond_block =
scc_ir_builder_bblock(&ctx->builder, "while_cond"); scc_ir_builder_bblock(&ctx->builder, "while_cond");
@@ -603,7 +601,6 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_set_current_bblock(&ctx->builder, exit_block); scc_ir_builder_set_current_bblock(&ctx->builder, exit_block);
break; break;
} }
case SCC_AST_STMT_DO_WHILE: { case SCC_AST_STMT_DO_WHILE: {
scc_ir_bblock_ref_t cond_block = scc_ir_bblock_ref_t cond_block =
scc_ir_builder_bblock(&ctx->builder, "do_while_cond"); scc_ir_builder_bblock(&ctx->builder, "do_while_cond");
@@ -626,7 +623,6 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_set_current_bblock(&ctx->builder, exit_block); scc_ir_builder_set_current_bblock(&ctx->builder, exit_block);
break; break;
} }
case SCC_AST_STMT_FOR: { case SCC_AST_STMT_FOR: {
scc_ir_bblock_ref_t cond_block = scc_ir_bblock_ref_t cond_block =
scc_ir_builder_bblock(&ctx->builder, "for_while_cond"); scc_ir_builder_bblock(&ctx->builder, "for_while_cond");
@@ -670,7 +666,6 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_set_current_bblock(&ctx->builder, exit_block); scc_ir_builder_set_current_bblock(&ctx->builder, exit_block);
break; break;
} }
// SCC_AST_STMT_SWITCH, // switch 语句 // SCC_AST_STMT_SWITCH, // switch 语句
// SCC_AST_STMT_CASE, // case 语句 // SCC_AST_STMT_CASE, // case 语句
// SCC_AST_STMT_DEFAULT, // default 语句 // SCC_AST_STMT_DEFAULT, // default 语句
@@ -701,7 +696,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
* @param decl * @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) {
if (ctx == null || decl == null) { if (ctx == nullptr || decl == nullptr) {
LOG_ERROR("Invalid argument"); LOG_ERROR("Invalid argument");
return; return;
} }
@@ -709,11 +704,10 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
switch (decl->base.type) { switch (decl->base.type) {
case SCC_AST_DECL_VAR: { case SCC_AST_DECL_VAR: {
// 转换类型 // 转换类型
scc_ir_type_ref_t ir_type = scc_ast2ir_type(ctx, decl->var.type); 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_value_ref_t alloc_val_node =
scc_ir_builder_alloca(&ctx->builder, ir_type, decl->name); scc_ir_builder_alloca(&ctx->builder, ir_type_ref, decl->name);
scc_hashtable_set(&ctx->decl2ir_ref, decl, scc_hashtable_set(&ctx->decl2ir_ref, decl,
(void *)(usize)alloc_val_node); (void *)(usize)alloc_val_node);
@@ -724,10 +718,30 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
} }
scc_ir_value_ref_t init_val_node = scc_ir_value_ref_t init_val_node =
scc_ast2ir_expr(ctx, decl->var.init, false); scc_ast2ir_expr(ctx, decl->var.init, false);
// FIXME array auto calucate size
scc_ir_type_t *ir_type =
scc_ir_module_get_type(ctx->builder.ctx.module, ir_type_ref);
if (ir_type->tag == SCC_IR_TYPE_ARRAY && ir_type->data.array.len == 0) {
scc_ast_expr_t *init_expr = decl->var.init;
if (init_expr->base.type == SCC_AST_EXPR_COMPOUND) {
Panic("TODO: init_expr->base.type == SCC_AST_EXPR_COMPOUND");
} else if (init_expr->base.type == SCC_AST_EXPR_STRING_LITERAL) {
ir_type->data.array.len =
scc_strlen(init_expr->literal.lexme) + 1;
scc_ir_const_int_t len = {.int64 = ir_type->data.array.len};
scc_ir_value_ref_t len_ref = scc_ir_builder_const_int(
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), len);
scc_ir_builder_builtin_memcpy(&ctx->builder, alloc_val_node,
init_val_node, len_ref);
} else {
Panic("unknown init expr in array decl");
}
}
scc_ir_builder_store(&ctx->builder, alloc_val_node, init_val_node); scc_ir_builder_store(&ctx->builder, alloc_val_node, init_val_node);
break; break;
} }
case SCC_AST_DECL_FUNC: { case SCC_AST_DECL_FUNC: {
scc_ir_type_ref_t func_type_ref = scc_ast2ir_type(ctx, decl->func.type); scc_ir_type_ref_t func_type_ref = scc_ast2ir_type(ctx, decl->func.type);
scc_ir_func_ref_t func_ref = scc_ir_func_ref_t func_ref =
@@ -739,15 +753,15 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
(void *)(usize)func_ref); (void *)(usize)func_ref);
} }
if (decl->func.body == null) { if (decl->func.body == nullptr) {
// function decl // function decl
break; break;
} }
scc_ir_builder_begin_func(&ctx->builder, func_ref, null); scc_ir_builder_begin_func(&ctx->builder, func_ref, nullptr);
scc_ir_func_t *func = scc_ir_func_t *func =
scc_ir_module_get_func(ctx->builder.ctx.module, func_ref); scc_ir_module_get_func(ctx->builder.ctx.module, func_ref);
Assert(func != null); Assert(func != nullptr);
scc_ir_builder_begin_bblock(&ctx->builder, "entry"); scc_ir_builder_begin_bblock(&ctx->builder, "entry");
scc_vec_foreach(decl->func.type->function.params, i) { scc_vec_foreach(decl->func.type->function.params, i) {
scc_ast_decl_t *param = scc_ast_decl_t *param =
@@ -756,7 +770,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
scc_ir_value_ref_t param_node_ref = scc_vec_at(func->params, i); scc_ir_value_ref_t param_node_ref = scc_vec_at(func->params, i);
scc_ir_value_t *param_node = scc_ir_module_get_value( scc_ir_value_t *param_node = scc_ir_module_get_value(
ctx->builder.ctx.module, param_node_ref); ctx->builder.ctx.module, param_node_ref);
Assert(param_node != null); Assert(param_node != nullptr);
param_node->name = param->name; param_node->name = param->name;
scc_hashtable_set(&ctx->decl2ir_ref, param, scc_hashtable_set(&ctx->decl2ir_ref, param,
(void *)(usize)param_node_ref); (void *)(usize)param_node_ref);
@@ -769,7 +783,6 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
scc_ir_builder_end_func(&ctx->builder); scc_ir_builder_end_func(&ctx->builder);
break; break;
} }
case SCC_AST_DECL_LIST: { case SCC_AST_DECL_LIST: {
scc_vec_foreach(decl->list.vars, i) { scc_vec_foreach(decl->list.vars, i) {
scc_ast_decl_t *sub_decl = scc_vec_at(decl->list.vars, i); scc_ast_decl_t *sub_decl = scc_vec_at(decl->list.vars, i);
@@ -784,11 +797,9 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
break; break;
case SCC_AST_DECL_UNION: case SCC_AST_DECL_UNION:
break; break;
case SCC_AST_DECL_ENUM: case SCC_AST_DECL_ENUM:
case SCC_AST_DECL_TYPEDEF: case SCC_AST_DECL_TYPEDEF:
break; break;
default: default:
LOG_FATAL("Unsupported declaration type: %d", decl->base.type); LOG_FATAL("Unsupported declaration type: %d", decl->base.type);
break; break;
@@ -797,7 +808,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx, void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx,
scc_ast_translation_unit_t *tu) { scc_ast_translation_unit_t *tu) {
Assert(ctx != null && tu != null); Assert(ctx != nullptr && tu != nullptr);
scc_vec_foreach(tu->declarations, i) { scc_vec_foreach(tu->declarations, i) {
scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i); scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i);
@@ -812,7 +823,7 @@ static int scc_cmp_node(const void *key1, const void *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_type_abi_t *abi,
scc_ir_cprog_t *cprog) { scc_ir_cprog_t *cprog) {
Assert(ctx != null); Assert(ctx != nullptr);
ctx->abi = abi; ctx->abi = abi;
scc_ir_builder_init(&ctx->builder, cprog); scc_ir_builder_init(&ctx->builder, cprog);
scc_hashtable_init(&ctx->decl2ir_ref, scc_hash_node, scc_cmp_node); scc_hashtable_init(&ctx->decl2ir_ref, scc_hash_node, scc_cmp_node);
+32 -21
View File
@@ -68,15 +68,32 @@ SCC_IR_BUILDER_TYPE_FUNC(f32)
SCC_IR_BUILDER_TYPE_FUNC(f64) SCC_IR_BUILDER_TYPE_FUNC(f64)
SCC_IR_BUILDER_TYPE_FUNC(f128) SCC_IR_BUILDER_TYPE_FUNC(f128)
static inline scc_ir_value_ref_t
scc_ir_builder_builtin_memcpy(scc_ir_builder_t *builder,
scc_ir_value_ref_t dest, scc_ir_value_ref_t src,
scc_ir_value_ref_t len) {
scc_ir_value_t value;
scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_BUILTIN);
value.type = scc_ir_builder_type_void(builder); // memcpy 返回 void*
value.data.builtin.tag = SCC_IR_BUILTIN_TAG_MEMCPY;
value.data.builtin.func.memcpy.dest = dest;
value.data.builtin.func.memcpy.src = src;
value.data.builtin.func.memcpy.size = len;
scc_ir_value_ref_t ref =
scc_ir_module_add_value(builder->ctx.module, &value);
scc_ir_builder_add_instr(builder, ref);
return ref;
}
// TODO // TODO
static inline scc_ir_value_ref_t static inline scc_ir_value_ref_t
scc_ir_builder_const_int(scc_ir_builder_t *builder, scc_ir_type_ref_t type, scc_ir_builder_const_int(scc_ir_builder_t *builder, scc_ir_type_ref_t type,
scc_ir_const_int_t value) { scc_ir_const_int_t val) {
scc_ir_value_t node; scc_ir_value_t value;
scc_ir_node_init(&node, null, SCC_IR_VALUE_TAG_CONST_INT); scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_CONST_INT);
node.data.const_int = value; value.data.const_int = val;
node.type = type; value.type = type;
return scc_ir_module_add_value(&builder->cprog->module, &node); return scc_ir_module_add_value(&builder->cprog->module, &value);
} }
static inline scc_ir_value_ref_t static inline scc_ir_value_ref_t
@@ -86,17 +103,11 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
scc_ir_type_t array_type = { scc_ir_type_t array_type = {
.tag = SCC_IR_TYPE_ARRAY, .tag = SCC_IR_TYPE_ARRAY,
.data.array.base = u8_type, .data.array.base = u8_type,
.data.array.len = len - 1, // 包含 null 结尾 .data.array.len = len - 1, // 包含 nullptr 结尾
}; };
scc_ir_type_ref_t array_type_ref = scc_ir_type_ref_t array_type_ref =
scc_ir_ctx_get_type(&builder->ctx, &array_type); scc_ir_ctx_get_type(&builder->ctx, &array_type);
// 2. 创建指针类型:指向 array_type
scc_ir_type_t ptr_type = {.tag = SCC_IR_TYPE_PTR,
.data.pointer.base = u8_type};
scc_ir_type_ref_t ptr_type_ref =
scc_ir_ctx_get_type(&builder->ctx, &ptr_type);
// 5. 创建聚合节点 // 5. 创建聚合节点
scc_ir_value_t const_array_value = { scc_ir_value_t const_array_value = {
.tag = SCC_IR_VALUE_TAG_CONST_ARRAY, .tag = SCC_IR_VALUE_TAG_CONST_ARRAY,
@@ -111,10 +122,10 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
} }
buff[len - 2] = '\0'; 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.elements,
buff, len - 1); (u8 *)buff, len - 1);
scc_ir_value_ref_t const_array_ref = scc_ir_value_ref_t const_array_ref =
scc_ir_module_add_value(builder->ctx.module, &const_array_value); scc_ir_module_add_value(builder->ctx.module, &const_array_value);
Assert(const_array_ref != SCC_IR_REF_NULL); Assert(const_array_ref != SCC_IR_REF_nullptr);
// 3. 创建全局变量节点,类型为指针,初始值指向常量数组 // 3. 创建全局变量节点,类型为指针,初始值指向常量数组
char *name = scc_malloc(32); char *name = scc_malloc(32);
@@ -124,7 +135,7 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
builder->ctx.module, &(scc_ir_value_t){ builder->ctx.module, &(scc_ir_value_t){
.name = name, .name = name,
.tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC, .tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC,
.type = ptr_type_ref, .type = array_type_ref,
.data.global_alloc.value = const_array_ref, .data.global_alloc.value = const_array_ref,
}); });
scc_snprintf(name, 32, "$G%u", global_value_ref); scc_snprintf(name, 32, "$G%u", global_value_ref);
@@ -135,7 +146,7 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
builder->ctx.module, &(scc_ir_value_t){ builder->ctx.module, &(scc_ir_value_t){
.tag = SCC_IR_VALUE_TAG_GET_PTR, .tag = SCC_IR_VALUE_TAG_GET_PTR,
.data.get_ptr.src_addr = global_value_ref, .data.get_ptr.src_addr = global_value_ref,
.data.get_ptr.index = SCC_IR_VALUE_TAG_NULL, .data.get_ptr.index = SCC_IR_VALUE_TAG_NULLPTR,
}); });
scc_ir_builder_add_instr(builder, pointer_to_global_value); scc_ir_builder_add_instr(builder, pointer_to_global_value);
return pointer_to_global_value; return pointer_to_global_value;
@@ -144,7 +155,7 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
/** /**
* @brief 开始构建函数 * @brief 开始构建函数
* @param func_ref 函数引用 * @param func_ref 函数引用
* @param param_names 参数名列表(可为NULL) * @param param_names 参数名列表(可为nullptr)
* @return void * @return void
*/ */
void scc_ir_builder_begin_func(scc_ir_builder_t *builder, void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
@@ -164,7 +175,7 @@ scc_ir_func_ref_t scc_ir_builder_current_func(scc_ir_builder_t *builder);
/** /**
* @brief 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。 * @brief 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。
* @param builder IR构建器 * @param builder IR构建器
* @param label 基本块标签(可为 NULL,自动生成) * @param label 基本块标签(可为 nullptr,自动生成)
* @return 新基本块的引用 * @return 新基本块的引用
*/ */
scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder, scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder,
@@ -172,7 +183,7 @@ scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder,
/** /**
* @brief 开始构建新的基本块 * @brief 开始构建新的基本块
* @param label 基本块标签(可为NULL,自动生成) * @param label 基本块标签(可为nullptr,自动生成)
* @return 基本块引用 * @return 基本块引用
*/ */
scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder, scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder,
@@ -193,7 +204,7 @@ void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder,
/** /**
* @brief 创建alloca指令(在当前基本块中) * @brief 创建alloca指令(在当前基本块中)
* @param type 分配的类型 * @param type 分配的类型
* @param name 变量名(可为NULL) * @param name 变量名(可为nullptr)
*/ */
scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
scc_ir_type_ref_t type, scc_ir_type_ref_t type,
+51 -2
View File
@@ -3,7 +3,7 @@
#include <scc_core.h> #include <scc_core.h>
#define SCC_IR_REF_NULL 0 #define SCC_IR_REF_nullptr 0
typedef unsigned int ir_handle_t; typedef unsigned int ir_handle_t;
typedef const char *scc_ir_label_t; typedef const char *scc_ir_label_t;
@@ -86,7 +86,8 @@ struct scc_ir_func {
}; };
typedef enum scc_ir_value_tag { typedef enum scc_ir_value_tag {
SCC_IR_VALUE_TAG_NULL, SCC_IR_VALUE_TAG_NULLPTR,
SCC_IR_VALUE_TAG_BUILTIN,
SCC_IR_VALUE_TAG_CONST_INT, SCC_IR_VALUE_TAG_CONST_INT,
SCC_IR_VALUE_TAG_CONST_UINT, SCC_IR_VALUE_TAG_CONST_UINT,
SCC_IR_VALUE_TAG_CONST_FLOAT, SCC_IR_VALUE_TAG_CONST_FLOAT,
@@ -175,12 +176,60 @@ typedef union {
u8 float_any[16]; u8 float_any[16];
} scc_ir_const_float_t; } scc_ir_const_float_t;
typedef enum {
SCC_IR_BUILTIN_TAG_MEMCPY,
SCC_IR_BUILTIN_TAG_MEMSET,
SCC_IR_BUILTIN_TAG_VA_START,
SCC_IR_BUILTIN_TAG_VA_ARG,
SCC_IR_BUILTIN_TAG_VA_END,
SCC_IR_BUILTIN_TAG_VA_COPY,
} scc_ir_builtin_tag_t;
typedef struct {
scc_ir_builtin_tag_t tag;
union {
struct {
scc_ir_value_ref_t dest;
scc_ir_value_ref_t src;
scc_ir_value_ref_t size;
} memcpy;
struct {
scc_ir_value_ref_t dest;
scc_ir_value_ref_t value;
scc_ir_value_ref_t size;
} memset;
struct {
scc_ir_value_ref_t ap; // va_list 的地址(i8* 或 struct*)
scc_ir_value_ref_t last; // 最后一个固定参数的引用(用于 va_start)
} va_start;
struct {
scc_ir_value_ref_t ap; // va_list 的地址
scc_ir_type_ref_t type; // 要提取的参数的类型
} va_arg;
struct {
scc_ir_value_ref_t ap; // va_list 的地址
} va_end;
struct {
scc_ir_value_ref_t dest; // 目标 va_list 地址
scc_ir_value_ref_t src; // 源 va_list 地址
} va_copy;
} func;
} scc_ir_builtin_t;
typedef enum {
SCC_IR_LINKAGE_EXTERNAL,
SCC_IR_LINKAGE_INTERNAL,
SCC_IR_LINKAGE_PRIVATE,
SCC_IR_LINKAGE_WEAK,
} scc_ir_linkage_t;
struct scc_ir_value { struct scc_ir_value {
scc_ir_type_ref_t type; scc_ir_type_ref_t type;
scc_ir_label_t name; scc_ir_label_t name;
scc_ir_node_ref_vec_t used_by; scc_ir_node_ref_vec_t used_by;
scc_ir_value_tag_t tag; scc_ir_value_tag_t tag;
union { union {
scc_ir_builtin_t builtin;
scc_ir_const_int_t const_int; scc_ir_const_int_t const_int;
scc_ir_const_uint_t const_uint; scc_ir_const_uint_t const_uint;
scc_ir_const_float_t const_float; scc_ir_const_float_t const_float;
+1 -1
View File
@@ -42,7 +42,7 @@ scc_ir_func_t *scc_ir_module_get_func(scc_ir_module_t *ctx,
static inline scc_ir_type_t * static inline scc_ir_type_t *
scc_ir_module_get_type_by_value(scc_ir_module_t *ctx, scc_ir_value_ref_t ref) { scc_ir_module_get_type_by_value(scc_ir_module_t *ctx, scc_ir_value_ref_t ref) {
scc_ir_value_t *value = scc_ir_module_get_value(ctx, ref); scc_ir_value_t *value = scc_ir_module_get_value(ctx, ref);
Assert(value != null); Assert(value != nullptr);
return scc_ir_module_get_type(ctx, value->type); return scc_ir_module_get_type(ctx, value->type);
} }
+3 -3
View File
@@ -8,8 +8,8 @@ void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag);
void scc_ir_bblock_init(scc_ir_bblock_t *in, const char *label); void scc_ir_bblock_init(scc_ir_bblock_t *in, const char *label);
void scc_ir_func_init(scc_ir_func_t *in, const char *name); void scc_ir_func_init(scc_ir_func_t *in, const char *name);
// node name can be null ptr // node name can be nullptr ptr
void scc_ir_node_init(scc_ir_value_t *in, const char *name, void scc_ir_value_init(scc_ir_value_t *in, const char *name,
scc_ir_value_tag_t tag); scc_ir_value_tag_t tag);
#endif /* __SCC_IR_H__ */ #endif /* __SCC_IR_H__ */
+50 -50
View File
@@ -4,8 +4,8 @@
#define GET_MODULE(builder) (&(builder->cprog->module)) #define GET_MODULE(builder) (&(builder->cprog->module))
void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog) { void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog) {
builder->current_bblock = SCC_IR_REF_NULL; builder->current_bblock = SCC_IR_REF_nullptr;
builder->current_func = SCC_IR_REF_NULL; builder->current_func = SCC_IR_REF_nullptr;
builder->cprog = cprog; builder->cprog = cprog;
scc_ir_ctx_init(&builder->ctx, GET_MODULE(builder)); scc_ir_ctx_init(&builder->ctx, GET_MODULE(builder));
@@ -40,12 +40,12 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
scc_ir_type_t *func_type = scc_ir_type_t *func_type =
scc_ir_module_get_type(GET_MODULE(builder), func_ptr->type); scc_ir_module_get_type(GET_MODULE(builder), func_ptr->type);
if (func_type == null || func_type->tag != SCC_IR_TYPE_FUNC) { if (func_type == nullptr || func_type->tag != SCC_IR_TYPE_FUNC) {
LOG_ERROR("Invalid function type"); LOG_ERROR("Invalid function type");
return; return;
} }
if (func_ptr == null) { if (func_ptr == nullptr) {
LOG_ERROR("Invalid function reference"); LOG_ERROR("Invalid function reference");
return; return;
} }
@@ -57,7 +57,7 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
} }
scc_ir_type_ref_vec_t params = func_type->data.function.params; scc_ir_type_ref_vec_t params = func_type->data.function.params;
func_type = null; func_type = nullptr;
scc_vec_foreach(params, i) { scc_vec_foreach(params, i) {
scc_ir_type_ref_t param_type = scc_vec_at(params, i); scc_ir_type_ref_t param_type = scc_vec_at(params, i);
@@ -67,7 +67,7 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
GET_MODULE(builder), GET_MODULE(builder),
&(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR, &(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR,
.data.pointer.base = param_type}); .data.pointer.base = param_type});
param_node.name = param_names ? param_names[i] : null; param_node.name = param_names ? param_names[i] : nullptr;
param_node.data.arg_ref.idx = i; param_node.data.arg_ref.idx = i;
scc_vec_init(param_node.used_by); scc_vec_init(param_node.used_by);
@@ -81,7 +81,7 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder,
void scc_ir_builder_end_func(scc_ir_builder_t *builder) { void scc_ir_builder_end_func(scc_ir_builder_t *builder) {
scc_ir_func_t *func_ptr = scc_ir_func_t *func_ptr =
scc_ir_module_get_func(GET_MODULE(builder), builder->current_func); scc_ir_module_get_func(GET_MODULE(builder), builder->current_func);
if (func_ptr == null) { if (func_ptr == nullptr) {
LOG_FATAL("Invalid function reference"); LOG_FATAL("Invalid function reference");
return; return;
} }
@@ -157,30 +157,30 @@ scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
&(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR, .data.pointer.base = type}); &(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR, .data.pointer.base = type});
alloc_node.name = name; alloc_node.name = name;
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &alloc_node); scc_ir_module_add_value(GET_MODULE(builder), &alloc_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder,
scc_ir_type_ref_t type, scc_ir_type_ref_t type,
const char *name, const char *name,
usize arg_idx) { usize arg_idx) {
scc_ir_value_t node = {0}; scc_ir_value_t value = {0};
node.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF; value.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF;
node.type = type; value.type = type;
node.name = name; value.name = name;
node.data.arg_ref.idx = arg_idx; value.data.arg_ref.idx = arg_idx;
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &node); scc_ir_module_add_value(GET_MODULE(builder), &value);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
@@ -200,31 +200,31 @@ scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
} }
} }
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &load_node); scc_ir_module_add_value(GET_MODULE(builder), &load_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder,
scc_ir_value_ref_t target, scc_ir_value_ref_t target,
scc_ir_value_ref_t value) { scc_ir_value_ref_t value) {
Assert(target != SCC_IR_REF_NULL && value != SCC_IR_REF_NULL); Assert(target != SCC_IR_REF_nullptr && value != SCC_IR_REF_nullptr);
scc_ir_value_t store_node = {0}; scc_ir_value_t store_node = {0};
store_node.tag = SCC_IR_VALUE_TAG_STORE; store_node.tag = SCC_IR_VALUE_TAG_STORE;
store_node.data.store.target = target; store_node.data.store.target = target;
store_node.data.store.value = value; store_node.data.store.value = value;
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &store_node); scc_ir_module_add_value(GET_MODULE(builder), &store_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_get_ptr(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_get_ptr(scc_ir_builder_t *builder,
@@ -242,13 +242,13 @@ scc_ir_value_ref_t scc_ir_builder_get_ptr(scc_ir_builder_t *builder,
get_ptr_node.type = src_node->type; get_ptr_node.type = src_node->type;
} }
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &get_ptr_node); scc_ir_module_add_value(GET_MODULE(builder), &get_ptr_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder,
@@ -268,13 +268,13 @@ scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder,
binop_node.type = lhs_node->type; binop_node.type = lhs_node->type;
} }
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &binop_node); scc_ir_module_add_value(GET_MODULE(builder), &binop_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder,
@@ -291,13 +291,13 @@ scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder,
cmp_node.type = cmp_node.type =
0; // FIXME scc_ir_module_get_builtin_i32(GET_MODULE(builder)); 0; // FIXME scc_ir_module_get_builtin_i32(GET_MODULE(builder));
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &cmp_node); scc_ir_module_add_value(GET_MODULE(builder), &cmp_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder,
@@ -306,13 +306,13 @@ scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder,
jump_node.tag = SCC_IR_VALUE_TAG_JUMP; jump_node.tag = SCC_IR_VALUE_TAG_JUMP;
jump_node.data.jump.target_bblock = target; jump_node.data.jump.target_bblock = target;
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &jump_node); scc_ir_module_add_value(GET_MODULE(builder), &jump_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder,
@@ -325,13 +325,13 @@ scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder,
branch_node.data.branch.true_bblock = true_target; branch_node.data.branch.true_bblock = true_target;
branch_node.data.branch.false_bblock = false_target; branch_node.data.branch.false_bblock = false_target;
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &branch_node); scc_ir_module_add_value(GET_MODULE(builder), &branch_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder,
@@ -358,13 +358,13 @@ scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder,
} }
} }
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &call_node); scc_ir_module_add_value(GET_MODULE(builder), &call_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder, scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder,
@@ -373,13 +373,13 @@ scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder,
ret_node.tag = SCC_IR_VALUE_TAG_RET; ret_node.tag = SCC_IR_VALUE_TAG_RET;
ret_node.data.ret.ret_val = value; ret_node.data.ret.ret_val = value;
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &ret_node); scc_ir_module_add_value(GET_MODULE(builder), &ret_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) { scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) {
@@ -387,10 +387,10 @@ scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) {
ret_node.tag = SCC_IR_VALUE_TAG_RET; ret_node.tag = SCC_IR_VALUE_TAG_RET;
ret_node.data.ret.ret_val = 0; // 无返回值 ret_node.data.ret.ret_val = 0; // 无返回值
scc_ir_value_ref_t node_ref = scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &ret_node); scc_ir_module_add_value(GET_MODULE(builder), &ret_node);
// 添加到当前基本块 // 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref); scc_ir_builder_add_instr(builder, value_ref);
return node_ref; return value_ref;
} }
+1 -4
View File
@@ -88,21 +88,17 @@ static int cmp_type(const void *_key1, const void *_key2) {
return 0; // 基本类型,tag相同即可 return 0; // 基本类型,tag相同即可
case SCC_IR_TYPE_PTR: case SCC_IR_TYPE_PTR:
return key1->data.pointer.base != key2->data.pointer.base; return key1->data.pointer.base != key2->data.pointer.base;
case SCC_IR_TYPE_ARRAY: case SCC_IR_TYPE_ARRAY:
return (key1->data.array.base != key2->data.array.base) || return (key1->data.array.base != key2->data.array.base) ||
(key1->data.array.len != key2->data.array.len); (key1->data.array.len != key2->data.array.len);
case SCC_IR_TYPE_FUNC: { case SCC_IR_TYPE_FUNC: {
if (key1->data.function.ret_type != key2->data.function.ret_type) { if (key1->data.function.ret_type != key2->data.function.ret_type) {
return 1; return 1;
} }
if (key1->data.function.params.size != if (key1->data.function.params.size !=
key2->data.function.params.size) { key2->data.function.params.size) {
return 1; return 1;
} }
for (usize i = 0; i < key1->data.function.params.size; i++) { for (usize i = 0; i < key1->data.function.params.size; i++) {
if (key1->data.function.params.data[i] != if (key1->data.function.params.data[i] !=
key2->data.function.params.data[i]) { key2->data.function.params.data[i]) {
@@ -136,6 +132,7 @@ void scc_ir_ctx_drop(scc_ir_ctx_t *ctx) {
scc_ir_type_ref_t scc_ir_ctx_get_type(scc_ir_ctx_t *ctx, scc_ir_type_ref_t scc_ir_ctx_get_type(scc_ir_ctx_t *ctx,
const scc_ir_type_t *type_desc) { const scc_ir_type_t *type_desc) {
Assert(type_desc->tag != SCC_IR_TYPE_unknown);
// 先查哈希表 // 先查哈希表
void *found = scc_hashtable_get(&ctx->type_uniquing, (void *)type_desc); void *found = scc_hashtable_get(&ctx->type_uniquing, (void *)type_desc);
if (found) { if (found) {
+158 -127
View File
@@ -6,7 +6,8 @@
static const char *get_node_type_str(scc_ir_value_tag_t tag) { static const char *get_node_type_str(scc_ir_value_tag_t tag) {
static const char *node_types[] = { static const char *node_types[] = {
[SCC_IR_VALUE_TAG_NULL] = "Null", [SCC_IR_VALUE_TAG_NULLPTR] = "NullPtr",
[SCC_IR_VALUE_TAG_BUILTIN] = "Builtin",
[SCC_IR_VALUE_TAG_CONST_INT] = "ConstInt", [SCC_IR_VALUE_TAG_CONST_INT] = "ConstInt",
[SCC_IR_VALUE_TAG_CONST_UINT] = "ConstUint", [SCC_IR_VALUE_TAG_CONST_UINT] = "ConstUint",
[SCC_IR_VALUE_TAG_CONST_FLOAT] = "ConstFloat", [SCC_IR_VALUE_TAG_CONST_FLOAT] = "ConstFloat",
@@ -81,56 +82,57 @@ static inline void dump_child_node_ref(scc_ir_dump_ctx_t *ctx,
} }
static void dump_const_int_node(scc_ir_dump_ctx_t *ctx, static void dump_const_int_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *node) { const scc_ir_value_t *value) {
scc_tree_dump_push(ctx->dump_ctx, true); scc_tree_dump_push(ctx->dump_ctx, true);
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_value(ctx->dump_ctx, "%d", node->data.const_int.int32); scc_tree_dump_value(ctx->dump_ctx, "%d", value->data.const_int.int32);
scc_tree_dump_pop(ctx->dump_ctx); scc_tree_dump_pop(ctx->dump_ctx);
} }
static void dump_op_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *node) { static void dump_op_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *value) {
scc_tree_dump_push(ctx->dump_ctx, false); scc_tree_dump_push(ctx->dump_ctx, false);
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "op: "); scc_tree_dump_node(ctx->dump_ctx, "op: ");
scc_tree_dump_value(ctx->dump_ctx, "%s", get_op_str(node->data.op.op)); scc_tree_dump_value(ctx->dump_ctx, "%s", get_op_str(value->data.op.op));
scc_tree_dump_pop(ctx->dump_ctx); scc_tree_dump_pop(ctx->dump_ctx);
if (node->data.op.lhs) if (value->data.op.lhs)
dump_child_node_ref(ctx, node->data.op.lhs, dump_child_node_ref(ctx, value->data.op.lhs,
node->data.op.rhs ? false : true); value->data.op.rhs ? false : true);
if (node->data.op.rhs) if (value->data.op.rhs)
dump_child_node_ref(ctx, node->data.op.rhs, true); dump_child_node_ref(ctx, value->data.op.rhs, true);
} }
static void dump_load_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *node) { static void dump_load_node(scc_ir_dump_ctx_t *ctx,
if (node->data.load.target) const scc_ir_value_t *value) {
dump_child_node_ref(ctx, node->data.load.target, true); if (value->data.load.target)
dump_child_node_ref(ctx, value->data.load.target, true);
} }
static void dump_store_node(scc_ir_dump_ctx_t *ctx, static void dump_store_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *node) { const scc_ir_value_t *value) {
if (node->data.store.target) if (value->data.store.target)
dump_child_node_ref(ctx, node->data.store.target, false); dump_child_node_ref(ctx, value->data.store.target, false);
if (node->data.store.value) if (value->data.store.value)
dump_child_node_ref(ctx, node->data.store.value, true); dump_child_node_ref(ctx, value->data.store.value, true);
} }
static void dump_get_ptr_node(scc_ir_dump_ctx_t *ctx, static void dump_get_ptr_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *node) { const scc_ir_value_t *value) {
if (node->data.get_ptr.src_addr) if (value->data.get_ptr.src_addr)
dump_child_node_ref(ctx, node->data.get_ptr.src_addr, false); dump_child_node_ref(ctx, value->data.get_ptr.src_addr, false);
if (node->data.get_ptr.index) if (value->data.get_ptr.index)
dump_child_node_ref(ctx, node->data.get_ptr.index, true); dump_child_node_ref(ctx, value->data.get_ptr.index, true);
} }
static void dump_branch_node(scc_ir_dump_ctx_t *ctx, static void dump_branch_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *node) { const scc_ir_value_t *value) {
if (node->data.branch.cond) if (value->data.branch.cond)
dump_child_node_ref(ctx, node->data.branch.cond, false); dump_child_node_ref(ctx, value->data.branch.cond, false);
if (node->data.branch.true_bblock) { if (value->data.branch.true_bblock) {
scc_ir_bblock_t *true_bblock = scc_ir_module_get_bblock( scc_ir_bblock_t *true_bblock = scc_ir_module_get_bblock(
GET_MODULE(ctx), node->data.branch.true_bblock); GET_MODULE(ctx), value->data.branch.true_bblock);
if (true_bblock) { if (true_bblock) {
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "TrueBlock: "); scc_tree_dump_node(ctx->dump_ctx, "TrueBlock: ");
@@ -139,9 +141,9 @@ static void dump_branch_node(scc_ir_dump_ctx_t *ctx,
: "<unnamed>"); : "<unnamed>");
} }
} }
if (node->data.branch.false_bblock) { if (value->data.branch.false_bblock) {
scc_ir_bblock_t *false_bblock = scc_ir_module_get_bblock( scc_ir_bblock_t *false_bblock = scc_ir_module_get_bblock(
GET_MODULE(ctx), node->data.branch.false_bblock); GET_MODULE(ctx), value->data.branch.false_bblock);
if (false_bblock) { if (false_bblock) {
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "FalseBlock: "); scc_tree_dump_node(ctx->dump_ctx, "FalseBlock: ");
@@ -152,45 +154,47 @@ static void dump_branch_node(scc_ir_dump_ctx_t *ctx,
} }
} }
static void dump_jump_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *node) { static void dump_jump_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *value) {
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
if (node->data.jump.target_bblock) { if (value->data.jump.target_bblock) {
scc_ir_bblock_t *target = scc_ir_module_get_bblock( scc_ir_bblock_t *target = scc_ir_module_get_bblock(
GET_MODULE(ctx), node->data.jump.target_bblock); GET_MODULE(ctx), value->data.jump.target_bblock);
if (target) if (target)
scc_tree_dump_value(ctx->dump_ctx, "to '%s'", scc_tree_dump_value(ctx->dump_ctx, "to '%s'",
target->label ? target->label : "<unnamed>"); target->label ? target->label : "<unnamed>");
else else
scc_tree_dump_value(ctx->dump_ctx, "to invalid block"); scc_tree_dump_value(ctx->dump_ctx, "to invalid block");
} else { } else {
scc_tree_dump_value(ctx->dump_ctx, "to NULL"); scc_tree_dump_value(ctx->dump_ctx, "to nullptr");
} }
} }
static void dump_call_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *node) { static void dump_call_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *value) {
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
if (node->data.call.callee) { if (value->data.call.callee) {
scc_ir_func_t *callee = scc_ir_func_t *callee =
scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee); scc_ir_module_get_func(GET_MODULE(ctx), value->data.call.callee);
scc_tree_dump_value(ctx->dump_ctx, "func='%s'", scc_tree_dump_value(ctx->dump_ctx, "func='%s'",
callee ? (callee->name ? callee->name : "<unnamed>") callee ? (callee->name ? callee->name : "<unnamed>")
: "<invalid>"); : "<invalid>");
} else { } else {
scc_tree_dump_value(ctx->dump_ctx, "func=NULL"); scc_tree_dump_value(ctx->dump_ctx, "func=nullptr");
} }
for (usize i = 0; i < scc_vec_size(node->data.call.args); i++) { for (usize i = 0; i < scc_vec_size(value->data.call.args); i++) {
cbool is_last = (i + 1 == scc_vec_size(node->data.call.args)); cbool is_last = (i + 1 == scc_vec_size(value->data.call.args));
scc_tree_dump_push(ctx->dump_ctx, is_last); scc_tree_dump_push(ctx->dump_ctx, is_last);
scc_ir_value_ref_t arg = scc_vec_at(node->data.call.args, i); scc_ir_value_ref_t arg = scc_vec_at(value->data.call.args, i);
dump_child_node_ref(ctx, arg, is_last); dump_child_node_ref(ctx, arg, is_last);
scc_tree_dump_pop(ctx->dump_ctx); scc_tree_dump_pop(ctx->dump_ctx);
} }
} }
static void dump_ret_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *node) { static void dump_ret_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *value) {
if (node->data.ret.ret_val) if (value->data.ret.ret_val)
dump_child_node_ref(ctx, node->data.ret.ret_val, true); dump_child_node_ref(ctx, value->data.ret.ret_val, true);
} }
void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, scc_tree_dump_t *td, void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, scc_tree_dump_t *td,
@@ -199,20 +203,20 @@ void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, scc_tree_dump_t *td,
ctx->dump_ctx = td; ctx->dump_ctx = td;
} }
void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t node_ref) { void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t value_ref) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref); scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref);
if (!node) { if (!value) {
LOG_ERROR("Invalid node ref"); LOG_ERROR("Invalid value ref");
return; return;
} }
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "%s", get_node_type_str(node->tag)); scc_tree_dump_node(ctx->dump_ctx, "%s", get_node_type_str(value->tag));
if (node->name && node->name[0]) if (value->name && value->name[0])
scc_tree_dump_value(ctx->dump_ctx, " [%s]", node->name); scc_tree_dump_value(ctx->dump_ctx, " [%s]", value->name);
if (node->type) { if (value->type) {
scc_ir_type_t *type = scc_ir_type_t *type =
scc_ir_module_get_type(GET_MODULE(ctx), node->type); scc_ir_module_get_type(GET_MODULE(ctx), value->type);
if (type) { if (type) {
scc_tree_dump_append(ctx->dump_ctx, " : "); scc_tree_dump_append(ctx->dump_ctx, " : ");
scc_tree_dump_value(ctx->dump_ctx, "%s", scc_tree_dump_value(ctx->dump_ctx, "%s",
@@ -220,39 +224,39 @@ void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t node_ref) {
} }
} }
switch (node->tag) { switch (value->tag) {
case SCC_IR_VALUE_TAG_CONST_INT: case SCC_IR_VALUE_TAG_CONST_INT:
dump_const_int_node(ctx, node); dump_const_int_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_ALLOC: case SCC_IR_VALUE_TAG_ALLOC:
break; break;
case SCC_IR_VALUE_TAG_LOAD: case SCC_IR_VALUE_TAG_LOAD:
dump_load_node(ctx, node); dump_load_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_STORE: case SCC_IR_VALUE_TAG_STORE:
dump_store_node(ctx, node); dump_store_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_GET_PTR: case SCC_IR_VALUE_TAG_GET_PTR:
dump_get_ptr_node(ctx, node); dump_get_ptr_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_OP: case SCC_IR_VALUE_TAG_OP:
dump_op_node(ctx, node); dump_op_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_BRANCH: case SCC_IR_VALUE_TAG_BRANCH:
dump_branch_node(ctx, node); dump_branch_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_JUMP: case SCC_IR_VALUE_TAG_JUMP:
dump_jump_node(ctx, node); dump_jump_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_CALL: case SCC_IR_VALUE_TAG_CALL:
dump_call_node(ctx, node); dump_call_node(ctx, value);
break; break;
case SCC_IR_VALUE_TAG_RET: case SCC_IR_VALUE_TAG_RET:
dump_ret_node(ctx, node); dump_ret_node(ctx, value);
break; break;
default: default:
scc_tree_dump_value(ctx->dump_ctx, "unknown"); scc_tree_dump_value(ctx->dump_ctx, "unknown");
scc_tree_dump_append_fmt(ctx->dump_ctx, " tag(%d)", node->tag); scc_tree_dump_append_fmt(ctx->dump_ctx, " tag(%d)", value->tag);
break; break;
} }
} }
@@ -434,73 +438,99 @@ void scc_ir_dump_type_linear(scc_ir_dump_ctx_t *ctx,
} }
} }
static void format_node_ref_or_value(scc_ir_dump_ctx_t *ctx, static void format_ref_or_value(scc_ir_dump_ctx_t *ctx,
scc_ir_value_ref_t node_ref) { scc_ir_value_ref_t value_ref) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref); scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref);
if (!node) { if (!value) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%%%u", node_ref); scc_tree_dump_append_fmt(ctx->dump_ctx, "%%%u", value_ref);
return; return;
} }
if (node->tag == SCC_IR_VALUE_TAG_CONST_INT) { if (value->tag == SCC_IR_VALUE_TAG_CONST_INT) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%d", scc_tree_dump_append_fmt(ctx->dump_ctx, "%d",
node->data.const_int.int32); value->data.const_int.int32);
return; return;
} }
if (node->name && node->name[0] != '\0') { if (value->name && value->name[0] != '\0') {
scc_tree_dump_node(ctx->dump_ctx, "%%%u[%s]", node_ref, node->name); scc_tree_dump_node(ctx->dump_ctx, "%%%u[%s]", value_ref, value->name);
} else { } else {
scc_tree_dump_node(ctx->dump_ctx, "%%%u", node_ref); scc_tree_dump_node(ctx->dump_ctx, "%%%u", value_ref);
} }
if (node->type != SCC_IR_REF_NULL) { if (value->type != SCC_IR_REF_nullptr) {
scc_tree_dump_append(ctx->dump_ctx, ":"); scc_tree_dump_append(ctx->dump_ctx, ":");
scc_ir_dump_type_linear(ctx, node->type); scc_ir_dump_type_linear(ctx, value->type);
} }
} }
void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx, void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx,
scc_ir_value_ref_t node_ref) { scc_ir_value_ref_t value_ref) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref); scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref);
if (!node) { if (!value) {
scc_tree_dump_append(ctx->dump_ctx, "<invalid node>\n"); scc_tree_dump_append(ctx->dump_ctx, "<invalid value>\n");
return; return;
} }
cbool needs_equals = (node->tag != SCC_IR_VALUE_TAG_BRANCH && cbool needs_equals = (value->tag != SCC_IR_VALUE_TAG_BRANCH &&
node->tag != SCC_IR_VALUE_TAG_JUMP && value->tag != SCC_IR_VALUE_TAG_JUMP &&
node->tag != SCC_IR_VALUE_TAG_RET && value->tag != SCC_IR_VALUE_TAG_RET &&
node->tag != SCC_IR_VALUE_TAG_STORE); value->tag != SCC_IR_VALUE_TAG_STORE);
if (needs_equals) { if (needs_equals) {
format_node_ref_or_value(ctx, node_ref); format_ref_or_value(ctx, value_ref);
scc_tree_dump_append(ctx->dump_ctx, " = "); scc_tree_dump_append(ctx->dump_ctx, " = ");
} }
switch (node->tag) { switch (value->tag) {
case SCC_IR_VALUE_TAG_BUILTIN: {
switch (value->data.builtin.tag) {
case SCC_IR_BUILTIN_TAG_MEMCPY:
scc_tree_dump_append(ctx->dump_ctx, "memcpy");
break;
case SCC_IR_BUILTIN_TAG_MEMSET:
scc_tree_dump_append(ctx->dump_ctx, "memset");
break;
case SCC_IR_BUILTIN_TAG_VA_ARG:
scc_tree_dump_append(ctx->dump_ctx, "va_arg");
break;
case SCC_IR_BUILTIN_TAG_VA_END:
scc_tree_dump_append(ctx->dump_ctx, "va_end");
break;
case SCC_IR_BUILTIN_TAG_VA_COPY:
scc_tree_dump_append(ctx->dump_ctx, "va_copy");
break;
case SCC_IR_BUILTIN_TAG_VA_START:
scc_tree_dump_append(ctx->dump_ctx, "va_start");
break;
default:
Panic("Unknown builtin tag");
break;
}
break;
}
case SCC_IR_VALUE_TAG_CONST_INT: case SCC_IR_VALUE_TAG_CONST_INT:
// 值已经在 format 中输出,这里不需要再做 // 值已经在 format 中输出,这里不需要再做
break; break;
case SCC_IR_VALUE_TAG_CONST_UINT: { case SCC_IR_VALUE_TAG_CONST_UINT: {
scc_ir_type_t *type = scc_ir_type_t *type =
scc_ir_module_get_type(GET_MODULE(ctx), node->type); scc_ir_module_get_type(GET_MODULE(ctx), value->type);
Assert(type != null); Assert(type != nullptr);
if (type->tag == SCC_IR_TYPE_u8) { if (type->tag == SCC_IR_TYPE_u8) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%c", scc_tree_dump_append_fmt(ctx->dump_ctx, "%c",
node->data.const_uint.uint8); value->data.const_uint.uint8);
} else { } else {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%u", scc_tree_dump_append_fmt(ctx->dump_ctx, "%u",
node->data.const_uint.uint32); value->data.const_uint.uint32);
} }
break; break;
} }
case SCC_IR_VALUE_TAG_CONST_FLOAT: case SCC_IR_VALUE_TAG_CONST_FLOAT:
scc_tree_dump_append_fmt(ctx->dump_ctx, "%f", scc_tree_dump_append_fmt(ctx->dump_ctx, "%f",
node->data.const_float.float32); value->data.const_float.float32);
break; break;
case SCC_IR_VALUE_TAG_AGGREGATE: case SCC_IR_VALUE_TAG_AGGREGATE:
// 聚合类型:递归输出每个元素(每个占一行) // 聚合类型:递归输出每个元素(每个占一行)
scc_vec_foreach(node->data.aggregate.elements, i) { scc_vec_foreach(value->data.aggregate.elements, i) {
scc_ir_dump_node_linear( scc_ir_dump_value_linear(
ctx, scc_vec_at(node->data.aggregate.elements, i)); ctx, scc_vec_at(value->data.aggregate.elements, i));
scc_tree_dump_append(ctx->dump_ctx, "\n"); scc_tree_dump_append(ctx->dump_ctx, "\n");
} }
return; return;
@@ -509,88 +539,89 @@ void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx,
break; break;
case SCC_IR_VALUE_TAG_LOAD: case SCC_IR_VALUE_TAG_LOAD:
scc_tree_dump_append(ctx->dump_ctx, "load "); scc_tree_dump_append(ctx->dump_ctx, "load ");
format_node_ref_or_value(ctx, node->data.load.target); format_ref_or_value(ctx, value->data.load.target);
break; break;
case SCC_IR_VALUE_TAG_STORE: case SCC_IR_VALUE_TAG_STORE:
scc_tree_dump_append(ctx->dump_ctx, "store "); scc_tree_dump_append(ctx->dump_ctx, "store ");
format_node_ref_or_value(ctx, node->data.store.value); format_ref_or_value(ctx, value->data.store.value);
scc_tree_dump_append(ctx->dump_ctx, " -> "); scc_tree_dump_append(ctx->dump_ctx, " -> ");
format_node_ref_or_value(ctx, node->data.store.target); format_ref_or_value(ctx, value->data.store.target);
break; break;
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: case SCC_IR_VALUE_TAG_GET_ELEM_PTR:
case SCC_IR_VALUE_TAG_GET_PTR: case SCC_IR_VALUE_TAG_GET_PTR:
scc_tree_dump_append( scc_tree_dump_append(
ctx->dump_ctx, ctx->dump_ctx,
node->tag == SCC_IR_VALUE_TAG_GET_PTR ? "getptr " : "getelemptr "); value->tag == SCC_IR_VALUE_TAG_GET_PTR ? "getptr " : "getelemptr ");
format_node_ref_or_value(ctx, node->data.get_ptr.src_addr); format_ref_or_value(ctx, value->data.get_ptr.src_addr);
scc_tree_dump_append(ctx->dump_ctx, ", "); scc_tree_dump_append(ctx->dump_ctx, ", ");
format_node_ref_or_value(ctx, node->data.get_ptr.index); format_ref_or_value(ctx, value->data.get_ptr.index);
break; break;
case SCC_IR_VALUE_TAG_OP: case SCC_IR_VALUE_TAG_OP:
format_node_ref_or_value(ctx, node->data.op.lhs); format_ref_or_value(ctx, value->data.op.lhs);
scc_tree_dump_append_fmt(ctx->dump_ctx, " %s ", scc_tree_dump_append_fmt(ctx->dump_ctx, " %s ",
get_op_str(node->data.op.op)); get_op_str(value->data.op.op));
format_node_ref_or_value(ctx, node->data.op.rhs); format_ref_or_value(ctx, value->data.op.rhs);
break; break;
case SCC_IR_VALUE_TAG_BRANCH: case SCC_IR_VALUE_TAG_BRANCH:
if (node->data.branch.cond) { if (value->data.branch.cond) {
scc_tree_dump_append(ctx->dump_ctx, "br "); scc_tree_dump_append(ctx->dump_ctx, "br ");
format_node_ref_or_value(ctx, node->data.branch.cond); format_ref_or_value(ctx, value->data.branch.cond);
scc_tree_dump_append_fmt( scc_tree_dump_append_fmt(ctx->dump_ctx,
ctx->dump_ctx, ", label %%L%u, label %%L%u", ", label %%L%u, label %%L%u",
node->data.branch.true_bblock, node->data.branch.false_bblock); value->data.branch.true_bblock,
value->data.branch.false_bblock);
} else { } else {
scc_tree_dump_append_fmt(ctx->dump_ctx, "br label %%L%u", scc_tree_dump_append_fmt(ctx->dump_ctx, "br label %%L%u",
node->data.branch.true_bblock); value->data.branch.true_bblock);
} }
break; break;
case SCC_IR_VALUE_TAG_JUMP: case SCC_IR_VALUE_TAG_JUMP:
scc_tree_dump_append_fmt(ctx->dump_ctx, "jmp label %%%u", scc_tree_dump_append_fmt(ctx->dump_ctx, "jmp label %%L%u",
node->data.jump.target_bblock); value->data.jump.target_bblock);
break; break;
case SCC_IR_VALUE_TAG_CALL: { case SCC_IR_VALUE_TAG_CALL: {
scc_ir_func_t *func = scc_ir_func_t *func =
scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee); scc_ir_module_get_func(GET_MODULE(ctx), value->data.call.callee);
scc_tree_dump_append_fmt(ctx->dump_ctx, "call @%s(", scc_tree_dump_append_fmt(ctx->dump_ctx, "call @%s(",
func ? (func->name ? func->name : "<unnamed>") func ? (func->name ? func->name : "<unnamed>")
: "<invalid>"); : "<invalid>");
for (usize i = 0; i < scc_vec_size(node->data.call.args); i++) { for (usize i = 0; i < scc_vec_size(value->data.call.args); i++) {
if (i > 0) if (i > 0)
scc_tree_dump_append(ctx->dump_ctx, ", "); scc_tree_dump_append(ctx->dump_ctx, ", ");
format_node_ref_or_value(ctx, scc_vec_at(node->data.call.args, i)); format_ref_or_value(ctx, scc_vec_at(value->data.call.args, i));
} }
scc_tree_dump_append(ctx->dump_ctx, ")"); scc_tree_dump_append(ctx->dump_ctx, ")");
break; break;
} }
case SCC_IR_VALUE_TAG_RET: case SCC_IR_VALUE_TAG_RET:
if (node->data.ret.ret_val != 0) { if (value->data.ret.ret_val != 0) {
scc_tree_dump_append(ctx->dump_ctx, "ret "); scc_tree_dump_append(ctx->dump_ctx, "ret ");
format_node_ref_or_value(ctx, node->data.ret.ret_val); format_ref_or_value(ctx, value->data.ret.ret_val);
} else { } else {
scc_tree_dump_append(ctx->dump_ctx, "ret void"); scc_tree_dump_append(ctx->dump_ctx, "ret void");
} }
break; break;
case SCC_IR_VALUE_TAG_FUNC_ARG_REF: case SCC_IR_VALUE_TAG_FUNC_ARG_REF:
scc_tree_dump_append_fmt(ctx->dump_ctx, "arg[%zu]", scc_tree_dump_append_fmt(ctx->dump_ctx, "arg[%zu]",
node->data.arg_ref.idx); value->data.arg_ref.idx);
break; break;
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC: case SCC_IR_VALUE_TAG_GLOBAL_ALLOC:
scc_tree_dump_append_fmt(ctx->dump_ctx, "global %s\n", node->name); scc_tree_dump_append_fmt(ctx->dump_ctx, "global %s\n", value->name);
scc_ir_dump_node_linear(ctx, node->data.global_alloc.value); scc_ir_dump_value_linear(ctx, value->data.global_alloc.value);
return; return;
case SCC_IR_VALUE_TAG_CONST_ARRAY: case SCC_IR_VALUE_TAG_CONST_ARRAY:
scc_tree_dump_append(ctx->dump_ctx, "const_array "); scc_tree_dump_append(ctx->dump_ctx, "const_array ");
scc_ir_dump_type_linear(ctx, node->data.const_array.base_type); scc_ir_dump_type_linear(ctx, value->data.const_array.base_type);
scc_tree_dump_append(ctx->dump_ctx, " ["); scc_tree_dump_append(ctx->dump_ctx, " [");
scc_vec_foreach(node->data.const_array.elements, i) { scc_vec_foreach(value->data.const_array.elements, i) {
u8 ch = scc_vec_at(node->data.const_array.elements, i); u8 ch = scc_vec_at(value->data.const_array.elements, i);
scc_tree_dump_append_fmt(ctx->dump_ctx, " `%c`, ", ch ? ch : ' '); scc_tree_dump_append_fmt(ctx->dump_ctx, " `%c`, ", ch ? ch : ' ');
} }
scc_tree_dump_append(ctx->dump_ctx, " ]"); scc_tree_dump_append(ctx->dump_ctx, " ]");
break; break;
default: default:
scc_tree_dump_append_fmt(ctx->dump_ctx, "<%s node %u>", scc_tree_dump_append_fmt(ctx->dump_ctx, "<%s value %u>",
get_node_type_str(node->tag), node_ref); get_node_type_str(value->tag), value_ref);
break; break;
} }
} }
@@ -613,7 +644,7 @@ void scc_ir_dump_bblock_linear(scc_ir_dump_ctx_t *ctx,
for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) { for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) {
scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_append(ctx->dump_ctx, " "); scc_tree_dump_append(ctx->dump_ctx, " ");
scc_ir_dump_node_linear(ctx, scc_vec_at(bblock->instrs, i)); scc_ir_dump_value_linear(ctx, scc_vec_at(bblock->instrs, i));
} }
} }
@@ -668,7 +699,7 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref,
void scc_ir_dump_cprog_linear(scc_ir_dump_ctx_t *ctx) { void scc_ir_dump_cprog_linear(scc_ir_dump_ctx_t *ctx) {
for (usize i = 0; i < scc_vec_size(ctx->cprog->global_vals); i++) { for (usize i = 0; i < scc_vec_size(ctx->cprog->global_vals); i++) {
scc_ir_dump_node_linear(ctx, scc_vec_at(ctx->cprog->global_vals, i)); scc_ir_dump_value_linear(ctx, scc_vec_at(ctx->cprog->global_vals, i));
} }
for (usize i = 0; i < scc_vec_size(ctx->cprog->func_decls); i++) { for (usize i = 0; i < scc_vec_size(ctx->cprog->func_decls); i++) {
scc_ir_func_ref_t func_decl = scc_vec_at(ctx->cprog->func_decls, i); scc_ir_func_ref_t func_decl = scc_vec_at(ctx->cprog->func_decls, i);
+8 -8
View File
@@ -99,39 +99,39 @@ scc_ir_func_ref_t scc_ir_module_add_func(scc_ir_module_t *ctx,
scc_ir_type_t *scc_ir_module_get_type(scc_ir_module_t *ctx, scc_ir_type_t *scc_ir_module_get_type(scc_ir_module_t *ctx,
scc_ir_type_ref_t ref) { scc_ir_type_ref_t ref) {
if (ref == 0) if (ref == 0)
return null; return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2type); usize idx = GET_ENTITY_INDEX(ctx, ref, uid2type);
if (idx >= ctx->types.size) if (idx >= ctx->types.size)
return null; return nullptr;
return &ctx->types.data[idx]; return &ctx->types.data[idx];
} }
scc_ir_value_t *scc_ir_module_get_value(scc_ir_module_t *ctx, scc_ir_value_t *scc_ir_module_get_value(scc_ir_module_t *ctx,
scc_ir_value_ref_t ref) { scc_ir_value_ref_t ref) {
if (ref == 0) if (ref == 0)
return null; return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2value); usize idx = GET_ENTITY_INDEX(ctx, ref, uid2value);
if (idx >= ctx->values.size) if (idx >= ctx->values.size)
return null; return nullptr;
return &ctx->values.data[idx]; return &ctx->values.data[idx];
} }
scc_ir_bblock_t *scc_ir_module_get_bblock(scc_ir_module_t *ctx, scc_ir_bblock_t *scc_ir_module_get_bblock(scc_ir_module_t *ctx,
scc_ir_bblock_ref_t ref) { scc_ir_bblock_ref_t ref) {
if (ref == 0) if (ref == 0)
return null; return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2bblock); usize idx = GET_ENTITY_INDEX(ctx, ref, uid2bblock);
if (idx >= ctx->bblocks.size) if (idx >= ctx->bblocks.size)
return null; return nullptr;
return &ctx->bblocks.data[idx]; return &ctx->bblocks.data[idx];
} }
scc_ir_func_t *scc_ir_module_get_func(scc_ir_module_t *ctx, scc_ir_func_t *scc_ir_module_get_func(scc_ir_module_t *ctx,
scc_ir_func_ref_t ref) { scc_ir_func_ref_t ref) {
if (ref == 0) if (ref == 0)
return null; return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2func); usize idx = GET_ENTITY_INDEX(ctx, ref, uid2func);
if (idx >= ctx->funcs.size) if (idx >= ctx->funcs.size)
return null; return nullptr;
return &ctx->funcs.data[idx]; return &ctx->funcs.data[idx];
} }
+12 -10
View File
@@ -1,9 +1,9 @@
#include <scc_ir.h> #include <scc_ir.h>
void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) { void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) {
Assert(in != null); Assert(in != nullptr);
in->tag = tag; in->tag = tag;
in->name = null; in->name = nullptr;
switch (tag) { switch (tag) {
case SCC_IR_TYPE_unknown: case SCC_IR_TYPE_unknown:
case SCC_IR_TYPE_void: case SCC_IR_TYPE_void:
@@ -40,31 +40,33 @@ void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) {
} }
void scc_ir_bblock_init(scc_ir_bblock_t *in, const char *label) { void scc_ir_bblock_init(scc_ir_bblock_t *in, const char *label) {
Assert(in != null); Assert(in != nullptr);
Assert(label != null); Assert(label != nullptr);
in->label = label; in->label = label;
scc_vec_init(in->instrs); scc_vec_init(in->instrs);
} }
void scc_ir_func_init(scc_ir_func_t *in, const char *name) { void scc_ir_func_init(scc_ir_func_t *in, const char *name) {
Assert(in != null); Assert(in != nullptr);
Assert(name != null); Assert(name != nullptr);
in->name = name; in->name = name;
in->type = 0; in->type = 0;
scc_vec_init(in->bblocks); scc_vec_init(in->bblocks);
scc_vec_init(in->params); scc_vec_init(in->params);
} }
void scc_ir_node_init(scc_ir_value_t *in, const char *name, void scc_ir_value_init(scc_ir_value_t *in, const char *name,
scc_ir_value_tag_t tag) { scc_ir_value_tag_t tag) {
Assert(in != null); Assert(in != nullptr);
in->name = name; in->name = name;
in->tag = tag; in->tag = tag;
scc_vec_init(in->used_by); scc_vec_init(in->used_by);
in->type = 0; in->type = 0;
switch (tag) { switch (tag) {
case SCC_IR_VALUE_TAG_NULL: case SCC_IR_VALUE_TAG_NULLPTR:
break;
case SCC_IR_VALUE_TAG_BUILTIN:
break; break;
case SCC_IR_VALUE_TAG_CONST_INT: case SCC_IR_VALUE_TAG_CONST_INT:
// TODO // TODO
+3
View File
@@ -0,0 +1,3 @@
#include <scc_ir.h>
int scc_ir2mcode_type_width(scc_ir_module_t *ctx, scc_ir_type_t *type);
+50
View File
@@ -0,0 +1,50 @@
// frame_manager.c
#include "frame_manager.h"
#include <assert.h>
#include <stdlib.h>
struct frame_manager {
int shadow_space; // 影子空间大小(字节)
int saved_reg_size; // 已分配的保存寄存器区域大小
int local_size; // 已分配的局部变量区域大小
int align; // 栈对齐要求
};
void frame_manager_init(frame_manager_t *fm, int shadow_space, int align) {
fm->shadow_space = shadow_space;
fm->saved_reg_size = 0;
fm->local_size = 0;
fm->align = align;
}
int frame_alloc_slot(frame_manager_t *fm, int size) {
int offset = fm->local_size;
fm->local_size += size;
return offset; // 返回虚拟偏移(从0开始)
}
int frame_alloc_saved_reg(frame_manager_t *fm, int reg_width) {
int offset = fm->saved_reg_size;
fm->saved_reg_size += reg_width;
return offset;
}
int frame_total_size(frame_manager_t *fm) {
int total = fm->shadow_space + fm->saved_reg_size + fm->local_size;
// 对齐到 align 字节
return (total + fm->align - 1) & ~(fm->align - 1);
}
int frame_slot_offset(frame_manager_t *fm, int slot_idx) {
// 布局: RBP 指向保存的 RBP,向下依次是:
// [影子空间] [保存寄存器区] [局部变量区]
// 局部变量区的起始地址 = RBP - (8 + shadow_space + saved_reg_size)
// 其中 8 是 push rbp 占用的空间(返回地址在 RBP+8,但 RBP 本身指向保存的
// RBP)
int base = 8 + fm->shadow_space + fm->saved_reg_size;
return base + slot_idx; // 返回正数,表示从 RBP 向下的字节数
}
int frame_shadow_space(frame_manager_t *fm) { return fm->shadow_space; }
int frame_saved_reg_size(frame_manager_t *fm) { return fm->saved_reg_size; }
+48 -41
View File
@@ -2,22 +2,10 @@
#include <amd64/scc_amd64_abi.h> #include <amd64/scc_amd64_abi.h>
#include <reg_alloc.h> #include <reg_alloc.h>
#include <scc_ir2mcode.h> #include <scc_ir2mcode.h>
#include <type_manager.h>
#define GET_MODULE(ctx) (&(ctx->cprog->module)) #define GET_MODULE(ctx) (&(ctx->cprog->module))
static int scc_type_width(scc_ir_type_t *type) {
/* clang-format off */
switch (type->tag) {
case SCC_IR_TYPE_i8: case SCC_IR_TYPE_u8: return 1;
case SCC_IR_TYPE_i16: case SCC_IR_TYPE_u16: return 2;
case SCC_IR_TYPE_i32: case SCC_IR_TYPE_u32: return 4;
case SCC_IR_TYPE_i64: case SCC_IR_TYPE_u64: return 8;
case SCC_IR_TYPE_PTR: return 8;
default: return 8; // 默认64位
}
/* clang-format on */
}
static bool scc_type_is_signed(scc_ir_type_t *type) { static bool scc_type_is_signed(scc_ir_type_t *type) {
return (type->tag == SCC_IR_TYPE_i8 || type->tag == SCC_IR_TYPE_i16 || return (type->tag == SCC_IR_TYPE_i8 || type->tag == SCC_IR_TYPE_i16 ||
type->tag == SCC_IR_TYPE_i32 || type->tag == SCC_IR_TYPE_i64); type->tag == SCC_IR_TYPE_i32 || type->tag == SCC_IR_TYPE_i64);
@@ -25,9 +13,9 @@ static bool scc_type_is_signed(scc_ir_type_t *type) {
static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc, static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
scc_ir_value_ref_t node_ref) { scc_ir_value_ref_t node_ref) {
Assert(ctx != null && loc != null); Assert(ctx != nullptr && loc != nullptr);
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref); scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (node == null) { if (node == nullptr) {
LOG_FATAL("invalid node ref"); LOG_FATAL("invalid node ref");
UNREACHABLE(); UNREACHABLE();
return; return;
@@ -140,7 +128,7 @@ typedef SCC_VEC(patch_t) patch_vec_t;
static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
patch_vec_t *patches) { patch_vec_t *patches) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref); scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (node == null) { if (node == nullptr) {
LOG_ERROR("invalid node ref"); LOG_ERROR("invalid node ref");
return; return;
} }
@@ -172,7 +160,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
GET_MODULE(ctx), node->data.load.target); GET_MODULE(ctx), node->data.load.target);
scc_ir_type_t *base_type = scc_ir_module_get_type( scc_ir_type_t *base_type = scc_ir_module_get_type(
GET_MODULE(ctx), ptr_type->data.pointer.base); GET_MODULE(ctx), ptr_type->data.pointer.base);
int width = scc_type_width(base_type); int width = scc_ir2mcode_type_width(GET_MODULE(ctx), base_type);
bool is_signed = scc_type_is_signed(base_type); bool is_signed = scc_type_is_signed(base_type);
// 间接加载到 RAX // 间接加载到 RAX
@@ -202,7 +190,9 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
scc_mcode_amd64_mov_r64_m64(&ctx->sect_mcode, SCC_AMD64_RAX, scc_mcode_amd64_mov_r64_m64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX); SCC_AMD64_RCX);
} else { } else {
UNREACHABLE(); LOG_WARN("unsupported type width: %d", width);
scc_mcode_amd64_mov_r64_m64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
} }
// 存储结果 // 存储结果
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX); store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
@@ -224,7 +214,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
GET_MODULE(ctx), node->data.store.target); GET_MODULE(ctx), node->data.store.target);
scc_ir_type_t *base_type = scc_ir_module_get_type( scc_ir_type_t *base_type = scc_ir_module_get_type(
GET_MODULE(ctx), ptr_type->data.pointer.base); GET_MODULE(ctx), ptr_type->data.pointer.base);
int width = scc_type_width(base_type); int width = scc_ir2mcode_type_width(GET_MODULE(ctx), base_type);
// 根据宽度生成存储指令 // 根据宽度生成存储指令
if (width == 1) { if (width == 1) {
@@ -242,30 +232,47 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
} }
break; break;
} }
///< 获取指针 ///< 获取指针
case SCC_IR_VALUE_TAG_GET_PTR: { case SCC_IR_VALUE_TAG_GET_PTR: {
scc_reg_loc_t loc; scc_reg_loc_t loc_res;
parse_location(ctx, &loc_res, node_ref);
scc_ir_value_t *src_addr = scc_ir_module_get_value( scc_ir_value_t *src_addr = scc_ir_module_get_value(
GET_MODULE(ctx), node->data.get_ptr.src_addr); GET_MODULE(ctx), node->data.get_ptr.src_addr);
Assert(src_addr != null); Assert(src_addr != nullptr);
if (src_addr->tag != SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
Panic(); if (src_addr->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
// 全局变量:RIP相对寻址
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode, SCC_AMD64_RAX,
0);
usize sym_idx =
sccf_builder_get_symbol_idx(ctx->builder, src_addr->name);
Assert(sym_idx != 0);
sccf_builder_add_reloc(
ctx->builder,
(sccf_reloc_t){
.reloc_type = SCCF_RELOC_TYPE_REL,
.offset = scc_vec_size(ctx->sect_mcode.mcode) - 4,
.addend = 4,
.sect_type = SCCF_SECT_DATA,
.sym_idx = sym_idx,
});
} else if (src_addr->tag == SCC_IR_VALUE_TAG_ALLOC) {
// 栈上变量:地址为 rbp - offset
scc_reg_loc_t src_loc;
parse_location(ctx, &src_loc, node->data.get_ptr.src_addr);
// src_loc.kind 应为 SCC_REG_KIND_STACK_ADDR,idx 是虚拟偏移(正数)
scc_mcode_amd64_lea_r64_m64_disp32(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RBP, -src_loc.idx - 8);
} else {
// 其他情况(如链式 getptr):源地址值已经存储在某个位置,直接加载到
// RAX
scc_reg_loc_t src_loc;
parse_location(ctx, &src_loc, node->data.get_ptr.src_addr);
load_value_to_reg(&ctx->sect_mcode, &src_loc, SCC_AMD64_RAX);
} }
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode, SCC_AMD64_RAX, 0); store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX);
usize sym_idx =
sccf_builder_get_symbol_idx(ctx->builder, src_addr->name);
Assert(sym_idx != 0);
sccf_builder_add_reloc(
ctx->builder, (sccf_reloc_t){
.reloc_type = SCCF_RELOC_TYPE_REL,
.offset = scc_vec_size(ctx->sect_mcode.mcode) - 4,
.addend = 4,
.sect_type = SCCF_SECT_DATA,
.sym_idx = sym_idx,
});
parse_location(ctx, &loc, node_ref);
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
break; break;
} }
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array) case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array)
@@ -555,7 +562,7 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
scc_ir_bblock_t *bblock = scc_ir_bblock_t *bblock =
scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref); scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref);
if (bblock == null) { if (bblock == nullptr) {
LOG_FATAL("<invalid block>\n"); LOG_FATAL("<invalid block>\n");
return; return;
} }
@@ -593,7 +600,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
Assert(galloc->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC); Assert(galloc->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC);
scc_ir_value_t *value = scc_ir_module_get_value( scc_ir_value_t *value = scc_ir_module_get_value(
GET_MODULE(ctx), galloc->data.global_alloc.value); GET_MODULE(ctx), galloc->data.global_alloc.value);
Assert(value != null); Assert(value != nullptr);
sccf_sym_t sym = (sccf_sym_t){ sccf_sym_t sym = (sccf_sym_t){
.sccf_sect_offset = scc_vec_size(ctx->sect_data), .sccf_sect_offset = scc_vec_size(ctx->sect_data),
.sccf_sect_type = SCCF_SECT_DATA, .sccf_sect_type = SCCF_SECT_DATA,
@@ -654,7 +661,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
} }
sccf_sym_t *sym = sccf_sym_t *sym =
sccf_builder_get_symbol_unsafe(ctx->builder, func->name); sccf_builder_get_symbol_unsafe(ctx->builder, func->name);
Assert(sym != null); Assert(sym != nullptr);
sym->sccf_sect_offset = scc_vec_size(ctx->sect_mcode.mcode); sym->sccf_sect_offset = scc_vec_size(ctx->sect_mcode.mcode);
parse_function(ctx, func); parse_function(ctx, func);
} }
+14 -4
View File
@@ -1,4 +1,5 @@
#include "reg_alloc.h" #include <reg_alloc.h>
#include <type_manager.h>
u32 hash_func(const void *key) { return (usize)key; } u32 hash_func(const void *key) { return (usize)key; }
int equal_func(const void *key1, const void *key2) { int equal_func(const void *key1, const void *key2) {
@@ -39,12 +40,12 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i); scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i);
scc_ir_bblock_t *bblock = scc_ir_bblock_t *bblock =
scc_ir_module_get_bblock(ctx->ir_module, bblock_ref); scc_ir_module_get_bblock(ctx->ir_module, bblock_ref);
Assert(bblock != null); Assert(bblock != nullptr);
scc_vec_foreach(bblock->instrs, j) { scc_vec_foreach(bblock->instrs, j) {
scc_ir_value_ref_t node_ref = scc_vec_at(bblock->instrs, j); scc_ir_value_ref_t node_ref = scc_vec_at(bblock->instrs, j);
scc_ir_value_t *node = scc_ir_value_t *node =
scc_ir_module_get_value(ctx->ir_module, node_ref); scc_ir_module_get_value(ctx->ir_module, node_ref);
Assert(node != null); Assert(node != nullptr);
loc.kind = SCC_REG_KIND_UNDEF; loc.kind = SCC_REG_KIND_UNDEF;
switch (node->tag) { switch (node->tag) {
case SCC_IR_VALUE_TAG_LOAD: case SCC_IR_VALUE_TAG_LOAD:
@@ -65,8 +66,17 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
// 为 alloc 分配栈偏移,但不作为普通值存储 // 为 alloc 分配栈偏移,但不作为普通值存储
loc.kind = loc.kind =
SCC_REG_KIND_STACK_ADDR; // 实际不需要存储到 reg_loc_vec SCC_REG_KIND_STACK_ADDR; // 实际不需要存储到 reg_loc_vec
scc_ir_type_t *type =
scc_ir_module_get_type(ctx->ir_module, node->type);
Assert(type != nullptr);
loc.idx = ctx->alloc_stack_size; loc.idx = ctx->alloc_stack_size;
ctx->alloc_stack_size += 8; // 根据类型大小调整 Assert(type->tag == SCC_IR_TYPE_PTR);
int len = scc_ir2mcode_type_width(
ctx->ir_module,
scc_ir_module_get_type(ctx->ir_module,
type->data.pointer.base));
len = len % 8 == 0 ? len : len + 8 - len % 8;
ctx->alloc_stack_size += len;
// 记录偏移 // 记录偏移
scc_vec_push(ctx->reg_loc_vec, loc); scc_vec_push(ctx->reg_loc_vec, loc);
+23
View File
@@ -0,0 +1,23 @@
#include <type_manager.h>
int scc_ir2mcode_type_width(scc_ir_module_t *ctx, scc_ir_type_t *type) {
/* clang-format off */
if (ctx == nullptr || type == nullptr) {
Panic("Invalid argument");
return 0;
}
switch (type->tag) {
case SCC_IR_TYPE_i8: case SCC_IR_TYPE_u8: return 1;
case SCC_IR_TYPE_i16: case SCC_IR_TYPE_u16: return 2;
case SCC_IR_TYPE_i32: case SCC_IR_TYPE_u32: return 4;
case SCC_IR_TYPE_i64: case SCC_IR_TYPE_u64: return 8;
case SCC_IR_TYPE_PTR: return 8;
case SCC_IR_TYPE_ARRAY:
return scc_ir2mcode_type_width(
ctx,
scc_ir_module_get_type(ctx, type->data.array.base)
) * type->data.array.len;
default: return 8; // 默认64位
}
/* clang-format on */
}
+1 -1
View File
@@ -24,7 +24,7 @@ void test_example(const char *input, cbool need_sema, const char *name) {
scc_sema_init(&sema_callbacks); scc_sema_init(&sema_callbacks);
scc_parser_init(&parser, tok_ring, &sema_callbacks); scc_parser_init(&parser, tok_ring, &sema_callbacks);
} else { } else {
scc_parser_init(&parser, tok_ring, null); scc_parser_init(&parser, tok_ring, nullptr);
} }
scc_ast_translation_unit_t *tu = scc_parse_translation_unit(&parser); scc_ast_translation_unit_t *tu = scc_parse_translation_unit(&parser);
+5 -5
View File
@@ -193,11 +193,11 @@ scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type);
const char *scc_get_tok_name(scc_tok_type_t type); const char *scc_get_tok_name(scc_tok_type_t type);
static inline void scc_lexer_tok_drop(scc_lexer_tok_t *tok) { static inline void scc_lexer_tok_drop(scc_lexer_tok_t *tok) {
Assert(tok != null); Assert(tok != nullptr);
tok->type = SCC_TOK_UNKNOWN; tok->type = SCC_TOK_UNKNOWN;
tok->loc.col = 0; tok->loc.col = 0;
tok->loc.line = 0; tok->loc.line = 0;
tok->loc.name = null; tok->loc.name = nullptr;
tok->loc.offset = 0; tok->loc.offset = 0;
scc_str_drop(&tok->lexeme); scc_str_drop(&tok->lexeme);
} }
@@ -209,7 +209,7 @@ static inline cbool scc_lexer_tok_match(const scc_lexer_tok_t *tok,
// 深拷贝 token // 深拷贝 token
static inline scc_lexer_tok_t scc_lexer_tok_copy(const scc_lexer_tok_t *src) { static inline scc_lexer_tok_t scc_lexer_tok_copy(const scc_lexer_tok_t *src) {
Assert(src != null); Assert(src != nullptr);
scc_lexer_tok_t dst = *src; scc_lexer_tok_t dst = *src;
dst.lexeme = scc_str_copy(&src->lexeme); dst.lexeme = scc_str_copy(&src->lexeme);
return dst; return dst;
@@ -218,9 +218,9 @@ static inline scc_lexer_tok_t scc_lexer_tok_copy(const scc_lexer_tok_t *src) {
// 移动 token(源 token 不再拥有 lexeme) // 移动 token(源 token 不再拥有 lexeme)
static inline void scc_lexer_tok_move(scc_lexer_tok_t *dst, static inline void scc_lexer_tok_move(scc_lexer_tok_t *dst,
scc_lexer_tok_t *src) { scc_lexer_tok_t *src) {
Assert(src != null); Assert(src != nullptr);
*dst = *src; *dst = *src;
src->lexeme.data = null; src->lexeme.data = nullptr;
src->lexeme.size = 0; src->lexeme.size = 0;
src->lexeme.cap = 0; src->lexeme.cap = 0;
} }
+2 -2
View File
@@ -4,13 +4,13 @@
#include "scc_lexer.h" #include "scc_lexer.h"
static inline void scc_lexer_gen_number_true(scc_lexer_tok_t *tok) { static inline void scc_lexer_gen_number_true(scc_lexer_tok_t *tok) {
Assert(tok != null && tok->type == SCC_TOK_UNKNOWN); Assert(tok != nullptr && tok->type == SCC_TOK_UNKNOWN);
tok->type = SCC_TOK_INT_LITERAL; tok->type = SCC_TOK_INT_LITERAL;
tok->lexeme = scc_str_from_cstr("1"); tok->lexeme = scc_str_from_cstr("1");
} }
static inline void scc_lexer_gen_number_false(scc_lexer_tok_t *tok) { static inline void scc_lexer_gen_number_false(scc_lexer_tok_t *tok) {
Assert(tok != null && tok->type == SCC_TOK_UNKNOWN); Assert(tok != nullptr && tok->type == SCC_TOK_UNKNOWN);
tok->type = SCC_TOK_INT_LITERAL; tok->type = SCC_TOK_INT_LITERAL;
tok->lexeme = scc_str_from_cstr("0"); tok->lexeme = scc_str_from_cstr("0");
} }
+1 -1
View File
@@ -538,7 +538,7 @@ void scc_lexer_drop_ring(scc_lexer_tok_ring_t *ring_ref) {
} }
void scc_lexer_drop(scc_lexer_t *lexer) { void scc_lexer_drop(scc_lexer_t *lexer) {
Assert(lexer != null); Assert(lexer != nullptr);
if (lexer->ring_ref_count) { if (lexer->ring_ref_count) {
LOG_FATAL("drop sstream must be drop ring before ref [%d]", LOG_FATAL("drop sstream must be drop ring before ref [%d]",
lexer->ring_ref_count); lexer->ring_ref_count);
+3 -3
View File
@@ -24,12 +24,12 @@ int g_num_arr[3];
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// int num = 0; // int num = 0;
if (argc == 3 && strcmp(argv[2], "--debug") == 0) { if (argc == 3 && strcmp(argv[2], "--debug") == 0) {
log_set_level(NULL, LOG_LEVEL_ALL); log_set_level(nullptr, LOG_LEVEL_ALL);
} else { } else {
// FIXME it is a hack lexer_logger // FIXME it is a hack lexer_logger
log_set_level(&__scc_lexer_log, LOG_LEVEL_NOTSET); log_set_level(&__scc_lexer_log, LOG_LEVEL_NOTSET);
log_set_level(NULL, LOG_LEVEL_INFO | LOG_LEVEL_WARN | LOG_LEVEL_ERROR | log_set_level(nullptr, LOG_LEVEL_INFO | LOG_LEVEL_WARN |
LOG_LEVEL_FATAL); LOG_LEVEL_ERROR | LOG_LEVEL_FATAL);
} }
const char *file_name = __FILE__; const char *file_name = __FILE__;
+1 -1
View File
@@ -412,5 +412,5 @@ TEST_LIST = {
{"edge_cases", test_edge_cases}, {"edge_cases", test_edge_cases},
{"sequences", test_sequences}, {"sequences", test_sequences},
{"error_recovery", test_error_recovery}, {"error_recovery", test_error_recovery},
{NULL, NULL}, {nullptr, nullptr},
}; };
+213
View File
@@ -794,6 +794,138 @@ SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_r16(scc_mcode_t *mcode, int dst,
scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, modrm);
} }
// ==================== 符号/零扩展加载(内存操作数) ====================
/**
* @brief 从内存加载字节并符号扩展到 64 位 (movsx r64, byte ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器(存储地址)
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m8(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48; // REX.W = 1
if (dst >= 8)
rex |= 0x04; // REX.R
if (base >= 8)
rex |= 0x01; // REX.B
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x0F);
scc_mcode_add_u8(mcode, 0xBE); // MOVSX r64, r/m8
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
// 需要 SIB 字节 (base == RSP 或 R12)
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24); // SIB: [base] 无索引,base=4
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载字节并零扩展到 64 位 (movzx r64, byte ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_m8(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48;
if (dst >= 8)
rex |= 0x04;
if (base >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x0F);
scc_mcode_add_u8(mcode, 0xB6); // MOVZX r64, r/m8
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载16位并符号扩展到 64 位 (movsx r64, word ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m16(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48;
if (dst >= 8)
rex |= 0x04;
if (base >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x0F);
scc_mcode_add_u8(mcode, 0xBF); // MOVSX r64, r/m16
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载16位并零扩展到 64 位 (movzx r64, word ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_m16(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48;
if (dst >= 8)
rex |= 0x04;
if (base >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x0F);
scc_mcode_add_u8(mcode, 0xB7); // MOVZX r64, r/m16
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载32位并符号扩展到 64 位 (movsxd r64, dword ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m32(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48; // REX.W = 1, 对应 MOVSXD
if (dst >= 8)
rex |= 0x04;
if (base >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x63); // MOVSXD r64, r/m32
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
// ==================== 算术运算 ==================== // ==================== 算术运算 ====================
// ---------- 64 位 ---------- // ---------- 64 位 ----------
@@ -1670,6 +1802,74 @@ SCC_MCODE_FUNC void scc_mcode_amd64_xor_r64_imm32(scc_mcode_t *mcode, int dst,
scc_mcode_add_u32(mcode, imm); scc_mcode_add_u32(mcode, imm);
} }
/**
* @brief 64 位按位取反 NOT r64
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r64(scc_mcode_t *mcode, int dst) {
u8 rex = 0x48;
if (dst >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0xF7);
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
/**
* @brief 32 位按位取反 NOT r32
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r32(scc_mcode_t *mcode, int dst) {
u8 rex = 0x40; // REX.W=0
if (dst >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0xF7);
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
/**
* @brief 16 位按位取反 NOT r16
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r16(scc_mcode_t *mcode, int dst) {
scc_mcode_amd64_emit_width_prefix(mcode, 2);
u8 rex = 0x40;
if (dst >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0xF7);
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
/**
* @brief 8 位按位取反 NOT r8
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r8(scc_mcode_t *mcode, int dst) {
u8 rex = 0x40;
int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst);
if (dst >= 8)
rex |= 0x01;
if (need_rex) {
scc_mcode_add_u8(mcode, rex);
}
scc_mcode_add_u8(mcode, 0xF6); // 8位版本使用0xF6
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
// ==================== 移位 ==================== // ==================== 移位 ====================
// 提供 64 位示例,其他宽度可类似添加 // 提供 64 位示例,其他宽度可类似添加
@@ -1873,6 +2073,19 @@ SCC_MCODE_FUNC void scc_mcode_amd64_call_rel32(scc_mcode_t *mcode, u32 rel32) {
scc_mcode_add_u32(mcode, rel32); scc_mcode_add_u32(mcode, rel32);
} }
/**
* @brief 通过内存地址调用 (call [rip+disp32]) - 通常用于导入表调用
*
* @param mcode 机器码缓冲区
* @param disp 32 位相对偏移
*/
SCC_MCODE_FUNC void scc_mcode_amd64_call_mem_rip_rel32(scc_mcode_t *mcode,
u32 disp) {
scc_mcode_add_u8(mcode, 0xFF);
scc_mcode_add_u8(mcode, 0x15); // reg=010 (CALL), r/m=101 (RIP+disp32)
scc_mcode_add_u32(mcode, disp);
}
/** /**
* @brief 间接跳转 JMP r64 * @brief 间接跳转 JMP r64
* *
+10 -10
View File
@@ -5,20 +5,20 @@
static inline const scc_lexer_tok_t *scc_parser_peek(scc_parser_t *parser) { static inline const scc_lexer_tok_t *scc_parser_peek(scc_parser_t *parser) {
cbool ok = false; cbool ok = false;
const scc_lexer_tok_t *tok = null; const scc_lexer_tok_t *tok = nullptr;
scc_ring_unsafe_peek_ref(*parser->ring, tok, ok); scc_ring_unsafe_peek_ref(*parser->ring, tok, ok);
if (ok == false) { if (ok == false) {
return null; return nullptr;
} }
return tok; return tok;
} }
static inline const scc_lexer_tok_t *scc_parser_next(scc_parser_t *parser) { static inline const scc_lexer_tok_t *scc_parser_next(scc_parser_t *parser) {
cbool ok = false; cbool ok = false;
const scc_lexer_tok_t *tok = null; const scc_lexer_tok_t *tok = nullptr;
scc_ring_unsafe_next_ref(*parser->ring, tok, ok); scc_ring_unsafe_next_ref(*parser->ring, tok, ok);
if (ok == false) { if (ok == false) {
return null; return nullptr;
} }
return tok; return tok;
} }
@@ -26,10 +26,10 @@ static inline const scc_lexer_tok_t *scc_parser_next(scc_parser_t *parser) {
static inline cbool scc_parser_consume_if(scc_parser_t *parser, static inline cbool scc_parser_consume_if(scc_parser_t *parser,
scc_tok_type_t type) { scc_tok_type_t type) {
cbool ok = false; cbool ok = false;
scc_lexer_tok_t *tok = null; scc_lexer_tok_t *tok = nullptr;
scc_ring_unsafe_peek_ref(*parser->ring, tok, ok); scc_ring_unsafe_peek_ref(*parser->ring, tok, ok);
if (ok == false) { if (ok == false) {
return null; return nullptr;
} }
if (tok->type == type) { if (tok->type == type) {
scc_lexer_tok_drop(tok); scc_lexer_tok_drop(tok);
@@ -48,13 +48,13 @@ static inline void scc_parser_restore(scc_parser_t *parser) {
_scc_ring_probe(*parser->ring) = parser->checkpoint; _scc_ring_probe(*parser->ring) = parser->checkpoint;
} }
// tok can null it will be safty free // tok can nullptr it will be safty free
static inline cbool scc_parser_next_consume(scc_parser_t *parser, static inline cbool scc_parser_next_consume(scc_parser_t *parser,
scc_lexer_tok_t *tok) { scc_lexer_tok_t *tok) {
cbool ok = false; cbool ok = false;
scc_lexer_tok_t *raw_tok_ref = null; scc_lexer_tok_t *raw_tok_ref = nullptr;
scc_ring_unsafe_next_ref_consume(*parser->ring, raw_tok_ref, ok); scc_ring_unsafe_next_ref_consume(*parser->ring, raw_tok_ref, ok);
if (tok == null) { if (tok == nullptr) {
scc_lexer_tok_drop(raw_tok_ref); scc_lexer_tok_drop(raw_tok_ref);
} else { } else {
scc_lexer_tok_move(tok, raw_tok_ref); scc_lexer_tok_move(tok, raw_tok_ref);
@@ -75,7 +75,7 @@ static inline void scc_parser_reset(scc_parser_t *parser) {
static inline scc_pos_t scc_parser_got_current_pos(scc_parser_t *parser) { static inline scc_pos_t scc_parser_got_current_pos(scc_parser_t *parser) {
const scc_lexer_tok_t *tok = scc_parser_peek(parser); const scc_lexer_tok_t *tok = scc_parser_peek(parser);
scc_pos_t pos = scc_pos_create(); scc_pos_t pos = scc_pos_create();
if (tok != null) if (tok != nullptr)
pos = tok->loc; pos = tok->loc;
return pos; return pos;
} }
+1 -1
View File
@@ -27,7 +27,7 @@ typedef struct scc_parser {
* @brief 初始化解析器 * @brief 初始化解析器
* @param parser 解析器实例 * @param parser 解析器实例
* @param lexer 词法分析器实例 * @param lexer 词法分析器实例
* @param callbacks 语义分析回调(可为 null) * @param callbacks 语义分析回调(可为 nullptr)
*/ */
void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring, void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring,
scc_sema_callbacks_t *callbacks); scc_sema_callbacks_t *callbacks);
+33 -33
View File
@@ -173,10 +173,10 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
[ constant-expression ] [ constant-expression ]
. identifier . identifier
*/ */
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
scc_lexer_tok_t tok = {0}; scc_lexer_tok_t tok = {0};
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
scc_ast_expr_t *init = null; scc_ast_expr_t *init = nullptr;
if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE)) { if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE)) {
// TODO int a = 1, b = 1; // TODO int a = 1, b = 1;
init = scc_parse_assignment_expression(parser); init = scc_parse_assignment_expression(parser);
@@ -187,23 +187,23 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
scc_lexer_tok_drop(&tok); scc_lexer_tok_drop(&tok);
init = scc_malloc(sizeof(scc_ast_expr_t)); init = scc_malloc(sizeof(scc_ast_expr_t));
Assert(init != null); Assert(init != nullptr);
scc_ast_expr_vec_t lhs_exprs; scc_ast_expr_vec_t lhs_exprs;
scc_vec_init(lhs_exprs); scc_vec_init(lhs_exprs);
scc_ast_expr_vec_t rhs_exprs; scc_ast_expr_vec_t rhs_exprs;
scc_vec_init(rhs_exprs); scc_vec_init(rhs_exprs);
scc_ast_expr_t *lhs = null; scc_ast_expr_t *lhs = nullptr;
scc_ast_expr_t *rhs = null; scc_ast_expr_t *rhs = nullptr;
scc_ast_expr_t *ptr = base; scc_ast_expr_t *ptr = base;
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_DOT) { if (tok_ptr->type == SCC_TOK_DOT) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr && tok_ptr->type == SCC_TOK_IDENT) { if (tok_ptr && tok_ptr->type == SCC_TOK_IDENT) {
scc_parser_next_consume(parser, &tok); scc_parser_next_consume(parser, &tok);
lhs = scc_malloc(sizeof(scc_ast_expr_t)); lhs = scc_malloc(sizeof(scc_ast_expr_t));
Assert(lhs != null); Assert(lhs != nullptr);
scc_ast_expr_member_init(lhs, ptr, scc_str_as_cstr(&tok.lexeme), scc_ast_expr_member_init(lhs, ptr, scc_str_as_cstr(&tok.lexeme),
tok.loc); tok.loc);
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) { if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
@@ -211,7 +211,7 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
continue; continue;
} }
rhs = scc_parse_initializer(parser, lhs); rhs = scc_parse_initializer(parser, lhs);
if (rhs == null) { if (rhs == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected initializer"); "Expected initializer");
Panic(); Panic();
@@ -224,34 +224,34 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
"Expected 'identifier' after '.'"); "Expected 'identifier' after '.'");
} }
} else if (tok_ptr->type == SCC_TOK_L_BRACKET) { } else if (tok_ptr->type == SCC_TOK_L_BRACKET) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
scc_ast_expr_t *idx = scc_parser_constant_expression(parser); scc_ast_expr_t *idx = scc_parser_constant_expression(parser);
Assert(idx != null); Assert(idx != nullptr);
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ']'"); SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ']'");
} }
lhs = scc_malloc(sizeof(scc_ast_expr_t)); lhs = scc_malloc(sizeof(scc_ast_expr_t));
Assert(lhs != null); Assert(lhs != nullptr);
scc_ast_expr_array_subscript_init(lhs, ptr, idx, tok_ptr->loc); scc_ast_expr_array_subscript_init(lhs, ptr, idx, tok_ptr->loc);
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) { if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
ptr = lhs; ptr = lhs;
continue; continue;
} }
rhs = scc_parse_initializer(parser, lhs); rhs = scc_parse_initializer(parser, lhs);
Assert(rhs != null); Assert(rhs != nullptr);
scc_vec_push(lhs_exprs, lhs); scc_vec_push(lhs_exprs, lhs);
scc_vec_push(rhs_exprs, rhs); scc_vec_push(rhs_exprs, rhs);
ptr = base; ptr = base;
} else if (tok_ptr->type == SCC_TOK_R_BRACE) { } else if (tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
} else if (tok_ptr->type == SCC_TOK_COMMA) { } else if (tok_ptr->type == SCC_TOK_COMMA) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
continue; continue;
} else { } else {
// FIXME // FIXME
scc_ast_expr_t *expr = scc_parse_initializer(parser, base); scc_ast_expr_t *expr = scc_parse_initializer(parser, base);
scc_vec_push(lhs_exprs, null); scc_vec_push(lhs_exprs, nullptr);
scc_vec_push(rhs_exprs, expr); scc_vec_push(rhs_exprs, expr);
} }
} }
@@ -260,29 +260,29 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
} }
scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
scc_ast_decl_t *decl_list = null; scc_ast_decl_t *decl_list = nullptr;
scc_ast_decl_vec_t decl_list_vec; scc_ast_decl_vec_t decl_list_vec;
scc_vec_init(decl_list_vec); scc_vec_init(decl_list_vec);
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser); scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type == null) { if (type == nullptr) {
return null; return nullptr;
} }
scc_ast_decl_specifier_t spec = type->quals; scc_ast_decl_specifier_t spec = type->quals;
// FIXME drop typedef inline and ... // FIXME drop typedef inline and ...
type->quals.is_typedef = false; type->quals.is_typedef = false;
scc_ast_decl_t *decl = null; scc_ast_decl_t *decl = nullptr;
CONTINUE: CONTINUE:
decl = scc_parse_declarator(parser, type); decl = scc_parse_declarator(parser, type);
if (decl == null) { if (decl == nullptr) {
return null; return nullptr;
} }
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_ASSIGN) { if (tok_ptr->type == SCC_TOK_ASSIGN) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
// TODO maybe memory leak // TODO maybe memory leak
scc_ast_expr_t *lvalue = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *lvalue = scc_malloc(sizeof(scc_ast_expr_t));
scc_ast_expr_lvalue_init(lvalue, decl->var.type, decl->base.loc); scc_ast_expr_lvalue_init(lvalue, decl->var.type, decl->base.loc);
@@ -290,7 +290,7 @@ CONTINUE:
} else if (tok_ptr->type == SCC_TOK_L_BRACE) { } else if (tok_ptr->type == SCC_TOK_L_BRACE) {
scc_parse_decl_sema(parser, decl); scc_parse_decl_sema(parser, decl);
parser->sema_callbacks.on_decl(parser->sema_callbacks.context, parser->sema_callbacks.on_decl(parser->sema_callbacks.context,
scc_ast_decl_t_BEGIN, null); scc_ast_decl_t_BEGIN, nullptr);
scc_vec_foreach(decl->func.type->function.params, i) { scc_vec_foreach(decl->func.type->function.params, i) {
scc_ast_decl_t *param = scc_ast_decl_t *param =
scc_vec_at(decl->func.type->function.params, i); scc_vec_at(decl->func.type->function.params, i);
@@ -299,19 +299,19 @@ CONTINUE:
} }
scc_ast_stmt_t *body = scc_parse_statement(parser); scc_ast_stmt_t *body = scc_parse_statement(parser);
parser->sema_callbacks.on_decl(parser->sema_callbacks.context, parser->sema_callbacks.on_decl(parser->sema_callbacks.context,
scc_ast_decl_t_END, null); scc_ast_decl_t_END, nullptr);
Assert(decl->base.type == SCC_AST_DECL_FUNC); Assert(decl->base.type == SCC_AST_DECL_FUNC);
decl->func.body = body; decl->func.body = body;
Assert(decl->func.type != null); Assert(decl->func.type != nullptr);
Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION); Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION);
Assert(decl->func.body != null); Assert(decl->func.body != nullptr);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND); Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
goto RETURN; goto RETURN;
} }
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_SEMICOLON) { if (tok_ptr->type == SCC_TOK_SEMICOLON) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
if (decl_list) if (decl_list)
scc_vec_push(decl_list_vec, decl); scc_vec_push(decl_list_vec, decl);
if (spec.is_typedef) { if (spec.is_typedef) {
@@ -326,7 +326,7 @@ CONTINUE:
decl->base.loc); decl->base.loc);
} }
} }
if (decl_list != null) { if (decl_list != nullptr) {
scc_vec_foreach(decl_list_vec, i) { scc_vec_foreach(decl_list_vec, i) {
decl = scc_vec_at(decl_list_vec, i); decl = scc_vec_at(decl_list_vec, i);
scc_parse_decl_sema(parser, decl); scc_parse_decl_sema(parser, decl);
@@ -340,10 +340,10 @@ CONTINUE:
} }
goto RETURN; goto RETURN;
} else if (tok_ptr->type == SCC_TOK_COMMA) { } else if (tok_ptr->type == SCC_TOK_COMMA) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
if (decl_list == null) { if (decl_list == nullptr) {
decl_list = scc_malloc(sizeof(scc_ast_decl_t)); decl_list = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl_list != null); Assert(decl_list != nullptr);
scc_vec_push(decl_list_vec, decl); scc_vec_push(decl_list_vec, decl);
} else { } else {
Assert(scc_vec_size(decl_list_vec) != 0); Assert(scc_vec_size(decl_list_vec) != 0);
@@ -361,5 +361,5 @@ CONTINUE:
RETURN: RETURN:
return decl; return decl;
ERROR: ERROR:
return null; return nullptr;
} }
+61 -61
View File
@@ -324,7 +324,7 @@ static scc_ast_expr_op_t map_token_to_assign_op(scc_tok_type_t type) {
// 跳过直到遇到同步 token(分号、右括号、逗号、EOF) // 跳过直到遇到同步 token(分号、右括号、逗号、EOF)
static void parser_sync(scc_parser_t *parser) { static void parser_sync(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr; const scc_lexer_tok_t *tok_ptr;
while ((tok_ptr = scc_parser_peek(parser)) != null) { while ((tok_ptr = scc_parser_peek(parser)) != nullptr) {
scc_tok_type_t type = tok_ptr->type; scc_tok_type_t type = tok_ptr->type;
if (type == SCC_TOK_SEMICOLON || type == SCC_TOK_R_PAREN || if (type == SCC_TOK_SEMICOLON || type == SCC_TOK_R_PAREN ||
type == SCC_TOK_R_BRACE || type == SCC_TOK_COMMA || type == SCC_TOK_R_BRACE || type == SCC_TOK_COMMA ||
@@ -344,7 +344,7 @@ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
// 从最底层(cast-expression)开始 // 从最底层(cast-expression)开始
scc_ast_expr_t *left = parse_cast_expression(parser); scc_ast_expr_t *left = parse_cast_expression(parser);
if (!left) if (!left)
return null; return nullptr;
while (1) { while (1) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
@@ -367,11 +367,11 @@ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
parse_expression_with_precedence(parser, prec + 1); parse_expression_with_precedence(parser, prec + 1);
if (!right) { if (!right) {
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
// FIXME pos // FIXME pos
scc_ast_expr_binary_init(expr, op, left, right, left->base.loc); scc_ast_expr_binary_init(expr, op, left, right, left->base.loc);
left = expr; left = expr;
@@ -382,10 +382,10 @@ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) { scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
// 先解析左侧的 unary-expression(C 标准规定赋值左边必须是 // 先解析左侧的 unary-expression(C 标准规定赋值左边必须是
// unary-expression) // unary-expression)
scc_ast_expr_t *left = null; scc_ast_expr_t *left = nullptr;
left = parse_conditional_expression(parser); left = parse_conditional_expression(parser);
if (!left) if (!left)
return null; return nullptr;
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr) if (!tok_ptr)
@@ -406,11 +406,11 @@ scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
if (!right) { if (!right) {
// 错误恢复 // 错误恢复
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_binary_init(expr, op, left, right, pos); scc_ast_expr_binary_init(expr, op, left, right, pos);
left = expr; left = expr;
} }
@@ -422,7 +422,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
scc_ast_expr_t *cond_expr = scc_ast_expr_t *cond_expr =
parse_expression_with_precedence(parser, PREC_LOGICAL_OR); parse_expression_with_precedence(parser, PREC_LOGICAL_OR);
if (!cond_expr) if (!cond_expr)
return null; return nullptr;
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr && tok_ptr->type == SCC_TOK_COND) { if (tok_ptr && tok_ptr->type == SCC_TOK_COND) {
@@ -437,7 +437,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
scc_ast_expr_t *then_expr = scc_parse_expression(parser); scc_ast_expr_t *then_expr = scc_parse_expression(parser);
if (!then_expr) { if (!then_expr) {
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
// 消耗 ':' // 消耗 ':'
@@ -445,18 +445,18 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ':' after '?'"); "Expected ':' after '?'");
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
// 解析 else 部分(右结合,再次调用 parse_conditional_expression) // 解析 else 部分(右结合,再次调用 parse_conditional_expression)
scc_ast_expr_t *else_expr = parse_conditional_expression(parser); scc_ast_expr_t *else_expr = parse_conditional_expression(parser);
if (!else_expr) { if (!else_expr) {
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
scc_ast_expr_t *cond = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *cond = scc_malloc(sizeof(scc_ast_expr_t));
Assert(cond != null); Assert(cond != nullptr);
scc_ast_expr_cond_init(cond, cond_expr, then_expr, else_expr, pos); scc_ast_expr_cond_init(cond, cond_expr, then_expr, else_expr, pos);
cond_expr = cond; cond_expr = cond;
} }
@@ -466,7 +466,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
// 类型转换表达式 (type-name) cast-expression // 类型转换表达式 (type-name) cast-expression
static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) { static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
scc_ast_type_t *type = null; scc_ast_type_t *type = nullptr;
if (tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN) { if (tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN) {
// 尝试解析类型名 // 尝试解析类型名
scc_parser_store(parser); scc_parser_store(parser);
@@ -487,7 +487,7 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
return operand; return operand;
} }
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
// FIXME pos // FIXME pos
scc_ast_expr_cast_init(expr, type, operand, type->base.loc); scc_ast_expr_cast_init(expr, type, operand, type->base.loc);
return expr; return expr;
@@ -523,7 +523,7 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
*/ */
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr) if (!tok_ptr)
return null; return nullptr;
scc_lexer_tok_t tok = {0}; scc_lexer_tok_t tok = {0};
@@ -539,14 +539,14 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
case SCC_TOK_NOT: // !x case SCC_TOK_NOT: // !x
{ {
if (!scc_parser_next_consume(parser, &tok)) if (!scc_parser_next_consume(parser, &tok))
return null; return nullptr;
scc_ast_expr_op_t op = map_token_to_unary_op(tok.type, true); scc_ast_expr_op_t op = map_token_to_unary_op(tok.type, true);
scc_pos_t pos = tok.loc; scc_pos_t pos = tok.loc;
scc_lexer_tok_drop(&tok); scc_lexer_tok_drop(&tok);
// 一元运算符右结合,递归调用 parse_unary_expression // 一元运算符右结合,递归调用 parse_unary_expression
scc_ast_expr_t *operand = null; scc_ast_expr_t *operand = nullptr;
if (tok_ptr->type == SCC_TOK_ADD_ADD || if (tok_ptr->type == SCC_TOK_ADD_ADD ||
tok_ptr->type == SCC_TOK_SUB_SUB) { tok_ptr->type == SCC_TOK_SUB_SUB) {
operand = parse_unary_expression(parser); operand = parse_unary_expression(parser);
@@ -555,11 +555,11 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
} }
if (!operand) { if (!operand) {
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_unary_init(expr, op, operand, pos); scc_ast_expr_unary_init(expr, op, operand, pos);
return expr; return expr;
} }
@@ -575,7 +575,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
scc_lexer_tok_t tok_ptr; scc_lexer_tok_t tok_ptr;
if (!scc_parser_next_consume(parser, &tok_ptr) || if (!scc_parser_next_consume(parser, &tok_ptr) ||
tok_ptr.type != SCC_TOK_SIZEOF) { tok_ptr.type != SCC_TOK_SIZEOF) {
return null; return nullptr;
} }
scc_pos_t pos = tok_ptr.loc; scc_pos_t pos = tok_ptr.loc;
scc_lexer_tok_drop(&tok_ptr); scc_lexer_tok_drop(&tok_ptr);
@@ -584,7 +584,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
if (!next) { if (!next) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected end after sizeof"); "Unexpected end after sizeof");
return null; return nullptr;
} }
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
@@ -593,7 +593,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
scc_parser_store(parser); scc_parser_store(parser);
scc_parser_next(parser); scc_parser_next(parser);
scc_ast_type_t *type_name = scc_parse_type_name(parser); scc_ast_type_t *type_name = scc_parse_type_name(parser);
if (type_name == null) { if (type_name == nullptr) {
scc_parser_restore(parser); scc_parser_restore(parser);
goto next; goto next;
} }
@@ -603,15 +603,15 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
"expected ')' after type-name in sizeof expression"); "expected ')' after type-name in sizeof expression");
} }
Assert(type_name != null); Assert(type_name != nullptr);
scc_ast_expr_sizeof_init(expr, type_name, null, pos); scc_ast_expr_sizeof_init(expr, type_name, nullptr, pos);
return expr; return expr;
} }
next: next:
// 尝试解析 sizeof unary-expression // 尝试解析 sizeof unary-expression
scc_ast_expr_t *operand = parse_unary_expression(parser); scc_ast_expr_t *operand = parse_unary_expression(parser);
if (operand != null) { if (operand != nullptr) {
scc_ast_expr_sizeof_init(expr, null, operand, pos); scc_ast_expr_sizeof_init(expr, nullptr, operand, pos);
return expr; return expr;
} }
@@ -622,12 +622,12 @@ next:
// 后缀表达式 // 后缀表达式
static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) { static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
scc_ast_expr_t *left = parse_primary_expression(parser); scc_ast_expr_t *left = parse_primary_expression(parser);
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
scc_pos_t pos = scc_pos_create(); scc_pos_t pos = scc_pos_create();
if (!left) { if (!left) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN)) { if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN)) {
return null; return nullptr;
} }
pos = tok_ptr->loc; pos = tok_ptr->loc;
@@ -636,7 +636,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
scc_ast_type_t *type = scc_parse_type_name(parser); scc_ast_type_t *type = scc_parse_type_name(parser);
if (!type) { if (!type) {
scc_parser_restore(parser); scc_parser_restore(parser);
return null; return nullptr;
} }
scc_parser_commit(parser); scc_parser_commit(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
@@ -656,30 +656,30 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
switch (tok_ptr->type) { switch (tok_ptr->type) {
case SCC_TOK_L_BRACKET: // left[expr] case SCC_TOK_L_BRACKET: // left[expr]
{ {
if (!scc_parser_next_consume(parser, null)) if (!scc_parser_next_consume(parser, nullptr))
return left; return left;
pos = left->base.loc; pos = left->base.loc;
scc_ast_expr_t *index = scc_parse_expression(parser); scc_ast_expr_t *index = scc_parse_expression(parser);
if (!index) { if (!index) {
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ']' after subscript"); "Expected ']' after subscript");
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
scc_ast_expr_t *subscript = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *subscript = scc_malloc(sizeof(scc_ast_expr_t));
Assert(subscript != null); Assert(subscript != nullptr);
scc_ast_expr_array_subscript_init(subscript, left, index, pos); scc_ast_expr_array_subscript_init(subscript, left, index, pos);
left = subscript; left = subscript;
break; break;
} }
case SCC_TOK_L_PAREN: // left(args) case SCC_TOK_L_PAREN: // left(args)
{ {
if (!scc_parser_next_consume(parser, null)) if (!scc_parser_next_consume(parser, nullptr))
return left; return left;
pos = left->base.loc; pos = left->base.loc;
scc_ast_expr_vec_t args; scc_ast_expr_vec_t args;
@@ -705,11 +705,11 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
// 释放已解析的参数 // 释放已解析的参数
// TODO: 释放 args 中的表达式 // TODO: 释放 args 中的表达式
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
} }
scc_ast_expr_t *call = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *call = scc_malloc(sizeof(scc_ast_expr_t));
Assert(call != null); Assert(call != nullptr);
scc_ast_expr_call_init(call, left, &args, pos); scc_ast_expr_call_init(call, left, &args, pos);
left = call; left = call;
break; break;
@@ -726,12 +726,12 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
"Expected identifier after member access"); "Expected identifier after member access");
scc_lexer_tok_drop(&op_tok); scc_lexer_tok_drop(&op_tok);
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
const char *name = scc_str_as_cstr(&ident_tok.lexeme); const char *name = scc_str_as_cstr(&ident_tok.lexeme);
scc_ast_expr_t *member = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *member = scc_malloc(sizeof(scc_ast_expr_t));
Assert(member != null); Assert(member != nullptr);
if (op_tok.type == SCC_TOK_DOT) { if (op_tok.type == SCC_TOK_DOT) {
scc_ast_expr_member_init(member, left, name, ident_tok.loc); scc_ast_expr_member_init(member, left, name, ident_tok.loc);
} else { } else {
@@ -750,7 +750,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
return left; return left;
scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false); scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false);
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_unary_init(expr, op, left, op_tok.loc); scc_ast_expr_unary_init(expr, op, left, op_tok.loc);
scc_lexer_tok_drop(&op_tok); scc_lexer_tok_drop(&op_tok);
left = expr; left = expr;
@@ -776,43 +776,43 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
*/ */
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr) if (!tok_ptr)
return null; return nullptr;
scc_lexer_tok_t tok = {0}; scc_lexer_tok_t tok = {0};
scc_ast_expr_t *expr = null; scc_ast_expr_t *expr = nullptr;
switch (tok_ptr->type) { switch (tok_ptr->type) {
case SCC_TOK_IDENT: { case SCC_TOK_IDENT: {
if (!scc_parser_next_consume(parser, &tok)) if (!scc_parser_next_consume(parser, &tok))
return null; return nullptr;
expr = scc_malloc(sizeof(scc_ast_expr_t)); expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_identifier_init(expr, scc_str_as_cstr(&tok.lexeme), scc_ast_expr_identifier_init(expr, scc_str_as_cstr(&tok.lexeme),
tok.loc); tok.loc);
break; break;
} }
case SCC_TOK_INT_LITERAL: { case SCC_TOK_INT_LITERAL: {
if (!scc_parser_next_consume(parser, &tok)) if (!scc_parser_next_consume(parser, &tok))
return null; return nullptr;
expr = scc_malloc(sizeof(scc_ast_expr_t)); expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_literal_int_init(expr, scc_str_as_cstr(&tok.lexeme), false, scc_ast_expr_literal_int_init(expr, scc_str_as_cstr(&tok.lexeme), false,
tok.loc); tok.loc);
break; break;
} }
case SCC_TOK_FLOAT_LITERAL: { case SCC_TOK_FLOAT_LITERAL: {
if (!scc_parser_next_consume(parser, &tok)) if (!scc_parser_next_consume(parser, &tok))
return null; return nullptr;
expr = scc_malloc(sizeof(scc_ast_expr_t)); expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_literal_float_init(expr, scc_str_as_cstr(&tok.lexeme), scc_ast_expr_literal_float_init(expr, scc_str_as_cstr(&tok.lexeme),
false, tok.loc); false, tok.loc);
break; break;
} }
case SCC_TOK_CHAR_LITERAL: { case SCC_TOK_CHAR_LITERAL: {
if (!scc_parser_next_consume(parser, &tok)) if (!scc_parser_next_consume(parser, &tok))
return null; return nullptr;
expr = scc_malloc(sizeof(scc_ast_expr_t)); expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_literal_char_init(expr, scc_str_as_cstr(&tok.lexeme), scc_ast_expr_literal_char_init(expr, scc_str_as_cstr(&tok.lexeme),
false, tok.loc); false, tok.loc);
break; break;
@@ -822,7 +822,7 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
scc_lexer_tok_t tok; scc_lexer_tok_t tok;
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
break; break;
} }
if (tok_ptr->type != SCC_TOK_STRING_LITERAL) { if (tok_ptr->type != SCC_TOK_STRING_LITERAL) {
@@ -835,14 +835,14 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
} }
expr = scc_malloc(sizeof(scc_ast_expr_t)); expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
// FIXME loc // FIXME loc
scc_ast_expr_literal_string_init(expr, scc_str_as_cstr(&string), true, scc_ast_expr_literal_string_init(expr, scc_str_as_cstr(&string), true,
tok.loc); tok.loc);
break; break;
} }
case SCC_TOK_L_PAREN: case SCC_TOK_L_PAREN:
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
expr = scc_parse_expression(parser); expr = scc_parse_expression(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
@@ -853,8 +853,8 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
break; break;
} }
if (expr == null) { if (expr == nullptr) {
return null; return nullptr;
} }
scc_parse_expr_sema(parser, expr); scc_parse_expr_sema(parser, expr);
return expr; return expr;
@@ -863,24 +863,24 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) { scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
scc_ast_expr_t *left = scc_parse_assignment_expression(parser); scc_ast_expr_t *left = scc_parse_assignment_expression(parser);
if (!left) if (!left)
return null; return nullptr;
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null || tok_ptr->type != SCC_TOK_COMMA) { if (tok_ptr == nullptr || tok_ptr->type != SCC_TOK_COMMA) {
break; break;
} }
scc_pos_t pos = tok_ptr->loc; scc_pos_t pos = tok_ptr->loc;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
scc_ast_expr_t *right = scc_parse_assignment_expression(parser); scc_ast_expr_t *right = scc_parse_assignment_expression(parser);
if (!right) { if (!right) {
parser_sync(parser); parser_sync(parser);
return null; return nullptr;
} }
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null); Assert(expr != nullptr);
scc_ast_expr_binary_init(expr, SCC_AST_OP_COMMA, left, right, pos); scc_ast_expr_binary_init(expr, SCC_AST_OP_COMMA, left, right, pos);
left = expr; left = expr;
} }
+38 -38
View File
@@ -52,7 +52,7 @@ A.2.3 Statements
static inline scc_ast_stmt_t *ast_stmt_alloc() { static inline scc_ast_stmt_t *ast_stmt_alloc() {
scc_ast_stmt_t *stmt = (scc_ast_stmt_t *)scc_malloc(sizeof(scc_ast_stmt_t)); scc_ast_stmt_t *stmt = (scc_ast_stmt_t *)scc_malloc(sizeof(scc_ast_stmt_t));
if (stmt == null) { if (stmt == nullptr) {
LOG_FATAL("Out of memory"); LOG_FATAL("Out of memory");
} }
return stmt; return stmt;
@@ -77,7 +77,7 @@ static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
scc_lexer_tok_t tok = {0}; scc_lexer_tok_t tok = {0};
if (!scc_parser_next_consume(parser, &tok)) { if (!scc_parser_next_consume(parser, &tok)) {
return null; return nullptr;
} }
if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) { if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) {
@@ -86,12 +86,12 @@ static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser,
} }
scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) { if (statement == nullptr) {
Panic("expect stmt"); Panic("expect stmt");
} }
scc_ast_stmt_t *stmt = ast_stmt_alloc(); scc_ast_stmt_t *stmt = ast_stmt_alloc();
Assert(stmt != null); Assert(stmt != nullptr);
scc_ast_stmt_label_init(stmt, scc_str_as_cstr(&tok.lexeme), statement, pos); scc_ast_stmt_label_init(stmt, scc_str_as_cstr(&tok.lexeme), statement, pos);
return stmt; return stmt;
} }
@@ -99,25 +99,25 @@ static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_case_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_case_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_CASE)) { if (!scc_parser_consume_if(parser, SCC_TOK_CASE)) {
return null; return nullptr;
} }
scc_ast_expr_t *expr = null; scc_ast_expr_t *expr = nullptr;
expr = scc_parser_constant_expression(parser); expr = scc_parser_constant_expression(parser);
if (expr == null) { if (expr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected constant expression after case."); "Expected constant expression after case.");
return null; return nullptr;
} }
if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) { if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected `:` after case."); "Expected `:` after case.");
return null; return nullptr;
} }
scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) { if (statement == nullptr) {
Panic("expect stmt"); Panic("expect stmt");
} }
@@ -129,17 +129,17 @@ static scc_ast_stmt_t *parse_case_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_default_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_default_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_DEFAULT)) { if (!scc_parser_consume_if(parser, SCC_TOK_DEFAULT)) {
return null; return nullptr;
} }
if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) { if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected constant expression after case."); "Expected constant expression after case.");
return null; return nullptr;
} }
scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) { if (statement == nullptr) {
Panic("expect stmt"); Panic("expect stmt");
} }
@@ -151,31 +151,31 @@ static scc_ast_stmt_t *parse_default_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACE)) { if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACE)) {
return null; return nullptr;
} }
scc_ast_block_item_vec_t block_items; scc_ast_block_item_vec_t block_items;
scc_vec_init(block_items); scc_vec_init(block_items);
parser->sema_callbacks.on_stmt(parser->sema_callbacks.context, parser->sema_callbacks.on_stmt(parser->sema_callbacks.context,
scc_ast_stmt_t_BEGIN, null); scc_ast_stmt_t_BEGIN, nullptr);
while (!scc_parser_consume_if(parser, SCC_TOK_R_BRACE)) { while (!scc_parser_consume_if(parser, SCC_TOK_R_BRACE)) {
/// TODO /// TODO
// scc_parse_is_decl(); // scc_parse_is_decl();
scc_ast_node_t *ret = null; scc_ast_node_t *ret = nullptr;
ret = (scc_ast_node_t *)scc_parse_declaration(parser); ret = (scc_ast_node_t *)scc_parse_declaration(parser);
if (ret == null) { if (ret == nullptr) {
ret = (scc_ast_node_t *)scc_parse_statement(parser); ret = (scc_ast_node_t *)scc_parse_statement(parser);
} }
if (ret == null) { if (ret == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Invalid statement"); SCC_ERROR(scc_parser_got_current_pos(parser), "Invalid statement");
// TODO free // TODO free
parser->errcode = 1; parser->errcode = 1;
return null; return nullptr;
} }
scc_vec_push(block_items, ret); scc_vec_push(block_items, ret);
} }
parser->sema_callbacks.on_stmt(parser->sema_callbacks.context, parser->sema_callbacks.on_stmt(parser->sema_callbacks.context,
scc_ast_stmt_t_END, null); scc_ast_stmt_t_END, nullptr);
scc_ast_stmt_t *stmt = ast_stmt_alloc(); scc_ast_stmt_t *stmt = ast_stmt_alloc();
scc_ast_stmt_compound_init(stmt, &block_items, pos); scc_ast_stmt_compound_init(stmt, &block_items, pos);
@@ -184,17 +184,17 @@ static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_if_statement(scc_parser_t *parser, scc_pos_t pos) { static scc_ast_stmt_t *parse_if_statement(scc_parser_t *parser, scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_IF)) { if (!scc_parser_consume_if(parser, SCC_TOK_IF)) {
return null; return nullptr;
} }
scc_ast_expr_t *expression = ast_parse_paren_expression(parser); scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *statement = scc_parse_statement(parser);
scc_ast_stmt_t *opt_else = null; scc_ast_stmt_t *opt_else = nullptr;
if (scc_parser_consume_if(parser, SCC_TOK_ELSE)) { if (scc_parser_consume_if(parser, SCC_TOK_ELSE)) {
opt_else = scc_parse_statement(parser); opt_else = scc_parse_statement(parser);
} else { } else {
opt_else = null; opt_else = nullptr;
} }
scc_ast_stmt_t *stmt = ast_stmt_alloc(); scc_ast_stmt_t *stmt = ast_stmt_alloc();
@@ -205,7 +205,7 @@ static scc_ast_stmt_t *parse_if_statement(scc_parser_t *parser, scc_pos_t pos) {
static scc_ast_stmt_t *parse_switch_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_switch_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_SWITCH)) { if (!scc_parser_consume_if(parser, SCC_TOK_SWITCH)) {
return null; return nullptr;
} }
scc_ast_expr_t *expression = ast_parse_paren_expression(parser); scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
@@ -219,7 +219,7 @@ static scc_ast_stmt_t *parse_switch_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_while_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_while_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_WHILE)) { if (!scc_parser_consume_if(parser, SCC_TOK_WHILE)) {
return null; return nullptr;
} }
scc_ast_expr_t *expression = ast_parse_paren_expression(parser); scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
@@ -233,7 +233,7 @@ static scc_ast_stmt_t *parse_while_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_DO)) { if (!scc_parser_consume_if(parser, SCC_TOK_DO)) {
return null; return nullptr;
} }
scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *statement = scc_parse_statement(parser);
@@ -243,7 +243,7 @@ static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser,
"Expected 'while' after do."); "Expected 'while' after do.");
// TODO 使用更好的错误处理,未来应当采用更好的内存管理器 // TODO 使用更好的错误处理,未来应当采用更好的内存管理器
scc_free(statement); scc_free(statement);
return null; return nullptr;
} }
scc_ast_expr_t *expression = ast_parse_paren_expression(parser); scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
@@ -255,7 +255,7 @@ static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser,
static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser, static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser,
scc_pos_t pos) { scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_FOR)) { if (!scc_parser_consume_if(parser, SCC_TOK_FOR)) {
return null; return nullptr;
} }
/* /*
@@ -268,14 +268,14 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser,
"Expected '(' before like `( expression )` ."); "Expected '(' before like `( expression )` .");
} }
scc_ast_node_t *init = null; scc_ast_node_t *init = nullptr;
scc_ast_expr_t *cond = null; scc_ast_expr_t *cond = nullptr;
scc_ast_expr_t *incr = null; scc_ast_expr_t *incr = nullptr;
scc_ast_stmt_t *body = null; scc_ast_stmt_t *body = nullptr;
// TODO use decl or expr // TODO use decl or expr
init = (scc_ast_node_t *)scc_parse_declaration(parser); init = (scc_ast_node_t *)scc_parse_declaration(parser);
if (init == null) { if (init == nullptr) {
init = (scc_ast_node_t *)scc_parse_expression(parser); init = (scc_ast_node_t *)scc_parse_expression(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
@@ -338,13 +338,13 @@ static scc_ast_stmt_t *parse_expression_statement(scc_parser_t *parser,
if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
scc_ast_stmt_t *stmt = ast_stmt_alloc(); scc_ast_stmt_t *stmt = ast_stmt_alloc();
scc_ast_stmt_expr_init(stmt, null, pos); scc_ast_stmt_expr_init(stmt, nullptr, pos);
return stmt; return stmt;
} }
scc_ast_expr_t *expr = scc_parse_expression(parser); scc_ast_expr_t *expr = scc_parse_expression(parser);
if (expr == null) { if (expr == nullptr) {
return null; return nullptr;
} }
scc_ast_stmt_t *stmt = ast_stmt_alloc(); scc_ast_stmt_t *stmt = ast_stmt_alloc();
@@ -362,7 +362,7 @@ scc_ast_stmt_t *scc_parse_statement(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ref; const scc_lexer_tok_t *tok_ref;
tok_ref = scc_parser_peek(parser); tok_ref = scc_parser_peek(parser);
if (!tok_ref) { if (!tok_ref) {
return null; return nullptr;
} }
scc_pos_t pos = tok_ref->loc; scc_pos_t pos = tok_ref->loc;
switch (tok_ref->type) { switch (tok_ref->type) {
@@ -376,7 +376,7 @@ scc_ast_stmt_t *scc_parse_statement(scc_parser_t *parser) {
case SCC_TOK_IDENT: case SCC_TOK_IDENT:
scc_parser_next(parser); scc_parser_next(parser);
tok_ref = scc_parser_next(parser); tok_ref = scc_parser_next(parser);
if (tok_ref == null || tok_ref->type != SCC_TOK_COLON) { if (tok_ref == nullptr || tok_ref->type != SCC_TOK_COLON) {
scc_parser_reset(parser); scc_parser_reset(parser);
break; break;
} }
+131 -129
View File
@@ -177,7 +177,7 @@ parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
static inline scc_ast_type_t *ast_type_alloc() { static inline scc_ast_type_t *ast_type_alloc() {
scc_ast_type_t *ast_type = scc_malloc(sizeof(scc_ast_type_t)); scc_ast_type_t *ast_type = scc_malloc(sizeof(scc_ast_type_t));
ast_type->base.type = SCC_AST_UNKNOWN; ast_type->base.type = SCC_AST_UNKNOWN;
if (ast_type == null) { if (ast_type == nullptr) {
LOG_FATAL("Out of memory"); LOG_FATAL("Out of memory");
} }
return ast_type; return ast_type;
@@ -194,7 +194,7 @@ static inline scc_ast_type_t *ast_type_alloc() {
*/ */
cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) { cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return false; return false;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -230,7 +230,7 @@ cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) {
// typedef 名称(标识符也可能是类型说明符) // typedef 名称(标识符也可能是类型说明符)
case SCC_TOK_IDENT: case SCC_TOK_IDENT:
return scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)) != return scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)) !=
null; nullptr;
default: default:
return false; return false;
} }
@@ -238,7 +238,7 @@ cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) {
cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) { cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return false; return false;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -261,7 +261,7 @@ cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) {
case SCC_TOK_IDENT: case SCC_TOK_IDENT:
// 需要检查标识符是否在符号表中定义为 typedef // 需要检查标识符是否在符号表中定义为 typedef
return scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)) != return scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)) !=
null; nullptr;
default: default:
return false; return false;
} }
@@ -269,7 +269,7 @@ cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) {
cbool scc_parse_is_type_qualifier_start(scc_parser_t *parser) { cbool scc_parse_is_type_qualifier_start(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return false; return false;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -285,7 +285,7 @@ cbool scc_parse_is_type_qualifier_start(scc_parser_t *parser) {
cbool scc_parse_is_storage_class_start(scc_parser_t *parser) { cbool scc_parse_is_storage_class_start(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return false; return false;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -320,10 +320,10 @@ parse_type_qualifier_list(scc_parser_t *parser,
type-qualifier type-qualifier
type-qualifier-list type-qualifier type-qualifier-list type-qualifier
*/ */
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
CONTINUE: CONTINUE:
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return quals; return quals;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -340,7 +340,7 @@ CONTINUE:
default: default:
return quals; return quals;
} }
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
goto CONTINUE; goto CONTINUE;
duplicate_error: duplicate_error:
SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier"); SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier");
@@ -350,10 +350,10 @@ duplicate_error:
static scc_ast_decl_specifier_t static scc_ast_decl_specifier_t
parse_declaration_specifiers_list(scc_parser_t *parser, parse_declaration_specifiers_list(scc_parser_t *parser,
scc_ast_decl_specifier_t quals) { scc_ast_decl_specifier_t quals) {
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
CONTINUE: CONTINUE:
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return quals; return quals;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -385,7 +385,7 @@ CONTINUE:
default: default:
return quals; return quals;
} }
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
goto CONTINUE; goto CONTINUE;
duplicate_error: duplicate_error:
SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier"); SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier");
@@ -459,7 +459,7 @@ static cbool check_type_combinations(scc_parser_t *parser,
return false; return false;
} }
// 如果用户定义了类型(struct/typedef),不能与任何其他类型说明符混合 // 如果用户定义了类型(struct/typedef),不能与任何其他类型说明符混合
if (info->user_type != null && basic_count > 0) { if (info->user_type != nullptr && basic_count > 0) {
SCC_ERROR( SCC_ERROR(
scc_parser_got_current_pos(parser), scc_parser_got_current_pos(parser),
"Cannot combine user-defined type with basic type specifiers"); "Cannot combine user-defined type with basic type specifiers");
@@ -574,12 +574,12 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
scc_lexer_tok_drop(&tok); scc_lexer_tok_drop(&tok);
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Unexpected EOF"); SCC_ERROR(scc_parser_got_current_pos(parser), "Unexpected EOF");
return null; return nullptr;
} }
const char *name = null; const char *name = nullptr;
scc_ast_decl_t *decl = null; scc_ast_decl_t *decl = nullptr;
scc_ast_decl_vec_t member; scc_ast_decl_vec_t member;
scc_vec_init(member); scc_vec_init(member);
@@ -590,19 +590,19 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
} }
if (tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE) { if (tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected EOF in enum specifier"); "Unexpected EOF in enum specifier");
break; break;
} }
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser); scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type != null) { if (type != nullptr) {
decl = scc_parse_declarator(parser, type); decl = scc_parse_declarator(parser, type);
if (decl != null) { if (decl != nullptr) {
scc_vec_push(member, decl); scc_vec_push(member, decl);
continue; continue;
} }
@@ -610,20 +610,20 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
if (tok_ptr->type == SCC_TOK_SEMICOLON) { if (tok_ptr->type == SCC_TOK_SEMICOLON) {
// FIXME check semicolon // FIXME check semicolon
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
} else if (tok_ptr->type == SCC_TOK_R_BRACE) { } else if (tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
} else { } else {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected token in struct/union specifier"); "Unexpected token in struct/union specifier");
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
} }
} }
decl = scc_malloc(sizeof(scc_ast_decl_t)); decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null); Assert(decl != nullptr);
if (type_kind == SCC_AST_TYPE_STRUCT) { if (type_kind == SCC_AST_TYPE_STRUCT) {
scc_ast_decl_struct_init(decl, name, &member, pos); scc_ast_decl_struct_init(decl, name, &member, pos);
} else { } else {
@@ -631,11 +631,11 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
} }
scc_parse_decl_sema(parser, decl); scc_parse_decl_sema(parser, decl);
} else { } else {
if (name == null) { if (name == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected name in struct/union specifier"); "Expected name in struct/union specifier");
// FIXME memory leak // FIXME memory leak
return null; return nullptr;
} }
} }
@@ -665,18 +665,18 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
scc_pos_t pos = tok.loc; scc_pos_t pos = tok.loc;
if (tok.type != SCC_TOK_ENUM) { if (tok.type != SCC_TOK_ENUM) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expected 'enum'"); SCC_ERROR(scc_parser_got_current_pos(parser), "Expected 'enum'");
return null; return nullptr;
} }
scc_lexer_tok_drop(&tok); scc_lexer_tok_drop(&tok);
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Unexpected EOF"); SCC_ERROR(scc_parser_got_current_pos(parser), "Unexpected EOF");
return null; return nullptr;
} }
scc_ast_type_t *type = ast_type_alloc(); scc_ast_type_t *type = ast_type_alloc();
const char *name = null; const char *name = nullptr;
scc_ast_decl_t *decl = null; scc_ast_decl_t *decl = nullptr;
scc_ast_decl_vec_t member; scc_ast_decl_vec_t member;
scc_vec_init(member); scc_vec_init(member);
@@ -687,10 +687,10 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
} }
if (tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE) { if (tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected EOF in enum specifier"); "Unexpected EOF in enum specifier");
break; break;
@@ -703,13 +703,13 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
break; break;
} }
scc_ast_expr_t *enum_item_init = null; scc_ast_expr_t *enum_item_init = nullptr;
if (scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) { if (scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
enum_item_init = scc_parser_constant_expression(parser); enum_item_init = scc_parser_constant_expression(parser);
} }
scc_ast_decl_t *enum_item_decl = scc_malloc(sizeof(scc_ast_decl_t)); scc_ast_decl_t *enum_item_decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(enum_item_decl != null); Assert(enum_item_decl != nullptr);
scc_ast_decl_val_init(enum_item_decl, type, scc_ast_decl_val_init(enum_item_decl, type,
scc_str_as_cstr(&tok.lexeme), enum_item_init, scc_str_as_cstr(&tok.lexeme), enum_item_init,
tok.loc); tok.loc);
@@ -719,34 +719,35 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
cbool got_comma = false; cbool got_comma = false;
if (tok_ptr && tok_ptr->type == SCC_TOK_COMMA) { if (tok_ptr && tok_ptr->type == SCC_TOK_COMMA) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
got_comma = true; got_comma = true;
} }
if (tok_ptr && tok_ptr->type == SCC_TOK_R_BRACE) { if (tok_ptr && tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
} else { } else {
if (got_comma) { if (got_comma) {
continue; continue;
} }
SCC_ERROR(tok_ptr != null ? tok_ptr->loc SCC_ERROR(tok_ptr != nullptr
: scc_parser_got_current_pos(parser), ? tok_ptr->loc
: scc_parser_got_current_pos(parser),
"Unexpected token in enum specifier"); "Unexpected token in enum specifier");
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
} }
} }
decl = scc_malloc(sizeof(scc_ast_decl_t)); decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null); Assert(decl != nullptr);
scc_ast_decl_enum_init(decl, name, &member, pos); scc_ast_decl_enum_init(decl, name, &member, pos);
scc_parse_decl_sema(parser, decl); scc_parse_decl_sema(parser, decl);
} else { } else {
if (name == null) { if (name == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected name in enum specifier"); "Expected name in enum specifier");
// FIXME memory leak // FIXME memory leak
return null; return nullptr;
} }
} }
@@ -757,11 +758,11 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) { static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
type_spec_info_t info = {0}; type_spec_info_t info = {0};
if (!scc_parse_is_type_specifier_start(parser)) if (!scc_parse_is_type_specifier_start(parser))
return null; return nullptr;
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return null; return nullptr;
} }
scc_pos_t pos = tok_ptr->loc; scc_pos_t pos = tok_ptr->loc;
@@ -778,13 +779,13 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
case SCC_TOK_IDENT: case SCC_TOK_IDENT:
info.user_type = info.user_type =
scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)); scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme));
if (info.user_type == null) { if (info.user_type == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected type specifier %s", "Expected type specifier %s",
scc_str_as_cstr(&tok_ptr->lexeme)); scc_str_as_cstr(&tok_ptr->lexeme));
} }
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
Assert(info.user_type != null); Assert(info.user_type != nullptr);
goto done; goto done;
default: default:
break; break;
@@ -792,7 +793,7 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
break; break;
} }
switch (tok_ptr->type) { switch (tok_ptr->type) {
@@ -800,32 +801,32 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
if (info.is_void) if (info.is_void)
goto duplicate_error; goto duplicate_error;
info.is_void = true; info.is_void = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_CHAR: case SCC_TOK_CHAR:
if (info.is_char) if (info.is_char)
goto duplicate_error; goto duplicate_error;
info.is_char = true; info.is_char = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_SHORT: case SCC_TOK_SHORT:
if (info.is_short) if (info.is_short)
goto duplicate_error; goto duplicate_error;
info.is_short = true; info.is_short = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_INT: case SCC_TOK_INT:
if (info.is_int) if (info.is_int)
goto duplicate_error; goto duplicate_error;
info.is_int = true; info.is_int = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_LONG: case SCC_TOK_LONG:
// long 可以出现两次 // long 可以出现两次
if (info.is_long_long) { if (info.is_long_long) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Three 'long's in type specifier"); "Three 'long's in type specifier");
return null; return nullptr;
} }
if (info.is_long) { if (info.is_long) {
info.is_long_long = true; info.is_long_long = true;
@@ -833,49 +834,49 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
} else { } else {
info.is_long = true; info.is_long = true;
} }
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_FLOAT: case SCC_TOK_FLOAT:
if (info.is_float) if (info.is_float)
goto duplicate_error; goto duplicate_error;
info.is_float = true; info.is_float = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_DOUBLE: case SCC_TOK_DOUBLE:
if (info.is_double) if (info.is_double)
goto duplicate_error; goto duplicate_error;
info.is_double = true; info.is_double = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_BOOL: case SCC_TOK_BOOL:
if (info.is_bool) if (info.is_bool)
goto duplicate_error; goto duplicate_error;
info.is_bool = true; info.is_bool = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_SIGNED: case SCC_TOK_SIGNED:
if (info.is_unsigned || info.is_signed) { if (info.is_unsigned || info.is_signed) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Both 'signed' and 'unsigned' in type specifier"); "Both 'signed' and 'unsigned' in type specifier");
return null; return nullptr;
} }
info.is_signed = true; info.is_signed = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_UNSIGNED: case SCC_TOK_UNSIGNED:
if (info.is_unsigned || info.is_signed) { if (info.is_unsigned || info.is_signed) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Both 'signed' and 'unsigned' in type specifier"); "Both 'signed' and 'unsigned' in type specifier");
return null; return nullptr;
} }
info.is_unsigned = true; info.is_unsigned = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
case SCC_TOK_COMPLEX: case SCC_TOK_COMPLEX:
if (info.is_complex) if (info.is_complex)
goto duplicate_error; goto duplicate_error;
info.is_complex = true; info.is_complex = true;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
break; break;
default: default:
goto done; goto done;
@@ -883,12 +884,12 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
} }
done: done:
if (!check_type_combinations(parser, &info)) { if (!check_type_combinations(parser, &info)) {
return null; return nullptr;
} }
return build_type_from_info(&info, pos); return build_type_from_info(&info, pos);
duplicate_error: duplicate_error:
SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier"); SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier");
return null; return nullptr;
} }
static scc_ast_type_t *parse_pointer(scc_parser_t *parser, static scc_ast_type_t *parse_pointer(scc_parser_t *parser,
@@ -900,15 +901,15 @@ static scc_ast_type_t *parse_pointer(scc_parser_t *parser,
* type-qualifier-list(opt) pointer * type-qualifier-list(opt) pointer
*/ */
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null || tok_ptr->type != SCC_TOK_MUL) { if (tok_ptr == nullptr || tok_ptr->type != SCC_TOK_MUL) {
return pointee; return pointee;
} }
scc_pos_t pos = tok_ptr->loc; scc_pos_t pos = tok_ptr->loc;
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
scc_ast_type_t *pointer = ast_type_alloc(); scc_ast_type_t *pointer = ast_type_alloc();
if (pointee == null) { if (pointee == nullptr) {
Assert(delay_pointee_ptr != null); Assert(delay_pointee_ptr != nullptr);
*delay_pointee_ptr = pointer; *delay_pointee_ptr = pointer;
pointee = pointer; pointee = pointer;
} }
@@ -931,17 +932,17 @@ static void parse_parameter_type_list(scc_parser_t *parser,
declaration-specifiers declarator declaration-specifiers declarator
declaration-specifiers abstract-declarator(opt) declaration-specifiers abstract-declarator(opt)
*/ */
scc_ast_decl_t *param = null; scc_ast_decl_t *param = nullptr;
scc_ast_decl_t *decl = null; scc_ast_decl_t *decl = nullptr;
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
while (1) { while (1) {
// FIXME // FIXME
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser); scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type == null) { if (type == nullptr) {
break; break;
} }
decl = scc_parse_declarator(parser, type); decl = scc_parse_declarator(parser, type);
if (decl == null) { if (decl == nullptr) {
break; break;
} }
@@ -957,18 +958,18 @@ static void parse_parameter_type_list(scc_parser_t *parser,
break; break;
} }
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_ELLIPSIS) { if (tok_ptr->type == SCC_TOK_ELLIPSIS) {
param = scc_malloc(sizeof(scc_ast_decl_t)); param = scc_malloc(sizeof(scc_ast_decl_t));
Assert(param != null); Assert(param != nullptr);
// FIXME // FIXME
type = scc_malloc(sizeof(scc_ast_type_t)); type = scc_malloc(sizeof(scc_ast_type_t));
Assert(type != null); Assert(type != nullptr);
scc_ast_type_builtin_init(type, SCC_AST_BUILTIN_TYPE_VA_LIST, scc_ast_type_builtin_init(type, SCC_AST_BUILTIN_TYPE_VA_LIST,
tok_ptr->loc); tok_ptr->loc);
scc_ast_decl_param_init(param, type, null, tok_ptr->loc); scc_ast_decl_param_init(param, type, nullptr, tok_ptr->loc);
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
scc_vec_push(*params, param); scc_vec_push(*params, param);
break; break;
} }
@@ -977,7 +978,7 @@ static void parse_parameter_type_list(scc_parser_t *parser,
static inline cbool parse_function_parameters_start(scc_parser_t *parser) { static inline cbool parse_function_parameters_start(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return false; return false;
} }
if (scc_parse_is_decl_specifier_start(parser)) { if (scc_parse_is_decl_specifier_start(parser)) {
@@ -1003,14 +1004,14 @@ static void parse_function_parameters(scc_parser_t *parser,
} }
static scc_ast_expr_t *parse_array_size_type(scc_parser_t *parser) { static scc_ast_expr_t *parse_array_size_type(scc_parser_t *parser) {
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACKET)) { if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expect '['"); SCC_ERROR(scc_parser_got_current_pos(parser), "Expect '['");
parser->errcode = 1; parser->errcode = 1;
return null; return nullptr;
} }
scc_ast_expr_t *size = null; scc_ast_expr_t *size = nullptr;
scc_ast_decl_specifier_t quals = {0}; scc_ast_decl_specifier_t quals = {0};
if (scc_parse_is_type_qualifier_start(parser)) { if (scc_parse_is_type_qualifier_start(parser)) {
// static assignment-expression // static assignment-expression
@@ -1019,7 +1020,7 @@ static scc_ast_expr_t *parse_array_size_type(scc_parser_t *parser) {
// TODO // TODO
} }
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr != null && tok_ptr->type != SCC_TOK_R_BRACKET) { if (tok_ptr != nullptr && tok_ptr->type != SCC_TOK_R_BRACKET) {
size = scc_parse_expression(parser); size = scc_parse_expression(parser);
} }
} else if (scc_parser_consume_if(parser, SCC_TOK_MUL)) { } else if (scc_parser_consume_if(parser, SCC_TOK_MUL)) {
@@ -1031,14 +1032,14 @@ static scc_ast_expr_t *parse_array_size_type(scc_parser_t *parser) {
} else { } else {
// assignment-expression(opt) // assignment-expression(opt)
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr != null && tok_ptr->type != SCC_TOK_R_BRACKET) { if (tok_ptr != nullptr && tok_ptr->type != SCC_TOK_R_BRACKET) {
size = scc_parse_expression(parser); size = scc_parse_expression(parser);
} }
} }
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "expect ']'"); SCC_ERROR(scc_parser_got_current_pos(parser), "expect ']'");
parser->errcode = 1; parser->errcode = 1;
return null; return nullptr;
} }
return size; return size;
} }
@@ -1071,16 +1072,16 @@ static scc_ast_type_t *
parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base, parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr, scc_ast_type_t **delay_pointee_ptr,
scc_lexer_tok_t *tok_ident) { scc_lexer_tok_t *tok_ident) {
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
scc_ast_type_t *ret = null; scc_ast_type_t *ret = nullptr;
// direct-abstract-declarator // direct-abstract-declarator
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return base; return base;
} }
if (tok_ptr->type == SCC_TOK_IDENT) { if (tok_ptr->type == SCC_TOK_IDENT) {
Assert(tok_ident != null); Assert(tok_ident != nullptr);
if (tok_ident->type != SCC_TOK_UNKNOWN) { if (tok_ident->type != SCC_TOK_UNKNOWN) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Got double identifier in declarator"); "Got double identifier in declarator");
@@ -1092,8 +1093,8 @@ parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
tok_ident); tok_ident);
} else if (tok_ptr->type == SCC_TOK_L_PAREN) { } else if (tok_ptr->type == SCC_TOK_L_PAREN) {
// () SCC_TOK_L_PAREN // () SCC_TOK_L_PAREN
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
scc_ast_type_t *delay_pointee = null; scc_ast_type_t *delay_pointee = nullptr;
if (parse_function_parameters_start(parser)) { if (parse_function_parameters_start(parser)) {
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
parse_function_parameters(parser, &params); parse_function_parameters(parser, &params);
@@ -1103,10 +1104,10 @@ parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
return parse_direct_declarator(parser, ret, delay_pointee_ptr, return parse_direct_declarator(parser, ret, delay_pointee_ptr,
tok_ident); tok_ident);
} else { } else {
ret = parse_declarator(parser, null, &delay_pointee, tok_ident); ret = parse_declarator(parser, nullptr, &delay_pointee, tok_ident);
if (ret == null) { if (ret == nullptr) {
SCC_ERROR(tok_ident->loc, "parse_declarator failed"); SCC_ERROR(tok_ident->loc, "parse_declarator failed");
Panic("parse_declarator failed ret == null"); Panic("parse_declarator failed ret == nullptr");
} }
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "expect ')'"); SCC_ERROR(scc_parser_got_current_pos(parser), "expect ')'");
@@ -1114,7 +1115,7 @@ parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
base = parse_direct_declarator(parser, base, delay_pointee_ptr, base = parse_direct_declarator(parser, base, delay_pointee_ptr,
tok_ident); tok_ident);
Assert(SCC_AST_IS_A(scc_ast_type_t, base)); Assert(SCC_AST_IS_A(scc_ast_type_t, base));
Assert(delay_pointee != null); Assert(delay_pointee != nullptr);
delay_pointee->pointer.pointee = base; delay_pointee->pointer.pointee = base;
return ret; return ret;
} }
@@ -1158,18 +1159,18 @@ parse_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
static scc_ast_type_t * static scc_ast_type_t *
parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base, parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr) { scc_ast_type_t **delay_pointee_ptr) {
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = nullptr;
scc_ast_type_t *ret = null; scc_ast_type_t *ret = nullptr;
// direct-abstract-declarator // direct-abstract-declarator
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) { if (tok_ptr == nullptr) {
return base; return base;
} }
if (tok_ptr->type == SCC_TOK_L_PAREN) { if (tok_ptr->type == SCC_TOK_L_PAREN) {
// () SCC_TOK_L_PAREN // () SCC_TOK_L_PAREN
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, nullptr);
scc_ast_type_t *delay_pointee = null; scc_ast_type_t *delay_pointee = nullptr;
if (parse_function_parameters_start(parser)) { if (parse_function_parameters_start(parser)) {
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
parse_function_parameters(parser, &params); parse_function_parameters(parser, &params);
@@ -1179,14 +1180,14 @@ parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
return parse_direct_abstract_declarator(parser, ret, return parse_direct_abstract_declarator(parser, ret,
delay_pointee_ptr); delay_pointee_ptr);
} else { } else {
ret = parse_abstract_declarator(parser, null, &delay_pointee); ret = parse_abstract_declarator(parser, nullptr, &delay_pointee);
Assert(ret != null); Assert(ret != nullptr);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "expect ')'"); SCC_ERROR(scc_parser_got_current_pos(parser), "expect ')'");
} }
base = parse_direct_abstract_declarator(parser, base, base = parse_direct_abstract_declarator(parser, base,
delay_pointee_ptr); delay_pointee_ptr);
Assert(delay_pointee != null); Assert(delay_pointee != nullptr);
delay_pointee->pointer.pointee = base; delay_pointee->pointer.pointee = base;
} }
return ret; return ret;
@@ -1208,20 +1209,21 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
scc_ast_type_t *type) { scc_ast_type_t *type) {
scc_lexer_tok_t decl_name_tok = {0}; scc_lexer_tok_t decl_name_tok = {0};
scc_ast_type_t *decl_type = scc_ast_type_t *decl_type =
parse_declarator(parser, type, null, &decl_name_tok); parse_declarator(parser, type, nullptr, &decl_name_tok);
scc_ast_decl_t *decl = null; scc_ast_decl_t *decl = nullptr;
decl = scc_malloc(sizeof(scc_ast_decl_t)); decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null); Assert(decl != nullptr);
Assert(decl_name_tok.type == SCC_TOK_IDENT || Assert(decl_name_tok.type == SCC_TOK_IDENT ||
decl_name_tok.type == SCC_TOK_UNKNOWN); decl_name_tok.type == SCC_TOK_UNKNOWN);
// FIXME memory leak // FIXME memory leak
const char *name = decl_name_tok.type == SCC_TOK_IDENT const char *name = decl_name_tok.type == SCC_TOK_IDENT
? scc_str_as_cstr(&decl_name_tok.lexeme) ? scc_str_as_cstr(&decl_name_tok.lexeme)
: null; : nullptr;
if (decl_type->base.type == SCC_AST_TYPE_FUNCTION) { if (decl_type->base.type == SCC_AST_TYPE_FUNCTION) {
scc_ast_decl_func_init(decl, decl_type, name, null, decl_name_tok.loc); scc_ast_decl_func_init(decl, decl_type, name, nullptr,
decl_name_tok.loc);
// TODO using sema to change it // TODO using sema to change it
if (type->quals.is_inline) { if (type->quals.is_inline) {
decl_type->quals.is_inline = true; decl_type->quals.is_inline = true;
@@ -1229,7 +1231,7 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
type->quals.is_inline = false; type->quals.is_inline = false;
} }
} else { } else {
scc_ast_decl_unsafe_val_init(decl, decl_type, name, null, scc_ast_decl_unsafe_val_init(decl, decl_type, name, nullptr,
decl_name_tok.loc); decl_name_tok.loc);
} }
@@ -1237,17 +1239,17 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
if (decl_type->base.type == SCC_AST_TYPE_STRUCT || if (decl_type->base.type == SCC_AST_TYPE_STRUCT ||
decl_type->base.type == SCC_AST_TYPE_UNION || decl_type->base.type == SCC_AST_TYPE_UNION ||
decl_type->base.type == SCC_AST_TYPE_ENUM) { decl_type->base.type == SCC_AST_TYPE_ENUM) {
if (decl_type->record.decl == null) { if (decl_type->record.decl == nullptr) {
decl = scc_malloc(sizeof(scc_ast_decl_t)); decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null); Assert(decl != nullptr);
if (decl_type->base.type == SCC_AST_TYPE_STRUCT) { if (decl_type->base.type == SCC_AST_TYPE_STRUCT) {
scc_ast_decl_struct_init(decl, decl_type->record.name, null, scc_ast_decl_struct_init(decl, decl_type->record.name,
decl_type->base.loc); nullptr, decl_type->base.loc);
} else if (decl_type->base.type == SCC_AST_TYPE_UNION) { } else if (decl_type->base.type == SCC_AST_TYPE_UNION) {
scc_ast_decl_union_init(decl, decl_type->record.name, null, scc_ast_decl_union_init(decl, decl_type->record.name,
decl_type->base.loc); nullptr, decl_type->base.loc);
} else { } else {
scc_ast_decl_enum_init(decl, type->record.name, null, scc_ast_decl_enum_init(decl, type->record.name, nullptr,
decl_type->base.loc); decl_type->base.loc);
} }
} else { } else {
@@ -1256,7 +1258,7 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
} }
} else { } else {
decl = scc_malloc(sizeof(scc_ast_decl_t)); decl = scc_malloc(sizeof(scc_ast_decl_t));
scc_ast_decl_unsafe_val_init(decl, type, null, null, scc_ast_decl_unsafe_val_init(decl, type, nullptr, nullptr,
decl_type->base.loc); decl_type->base.loc);
} }
} }
@@ -1265,7 +1267,7 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser) { scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser) {
if (!scc_parse_is_decl_specifier_start(parser)) { if (!scc_parse_is_decl_specifier_start(parser)) {
return null; return nullptr;
} }
scc_ast_decl_specifier_t spec = {0}; scc_ast_decl_specifier_t spec = {0};
@@ -1275,10 +1277,10 @@ scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser) {
spec = parse_declaration_specifiers_list(parser, spec); spec = parse_declaration_specifiers_list(parser, spec);
scc_ast_type_t *specifier = parse_type_specifier(parser); scc_ast_type_t *specifier = parse_type_specifier(parser);
if (specifier == null) { if (specifier == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"declaration specifier can't have type specifier"); "declaration specifier can't have type specifier");
return null; return nullptr;
} }
specifier->quals = spec; specifier->quals = spec;
@@ -1288,16 +1290,16 @@ scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser) {
scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) { scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) {
if (!(scc_parse_is_type_specifier_start(parser) || if (!(scc_parse_is_type_specifier_start(parser) ||
scc_parse_is_type_qualifier_start(parser))) { scc_parse_is_type_qualifier_start(parser))) {
return null; return nullptr;
} }
scc_ast_type_t *ret = null; scc_ast_type_t *ret = nullptr;
scc_ast_decl_specifier_t spec = {0}; scc_ast_decl_specifier_t spec = {0};
spec = parse_type_qualifier_list(parser, spec); spec = parse_type_qualifier_list(parser, spec);
ret = parse_type_specifier(parser); ret = parse_type_specifier(parser);
if (ret != null) { if (ret != nullptr) {
ret->quals = spec; ret->quals = spec;
} }
ret = parse_abstract_declarator(parser, ret, null); ret = parse_abstract_declarator(parser, ret, nullptr);
return ret; return ret;
} }
+8 -8
View File
@@ -13,7 +13,7 @@ static scc_ast_type_t *dummy_got_type_callback(void *context,
const char *name) { const char *name) {
(void)context; (void)context;
(void)name; (void)name;
return null; return nullptr;
} }
#define ASSIGN_PTR_OR_DEFAULT(assigned_val, value, default) \ #define ASSIGN_PTR_OR_DEFAULT(assigned_val, value, default) \
@@ -21,10 +21,10 @@ static scc_ast_type_t *dummy_got_type_callback(void *context,
void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring, void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring,
scc_sema_callbacks_t *callbacks) { scc_sema_callbacks_t *callbacks) {
Assert(parser != null && tok_ring != null); Assert(parser != nullptr && tok_ring != nullptr);
parser->ring = tok_ring; parser->ring = tok_ring;
parser->errcode = 0; parser->errcode = 0;
parser->translation_unit = null; parser->translation_unit = nullptr;
if (callbacks) { if (callbacks) {
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_decl, ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_decl,
callbacks->on_decl, dummy_sema_callback); callbacks->on_decl, dummy_sema_callback);
@@ -43,7 +43,7 @@ void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring,
parser->sema_callbacks.on_expr = dummy_sema_callback; parser->sema_callbacks.on_expr = dummy_sema_callback;
parser->sema_callbacks.on_type = dummy_sema_callback; parser->sema_callbacks.on_type = dummy_sema_callback;
parser->sema_callbacks.got_type = dummy_got_type_callback; parser->sema_callbacks.got_type = dummy_got_type_callback;
parser->sema_callbacks.context = null; parser->sema_callbacks.context = nullptr;
} }
} }
@@ -55,7 +55,7 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
scc_ast_translation_unit_t *unit = scc_ast_translation_unit_t *unit =
scc_malloc(sizeof(scc_ast_translation_unit_t)); scc_malloc(sizeof(scc_ast_translation_unit_t));
if (!unit) if (!unit)
return null; return nullptr;
unit->base.type = SCC_AST_TRANSLATION_UNIT; unit->base.type = SCC_AST_TRANSLATION_UNIT;
scc_vec_init(unit->declarations); scc_vec_init(unit->declarations);
@@ -66,7 +66,7 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
*/ */
while (1) { while (1) {
scc_ast_decl_t *decl = scc_parse_declaration(parser); scc_ast_decl_t *decl = scc_parse_declaration(parser);
if (decl != null) { if (decl != nullptr) {
scc_vec_push(unit->declarations, decl); scc_vec_push(unit->declarations, decl);
} else { } else {
break; break;
@@ -77,7 +77,7 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
break; break;
} }
const scc_lexer_tok_t *tok = scc_parser_peek(parser); const scc_lexer_tok_t *tok = scc_parser_peek(parser);
if (tok == null || tok->type == SCC_TOK_EOF) { if (tok == nullptr || tok->type == SCC_TOK_EOF) {
break; break;
} }
} }
@@ -87,7 +87,7 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
SCC_ERROR(scc_parser_got_current_pos(parser), "parser error: %d", SCC_ERROR(scc_parser_got_current_pos(parser), "parser error: %d",
parser->errcode); parser->errcode);
scc_free(unit); scc_free(unit);
return null; return nullptr;
} }
Assert(unit->base.type == SCC_AST_TRANSLATION_UNIT); Assert(unit->base.type == SCC_AST_TRANSLATION_UNIT);
+17 -16
View File
@@ -15,14 +15,14 @@ static void expr_callback(void *context, scc_ast_node_type_t node_type,
void *node) { void *node) {
scc_sema_symtab_t *sema_symtab = context; scc_sema_symtab_t *sema_symtab = context;
if (node_type == SCC_AST_UNKNOWN || node == null) { if (node_type == SCC_AST_UNKNOWN || node == nullptr) {
return; return;
} }
scc_ast_expr_t *expr = SCC_AST_CAST_TO(scc_ast_expr_t, node); scc_ast_expr_t *expr = SCC_AST_CAST_TO(scc_ast_expr_t, node);
if (node_type == SCC_AST_EXPR_IDENTIFIER) { if (node_type == SCC_AST_EXPR_IDENTIFIER) {
scc_ast_node_t *node = scc_ast_node_t *node =
scc_sema_symtab_lookup_symbol(sema_symtab, expr->identifier.name); scc_sema_symtab_lookup_symbol(sema_symtab, expr->identifier.name);
if (node == null) { if (node == nullptr) {
SCC_ERROR(expr->base.loc, "sema error: Identifier '%s' not found", SCC_ERROR(expr->base.loc, "sema error: Identifier '%s' not found",
expr->identifier.name); expr->identifier.name);
} else if (!SCC_AST_IS_A(scc_ast_decl_t, node)) { } else if (!SCC_AST_IS_A(scc_ast_decl_t, node)) {
@@ -48,7 +48,7 @@ static void stmt_callback(void *context, scc_ast_node_type_t node_type,
scc_sema_symtab_leave_scope(sema_symtab); scc_sema_symtab_leave_scope(sema_symtab);
return; return;
} }
if (node_type == SCC_AST_UNKNOWN || node == null) { if (node_type == SCC_AST_UNKNOWN || node == nullptr) {
return; return;
} }
return; return;
@@ -66,20 +66,20 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type,
scc_sema_symtab_leave_scope(sema_symtab); scc_sema_symtab_leave_scope(sema_symtab);
return; return;
} }
if (node_type == SCC_AST_UNKNOWN || node == null) { if (node_type == SCC_AST_UNKNOWN || node == nullptr) {
return; return;
} }
scc_ast_decl_t *decl = SCC_AST_CAST_TO(scc_ast_decl_t, node); scc_ast_decl_t *decl = SCC_AST_CAST_TO(scc_ast_decl_t, node);
scc_ast_type_t *type = scc_malloc(sizeof(scc_ast_type_t)); scc_ast_type_t *type = scc_malloc(sizeof(scc_ast_type_t));
Assert(type != null); Assert(type != nullptr);
if (node_type == SCC_AST_DECL_STRUCT) { if (node_type == SCC_AST_DECL_STRUCT) {
scc_ast_type_struct_init(type, decl->name, decl, decl->base.loc); scc_ast_type_struct_init(type, decl->name, decl, decl->base.loc);
// FIXME memory leak // FIXME memory leak
scc_str_t name = scc_str_from_cstr("$S_"); scc_str_t name = scc_str_from_cstr("$S_");
if (decl->name == null) { if (decl->name == nullptr) {
decl->name = "<anonymous struct>"; decl->name = "<anonymous struct>";
} }
scc_str_append_cstr(&name, decl->name, scc_strlen(decl->name)); scc_str_append_cstr(&name, decl->name, scc_strlen(decl->name));
@@ -88,7 +88,7 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type,
} else if (node_type == SCC_AST_DECL_UNION) { } else if (node_type == SCC_AST_DECL_UNION) {
scc_ast_type_union_init(type, decl->name, decl, decl->base.loc); scc_ast_type_union_init(type, decl->name, decl, decl->base.loc);
scc_str_t name = scc_str_from_cstr("$U_"); scc_str_t name = scc_str_from_cstr("$U_");
if (decl->name == null) { if (decl->name == nullptr) {
decl->name = "<anonymous union>"; decl->name = "<anonymous union>";
} }
scc_str_append_cstr(&name, decl->name, scc_strlen(decl->name)); scc_str_append_cstr(&name, decl->name, scc_strlen(decl->name));
@@ -97,7 +97,7 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type,
} else if (node_type == SCC_AST_DECL_ENUM) { } else if (node_type == SCC_AST_DECL_ENUM) {
scc_ast_type_enum_init(type, decl->name, decl, decl->base.loc); scc_ast_type_enum_init(type, decl->name, decl, decl->base.loc);
scc_str_t name = scc_str_from_cstr("$E_"); scc_str_t name = scc_str_from_cstr("$E_");
if (decl->name == null) { if (decl->name == nullptr) {
decl->name = "<anonymous enum>"; decl->name = "<anonymous enum>";
} }
scc_str_append_cstr(&name, decl->name, scc_strlen(decl->name)); scc_str_append_cstr(&name, decl->name, scc_strlen(decl->name));
@@ -111,7 +111,7 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type,
// LOG_INFO("enum added %s", enum_decl->name); // LOG_INFO("enum added %s", enum_decl->name);
} }
} else if (node_type == SCC_AST_DECL_TYPEDEF) { } else if (node_type == SCC_AST_DECL_TYPEDEF) {
if (decl->name == null) { if (decl->name == nullptr) {
SCC_ERROR(decl->base.loc, "typedef without name"); SCC_ERROR(decl->base.loc, "typedef without name");
return; return;
} }
@@ -120,7 +120,7 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type,
} else if (node_type == SCC_AST_DECL_VAR) { } else if (node_type == SCC_AST_DECL_VAR) {
scc_sema_symtab_add_symbol(sema_symtab, decl->name, &decl->base); scc_sema_symtab_add_symbol(sema_symtab, decl->name, &decl->base);
} else if (node_type == SCC_AST_DECL_PARAM) { } else if (node_type == SCC_AST_DECL_PARAM) {
if (decl->name == null) { if (decl->name == nullptr) {
if (decl->param.type->base.type == SCC_AST_TYPE_BUILTIN && if (decl->param.type->base.type == SCC_AST_TYPE_BUILTIN &&
(decl->param.type->builtin.type == (decl->param.type->builtin.type ==
SCC_AST_BUILTIN_TYPE_VA_LIST || SCC_AST_BUILTIN_TYPE_VA_LIST ||
@@ -132,7 +132,7 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type,
} }
scc_sema_symtab_add_symbol(sema_symtab, decl->name, &decl->base); scc_sema_symtab_add_symbol(sema_symtab, decl->name, &decl->base);
} else if (node_type == SCC_AST_DECL_FUNC) { } else if (node_type == SCC_AST_DECL_FUNC) {
if (decl->name == null) { if (decl->name == nullptr) {
SCC_ERROR(decl->base.loc, "sema error: Function must have a name"); SCC_ERROR(decl->base.loc, "sema error: Function must have a name");
} else { } else {
// FIXME 重名函数... // FIXME 重名函数...
@@ -150,12 +150,12 @@ static scc_ast_type_t *got_type_callback(void *context, const char *name) {
*type = *(scc_ast_type_t *)node; *type = *(scc_ast_type_t *)node;
return type; return type;
} }
return null; return nullptr;
} }
void scc_sema_init(scc_sema_callbacks_t *callbacks) { void scc_sema_init(scc_sema_callbacks_t *callbacks) {
scc_sema_symtab_t *sema_symtab = scc_malloc(sizeof(scc_sema_symtab_t)); scc_sema_symtab_t *sema_symtab = scc_malloc(sizeof(scc_sema_symtab_t));
if (sema_symtab == null) { if (sema_symtab == nullptr) {
LOG_FATAL("out of memory"); LOG_FATAL("out of memory");
return; return;
} }
@@ -176,15 +176,16 @@ void scc_sema_init(scc_sema_callbacks_t *callbacks) {
&type->base); &type->base);
scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t)); scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t));
scc_ast_decl_val_init(decl, type, "__scc_builtin__", null, scc_ast_decl_val_init(decl, type, "__scc_builtin__", nullptr,
scc_pos_create()); scc_pos_create());
scc_sema_symtab_add_symbol(sema_symtab, "__func__", &decl->base); scc_sema_symtab_add_symbol(sema_symtab, "__func__", &decl->base);
scc_ast_type_t *built_func_type = scc_malloc(sizeof(scc_ast_type_t)); scc_ast_type_t *built_func_type = scc_malloc(sizeof(scc_ast_type_t));
scc_ast_type_function_init(built_func_type, null, null, scc_pos_create()); scc_ast_type_function_init(built_func_type, nullptr, nullptr,
scc_pos_create());
scc_ast_decl_t *builin_func = scc_malloc(sizeof(scc_ast_decl_t)); scc_ast_decl_t *builin_func = scc_malloc(sizeof(scc_ast_decl_t));
scc_ast_decl_func_init(builin_func, built_func_type, "__scc_builtin_func", scc_ast_decl_func_init(builin_func, built_func_type, "__scc_builtin_func",
null, scc_pos_create()); nullptr, scc_pos_create());
scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_start", scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_start",
&builin_func->base); &builin_func->base);
scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_end", scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_end",
+7 -7
View File
@@ -1,7 +1,7 @@
#include <sema_symtab.h> #include <sema_symtab.h>
void scc_sema_symtab_init(scc_sema_symtab_t *symtab) { void scc_sema_symtab_init(scc_sema_symtab_t *symtab) {
symtab->root_scope.parent = null; symtab->root_scope.parent = nullptr;
scc_hashtable_init(&symtab->root_scope.symbols, scc_hashtable_init(&symtab->root_scope.symbols,
(scc_hashtable_hash_func_t)scc_strhash32, (scc_hashtable_hash_func_t)scc_strhash32,
@@ -10,7 +10,7 @@ void scc_sema_symtab_init(scc_sema_symtab_t *symtab) {
} }
void scc_sema_symtab_drop(scc_sema_symtab_t *symtab) { void scc_sema_symtab_drop(scc_sema_symtab_t *symtab) {
while (symtab->current_scope != null) { while (symtab->current_scope != nullptr) {
scc_hashtable_drop(&symtab->current_scope->symbols); scc_hashtable_drop(&symtab->current_scope->symbols);
symtab->current_scope = symtab->current_scope->parent; symtab->current_scope = symtab->current_scope->parent;
} }
@@ -18,7 +18,7 @@ void scc_sema_symtab_drop(scc_sema_symtab_t *symtab) {
void scc_sema_symtab_enter_scope(scc_sema_symtab_t *symtab) { void scc_sema_symtab_enter_scope(scc_sema_symtab_t *symtab) {
scc_sema_scope_t *scope = scc_malloc(sizeof(scc_sema_scope_t)); scc_sema_scope_t *scope = scc_malloc(sizeof(scc_sema_scope_t));
if (scope == null) { if (scope == nullptr) {
LOG_FATAL("out of memory"); LOG_FATAL("out of memory");
return; return;
} }
@@ -47,13 +47,13 @@ scc_ast_node_t *scc_sema_symtab_add_symbol(scc_sema_symtab_t *symtab,
scc_ast_node_t *scc_sema_symtab_lookup_symbol(scc_sema_symtab_t *symtab, scc_ast_node_t *scc_sema_symtab_lookup_symbol(scc_sema_symtab_t *symtab,
const char *name) { const char *name) {
scc_ast_node_t *node = null; scc_ast_node_t *node = nullptr;
for (scc_sema_scope_t *scope = symtab->current_scope; scope != null; for (scc_sema_scope_t *scope = symtab->current_scope; scope != nullptr;
scope = scope->parent) { scope = scope->parent) {
node = scc_hashtable_get(&scope->symbols, name); node = scc_hashtable_get(&scope->symbols, name);
if (node != null) { if (node != nullptr) {
return node; return node;
} }
} }
return null; return nullptr;
} }
+2 -2
View File
@@ -26,7 +26,7 @@ static scc_ast_node_t *process_input(const char *input,
scc_sema_init(&sema_callbacks); scc_sema_init(&sema_callbacks);
scc_parser_init(&parser, tok_ring, &sema_callbacks); scc_parser_init(&parser, tok_ring, &sema_callbacks);
} else { } else {
scc_parser_init(&parser, tok_ring, null); scc_parser_init(&parser, tok_ring, nullptr);
} }
scc_ast_node_t *ret = parse_func(&parser); scc_ast_node_t *ret = parse_func(&parser);
@@ -36,7 +36,7 @@ static scc_ast_node_t *process_input(const char *input,
if (not_eof == true) { if (not_eof == true) {
// FIXME MAYBE free // FIXME MAYBE free
LOG_FATAL("Didn't consume all tokens"); LOG_FATAL("Didn't consume all tokens");
return null; return nullptr;
} }
scc_lexer_drop_ring(parser.ring); scc_lexer_drop_ring(parser.ring);
+3 -3
View File
@@ -170,14 +170,14 @@ static void test_unary_expr(void) {
TEST_CASE("sizeof expression"); TEST_CASE("sizeof expression");
{ {
scc_ast_expr_t sizeof_expr; scc_ast_expr_t sizeof_expr;
scc_ast_expr_sizeof_init(&sizeof_expr, NULL, &x, LOC); scc_ast_expr_sizeof_init(&sizeof_expr, nullptr, &x, LOC);
SCC_CHECK_AST(&sizeof_expr.base, "sizeof(x)", scc_parse_expression); SCC_CHECK_AST(&sizeof_expr.base, "sizeof(x)", scc_parse_expression);
} }
TEST_CASE("sizeof type"); TEST_CASE("sizeof type");
{ {
scc_ast_expr_t sizeof_type; scc_ast_expr_t sizeof_type;
scc_ast_expr_sizeof_init(&sizeof_type, &int_type, NULL, LOC); scc_ast_expr_sizeof_init(&sizeof_type, &int_type, nullptr, LOC);
SCC_CHECK_AST(&sizeof_type.base, "sizeof(int)", scc_parse_expression); SCC_CHECK_AST(&sizeof_type.base, "sizeof(int)", scc_parse_expression);
} }
} }
@@ -391,5 +391,5 @@ TEST_LIST = {
{"test_comma_expr", test_comma_expr}, {"test_comma_expr", test_comma_expr},
{"test_complex_expr", test_complex_expr}, {"test_complex_expr", test_complex_expr},
{"test_detail_expr", test_detail_expr}, {"test_detail_expr", test_detail_expr},
{NULL, NULL}, {nullptr, nullptr},
}; };
+43 -33
View File
@@ -106,7 +106,7 @@ static void test_array_type(void) {
{ {
// int [] // int []
scc_ast_type_t array_unknown_int; scc_ast_type_t array_unknown_int;
scc_ast_type_array_init(&array_unknown_int, &int_type, null, scc_ast_type_array_init(&array_unknown_int, &int_type, nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&array_unknown_int.base, "int []", scc_parse_type_name); SCC_CHECK_AST(&array_unknown_int.base, "int []", scc_parse_type_name);
} }
@@ -159,7 +159,7 @@ static void test_function_type(void) {
{ {
// int () // int ()
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &int_type, null, scc_ast_type_function_init(&func_type, &int_type, nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&func_type.base, "int ()", scc_parse_type_name); SCC_CHECK_AST(&func_type.base, "int ()", scc_parse_type_name);
} }
@@ -168,7 +168,7 @@ static void test_function_type(void) {
{ {
// int (void) // int (void)
scc_ast_decl_t void_param; scc_ast_decl_t void_param;
scc_ast_decl_param_init(&void_param, &void_type, null, scc_ast_decl_param_init(&void_param, &void_type, nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
@@ -189,8 +189,9 @@ static void test_function_type(void) {
scc_pos_create()); scc_pos_create());
scc_ast_decl_t param_int, param_float; scc_ast_decl_t param_int, param_float;
scc_ast_decl_param_init(&param_int, &int_type, null, scc_pos_create()); scc_ast_decl_param_init(&param_int, &int_type, nullptr,
scc_ast_decl_param_init(&param_float, &float_type, null, scc_pos_create());
scc_ast_decl_param_init(&param_float, &float_type, nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
@@ -212,7 +213,8 @@ static void test_function_type(void) {
scc_pos_create()); scc_pos_create());
scc_ast_decl_t param_int, param_var; scc_ast_decl_t param_int, param_var;
scc_ast_decl_param_init(&param_int, &int_type, null, scc_pos_create()); scc_ast_decl_param_init(&param_int, &int_type, nullptr,
scc_pos_create());
scc_ast_decl_param_init(&param_var, &va_list_type, "...", scc_ast_decl_param_init(&param_var, &va_list_type, "...",
scc_pos_create()); scc_pos_create());
@@ -231,7 +233,7 @@ static void test_function_type(void) {
{ {
// int *() // int *()
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &pointer_int_type, null, scc_ast_type_function_init(&func_type, &pointer_int_type, nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&func_type.base, "int *()", scc_parse_type_name); SCC_CHECK_AST(&func_type.base, "int *()", scc_parse_type_name);
} }
@@ -240,7 +242,7 @@ static void test_function_type(void) {
{ {
// int (*)(void) // int (*)(void)
scc_ast_decl_t void_param; scc_ast_decl_t void_param;
scc_ast_decl_param_init(&void_param, &void_type, null, scc_ast_decl_param_init(&void_param, &void_type, nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
@@ -262,7 +264,7 @@ static void test_struct_union_type(void) {
{ {
// struct S // struct S
scc_ast_type_t struct_type; scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, "S", null, scc_pos_create()); scc_ast_type_struct_init(&struct_type, "S", nullptr, scc_pos_create());
SCC_CHECK_AST(&struct_type.base, "struct S", scc_parse_type_name); SCC_CHECK_AST(&struct_type.base, "struct S", scc_parse_type_name);
} }
@@ -270,7 +272,7 @@ static void test_struct_union_type(void) {
{ {
// union U // union U
scc_ast_type_t union_type; scc_ast_type_t union_type;
scc_ast_type_union_init(&union_type, "U", null, scc_pos_create()); scc_ast_type_union_init(&union_type, "U", nullptr, scc_pos_create());
SCC_CHECK_AST(&union_type.base, "union U", scc_parse_type_name); SCC_CHECK_AST(&union_type.base, "union U", scc_parse_type_name);
} }
@@ -278,17 +280,19 @@ static void test_struct_union_type(void) {
{ {
// struct { int x; } // struct { int x; }
scc_ast_decl_t field_x; scc_ast_decl_t field_x;
scc_ast_decl_val_init(&field_x, &int_type, "x", null, scc_pos_create()); scc_ast_decl_val_init(&field_x, &int_type, "x", nullptr,
scc_pos_create());
scc_ast_decl_vec_t fields; scc_ast_decl_vec_t fields;
scc_vec_init(fields); scc_vec_init(fields);
scc_vec_push(fields, &field_x); scc_vec_push(fields, &field_x);
scc_ast_decl_t struct_decl; scc_ast_decl_t struct_decl;
scc_ast_decl_struct_init(&struct_decl, null, &fields, scc_pos_create()); scc_ast_decl_struct_init(&struct_decl, nullptr, &fields,
scc_pos_create());
scc_ast_type_t struct_type; scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, null, &struct_decl, scc_ast_type_struct_init(&struct_type, nullptr, &struct_decl,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&struct_type.base, "struct { int x; }", SCC_CHECK_AST(&struct_type.base, "struct { int x; }",
scc_parse_type_name); scc_parse_type_name);
@@ -298,7 +302,8 @@ static void test_struct_union_type(void) {
{ {
// struct S { int x; } // struct S { int x; }
scc_ast_decl_t field_x; scc_ast_decl_t field_x;
scc_ast_decl_val_init(&field_x, &int_type, "x", null, scc_pos_create()); scc_ast_decl_val_init(&field_x, &int_type, "x", nullptr,
scc_pos_create());
scc_ast_decl_vec_t fields; scc_ast_decl_vec_t fields;
scc_vec_init(fields); scc_vec_init(fields);
@@ -322,8 +327,9 @@ static void test_struct_union_type(void) {
scc_pos_create()); scc_pos_create());
scc_ast_decl_t field_a, field_b; scc_ast_decl_t field_a, field_b;
scc_ast_decl_val_init(&field_a, &int_type, "a", null, scc_pos_create()); scc_ast_decl_val_init(&field_a, &int_type, "a", nullptr,
scc_ast_decl_val_init(&field_b, &float_type, "b", null, scc_pos_create());
scc_ast_decl_val_init(&field_b, &float_type, "b", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t fields; scc_ast_decl_vec_t fields;
@@ -332,10 +338,11 @@ static void test_struct_union_type(void) {
scc_vec_push(fields, &field_b); scc_vec_push(fields, &field_b);
scc_ast_decl_t union_decl; scc_ast_decl_t union_decl;
scc_ast_decl_union_init(&union_decl, null, &fields, scc_pos_create()); scc_ast_decl_union_init(&union_decl, nullptr, &fields,
scc_pos_create());
scc_ast_type_t union_type; scc_ast_type_t union_type;
scc_ast_type_union_init(&union_type, null, &union_decl, scc_ast_type_union_init(&union_type, nullptr, &union_decl,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&union_type.base, "union { int a; float b; }", SCC_CHECK_AST(&union_type.base, "union { int a; float b; }",
scc_parse_type_name); scc_parse_type_name);
@@ -347,7 +354,7 @@ static void test_enum_type(void) {
{ {
// enum E // enum E
scc_ast_type_t enum_type; scc_ast_type_t enum_type;
scc_ast_type_enum_init(&enum_type, "E", null, scc_pos_create()); scc_ast_type_enum_init(&enum_type, "E", nullptr, scc_pos_create());
SCC_CHECK_AST(&enum_type.base, "enum E", scc_parse_type_name); SCC_CHECK_AST(&enum_type.base, "enum E", scc_parse_type_name);
} }
@@ -357,10 +364,11 @@ static void test_enum_type(void) {
scc_ast_type_t enum_type; scc_ast_type_t enum_type;
scc_ast_decl_t red, green, blue; scc_ast_decl_t red, green, blue;
scc_ast_decl_val_init(&red, &enum_type, "RED", null, scc_pos_create()); scc_ast_decl_val_init(&red, &enum_type, "RED", nullptr,
scc_ast_decl_val_init(&green, &enum_type, "GREEN", null,
scc_pos_create()); scc_pos_create());
scc_ast_decl_val_init(&blue, &enum_type, "BLUE", null, scc_ast_decl_val_init(&green, &enum_type, "GREEN", nullptr,
scc_pos_create());
scc_ast_decl_val_init(&blue, &enum_type, "BLUE", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t enumerators; scc_ast_decl_vec_t enumerators;
@@ -370,10 +378,11 @@ static void test_enum_type(void) {
scc_vec_push(enumerators, &blue); scc_vec_push(enumerators, &blue);
scc_ast_decl_t enum_decl; scc_ast_decl_t enum_decl;
scc_ast_decl_enum_init(&enum_decl, null, &enumerators, scc_ast_decl_enum_init(&enum_decl, nullptr, &enumerators,
scc_pos_create()); scc_pos_create());
scc_ast_type_enum_init(&enum_type, null, &enum_decl, scc_pos_create()); scc_ast_type_enum_init(&enum_type, nullptr, &enum_decl,
scc_pos_create());
SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }", SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }",
scc_parse_type_name); scc_parse_type_name);
} }
@@ -384,10 +393,11 @@ static void test_enum_type(void) {
scc_ast_type_t enum_type; scc_ast_type_t enum_type;
scc_ast_decl_t red, green, blue; scc_ast_decl_t red, green, blue;
scc_ast_decl_val_init(&red, &enum_type, "RED", null, scc_pos_create()); scc_ast_decl_val_init(&red, &enum_type, "RED", nullptr,
scc_ast_decl_val_init(&green, &enum_type, "GREEN", null,
scc_pos_create()); scc_pos_create());
scc_ast_decl_val_init(&blue, &enum_type, "BLUE", null, scc_ast_decl_val_init(&green, &enum_type, "GREEN", nullptr,
scc_pos_create());
scc_ast_decl_val_init(&blue, &enum_type, "BLUE", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t enumerators; scc_ast_decl_vec_t enumerators;
@@ -397,7 +407,7 @@ static void test_enum_type(void) {
scc_vec_push(enumerators, &blue); scc_vec_push(enumerators, &blue);
scc_ast_decl_t enum_decl; scc_ast_decl_t enum_decl;
scc_ast_decl_enum_init(&enum_decl, null, &enumerators, scc_ast_decl_enum_init(&enum_decl, nullptr, &enumerators,
scc_pos_create()); scc_pos_create());
scc_ast_type_enum_init(&enum_type, "E", &enum_decl, scc_pos_create()); scc_ast_type_enum_init(&enum_type, "E", &enum_decl, scc_pos_create());
@@ -485,7 +495,7 @@ static void test_hard_type(void) {
{ {
// 1) 函数类型 int (void) // 1) 函数类型 int (void)
scc_ast_decl_t void_param; scc_ast_decl_t void_param;
scc_ast_decl_param_init(&void_param, &void_type, null, scc_ast_decl_param_init(&void_param, &void_type, nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
scc_vec_init(params); scc_vec_init(params);
@@ -533,7 +543,7 @@ static void test_hard_type(void) {
// 3) 函数类型,返回上述指针,无参数 // 3) 函数类型,返回上述指针,无参数
scc_ast_decl_t void_param; scc_ast_decl_t void_param;
scc_ast_decl_param_init(&void_param, &void_type, null, scc_ast_decl_param_init(&void_param, &void_type, nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
scc_vec_init(params); scc_vec_init(params);
@@ -556,7 +566,7 @@ static void test_hard_type(void) {
{ {
// 1) 函数类型 int (void) // 1) 函数类型 int (void)
scc_ast_decl_t void_param; scc_ast_decl_t void_param;
scc_ast_decl_param_init(&void_param, &void_type, null, scc_ast_decl_param_init(&void_param, &void_type, nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t params; scc_ast_decl_vec_t params;
scc_vec_init(params); scc_vec_init(params);
@@ -572,7 +582,7 @@ static void test_hard_type(void) {
// 3) 外部函数类型,返回上述指针,无参数 // 3) 外部函数类型,返回上述指针,无参数
scc_ast_type_t outer_func; scc_ast_type_t outer_func;
scc_ast_type_function_init(&outer_func, &ptr_to_func, null, scc_ast_type_function_init(&outer_func, &ptr_to_func, nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&outer_func.base, "int (*())(void)", scc_parse_type_name); SCC_CHECK_AST(&outer_func.base, "int (*())(void)", scc_parse_type_name);
@@ -588,5 +598,5 @@ TEST_LIST = {
{"test_enum_type", test_enum_type}, {"test_enum_type", test_enum_type},
{"test_specifier_type", test_specifier_type}, {"test_specifier_type", test_specifier_type},
{"test_hard_type", test_hard_type}, {"test_hard_type", test_hard_type},
{null, null}, {nullptr, nullptr},
}; };
+45 -36
View File
@@ -32,7 +32,7 @@ static void test_parser_unit(void) {
// 1. 变量声明 int a; // 1. 变量声明 int a;
{ {
scc_ast_decl_t int_decl; scc_ast_decl_t int_decl;
scc_ast_decl_val_init(&int_decl, &int_type, "a", null, scc_ast_decl_val_init(&int_decl, &int_type, "a", nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration); SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration);
} }
@@ -43,14 +43,15 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params; scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl; scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, null, scc_pos_create()); scc_ast_decl_param_init(&void_decl, &void_type, nullptr,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl}; scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array); scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params, scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create()); scc_pos_create());
// 构造复合语句块(空) // 构造复合语句块(空)
scc_ast_stmt_t compound; scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null, scc_pos_create()); scc_ast_stmt_compound_init(&compound, nullptr, scc_pos_create());
// 构造函数声明 // 构造函数声明
scc_ast_decl_t func_decl; scc_ast_decl_t func_decl;
@@ -66,14 +67,15 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params; scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl; scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, null, scc_pos_create()); scc_ast_decl_param_init(&void_decl, &void_type, nullptr,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl}; scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array); scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params, scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create()); scc_pos_create());
scc_ast_stmt_t compound; scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null, scc_pos_create()); scc_ast_stmt_compound_init(&compound, nullptr, scc_pos_create());
scc_ast_decl_t func_decl; scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound, scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
@@ -114,7 +116,8 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params; scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl; scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, null, scc_pos_create()); scc_ast_decl_param_init(&void_decl, &void_type, nullptr,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl}; scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array); scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params, scc_ast_type_function_init(&func_type, &int_type, &func_params,
@@ -139,11 +142,13 @@ static void test_parser_unit(void) {
{ {
// 变量声明 int a; // 变量声明 int a;
scc_ast_decl_t a_decl; scc_ast_decl_t a_decl;
scc_ast_decl_val_init(&a_decl, &int_type, "a", null, scc_pos_create()); scc_ast_decl_val_init(&a_decl, &int_type, "a", nullptr,
scc_pos_create());
// 变量声明 int b; // 变量声明 int b;
scc_ast_decl_t b_decl; scc_ast_decl_t b_decl;
scc_ast_decl_val_init(&b_decl, &int_type, "b", null, scc_pos_create()); scc_ast_decl_val_init(&b_decl, &int_type, "b", nullptr,
scc_pos_create());
// 表达式 1 + 2 * 3 // 表达式 1 + 2 * 3
scc_ast_expr_t lit1, lit2, lit3, mul, add; scc_ast_expr_t lit1, lit2, lit3, mul, add;
@@ -213,7 +218,7 @@ static void test_parser_unit(void) {
// 函数类型 // 函数类型
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type, scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type,
null, scc_pos_create()); nullptr, scc_pos_create());
scc_ast_decl_t func_decl; scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound, scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
@@ -284,8 +289,8 @@ static void test_parser_unit(void) {
// 函数类型(返回 int,无参数) // 函数类型(返回 int,无参数)
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type, scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type,
null, nullptr,
scc_pos_create()); // null 表示无参数 scc_pos_create()); // nullptr 表示无参数
// 函数声明 int main() { ... } // 函数声明 int main() { ... }
scc_ast_decl_t func_decl; scc_ast_decl_t func_decl;
@@ -320,15 +325,15 @@ static void test_parser_unit(void) {
scc_ast_decl_param_init(&param1, (scc_ast_type_t *)&int_type, "b", scc_ast_decl_param_init(&param1, (scc_ast_type_t *)&int_type, "b",
scc_pos_create()); scc_pos_create());
scc_ast_decl_t param2; scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, (scc_ast_type_t *)&va_list_type, null, scc_ast_decl_param_init(&param2, (scc_ast_type_t *)&va_list_type,
scc_pos_create()); nullptr, scc_pos_create());
scc_ast_decl_t *params_array[] = {&param0, &param1, &param2}; scc_ast_decl_t *params_array[] = {&param0, &param1, &param2};
scc_vec_unsafe_from_static_array(params, params_array); scc_vec_unsafe_from_static_array(params, params_array);
scc_ast_type_t decl_func_type; scc_ast_type_t decl_func_type;
scc_ast_type_function_init(&decl_func_type, (scc_ast_type_t *)&int_type, scc_ast_type_function_init(&decl_func_type, (scc_ast_type_t *)&int_type,
&params, scc_pos_create()); &params, scc_pos_create());
scc_ast_decl_t decl_func; scc_ast_decl_t decl_func;
scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", null, scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);", SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);",
scc_parse_declaration); scc_parse_declaration);
@@ -343,7 +348,7 @@ static void test_parser_unit(void) {
scc_pos_create()); scc_pos_create());
scc_ast_decl_t i32a_decl; scc_ast_decl_t i32a_decl;
scc_ast_decl_val_init(&i32a_decl, &typedef_type, "a", null, scc_ast_decl_val_init(&i32a_decl, &typedef_type, "a", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_node_t *array[] = {&typedef_decl.base, &i32a_decl.base}; scc_ast_node_t *array[] = {&typedef_decl.base, &i32a_decl.base};
@@ -364,7 +369,7 @@ static void test_parser_unit(void) {
scc_pos_create()); scc_pos_create());
scc_ast_decl_t void_ptr_a_decl; scc_ast_decl_t void_ptr_a_decl;
scc_ast_decl_val_init(&void_ptr_a_decl, &void_ptr_type, "a", null, scc_ast_decl_val_init(&void_ptr_a_decl, &void_ptr_type, "a", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_node_t *array2[] = {&void_ptr_decl.base, &void_ptr_a_decl.base}; scc_ast_node_t *array2[] = {&void_ptr_decl.base, &void_ptr_a_decl.base};
@@ -381,19 +386,20 @@ static void test_parser_unit(void) {
{ {
// struct { int x; } (匿名结构体定义) // struct { int x; } (匿名结构体定义)
scc_ast_decl_t field; scc_ast_decl_t field;
scc_ast_decl_val_init(&field, (scc_ast_type_t *)&int_type, "x", null, scc_ast_decl_val_init(&field, (scc_ast_type_t *)&int_type, "x", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t fields; scc_ast_decl_vec_t fields;
scc_vec_init(fields); scc_vec_init(fields);
scc_vec_push(fields, &field); scc_vec_push(fields, &field);
scc_ast_decl_t struct_def; scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, null, &fields, scc_pos_create()); scc_ast_decl_struct_init(&struct_def, nullptr, &fields,
scc_pos_create());
SCC_CHECK_AST(&struct_def.base, "struct { int x;};", SCC_CHECK_AST(&struct_def.base, "struct { int x;};",
scc_parse_declaration); scc_parse_declaration);
scc_ast_type_t struct_type; scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, null, &struct_def, scc_ast_type_struct_init(&struct_type, nullptr, &struct_def,
scc_pos_create()); scc_pos_create());
scc_ast_type_t typedef_type; scc_ast_type_t typedef_type;
scc_ast_type_typedef_init(&typedef_type, "struct_t", &struct_def, scc_ast_type_typedef_init(&typedef_type, "struct_t", &struct_def,
@@ -406,7 +412,7 @@ static void test_parser_unit(void) {
scc_parse_declaration); scc_parse_declaration);
scc_ast_decl_t typedef_impl_decl; scc_ast_decl_t typedef_impl_decl;
scc_ast_decl_val_init(&typedef_impl_decl, &typedef_type, "a", null, scc_ast_decl_val_init(&typedef_impl_decl, &typedef_type, "a", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_node_t *array[] = {&typedef_decl.base, &typedef_impl_decl.base}; scc_ast_node_t *array[] = {&typedef_decl.base, &typedef_impl_decl.base};
scc_ast_stmt_t stmt; scc_ast_stmt_t stmt;
@@ -431,7 +437,8 @@ static void test_parser_unit(void) {
scc_ast_decl_t param2; scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &int_type, "b", scc_pos_create()); scc_ast_decl_param_init(&param2, &int_type, "b", scc_pos_create());
scc_ast_decl_t param3; scc_ast_decl_t param3;
scc_ast_decl_param_init(&param3, &va_list_type, null, scc_pos_create()); scc_ast_decl_param_init(&param3, &va_list_type, nullptr,
scc_pos_create());
scc_ast_decl_t *params_array[] = {&param1, &param2, &param3}; scc_ast_decl_t *params_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_params; scc_ast_decl_vec_t func_params;
scc_vec_unsafe_from_static_array(func_params, params_array); scc_vec_unsafe_from_static_array(func_params, params_array);
@@ -443,7 +450,7 @@ static void test_parser_unit(void) {
scc_ast_type_function_init(&func_type, &return_type, &func_params, scc_ast_type_function_init(&func_type, &return_type, &func_params,
scc_pos_create()); scc_pos_create());
scc_ast_decl_t func_decl; scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "func", null, scc_ast_decl_func_init(&func_decl, &func_type, "func", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_t *decls_array[] = {&type_decl, &func_decl}; scc_ast_decl_t *decls_array[] = {&type_decl, &func_decl};
@@ -512,7 +519,7 @@ static void test_parser_unit(void) {
// 6. 函数声明 // 6. 函数声明
scc_ast_decl_t decl; scc_ast_decl_t decl;
scc_ast_decl_func_init(&decl, &func_type, "call", null, scc_ast_decl_func_init(&decl, &func_type, "call", nullptr,
scc_pos_create()); scc_pos_create());
// 7. 与解析结果比较 // 7. 与解析结果比较
@@ -664,9 +671,9 @@ static void test_parser_unit(void) {
{ {
scc_ast_decl_t decl_a, decl_b; scc_ast_decl_t decl_a, decl_b;
scc_ast_decl_val_init(&decl_a, (scc_ast_type_t *)&int_type, "a", scc_ast_decl_val_init(&decl_a, (scc_ast_type_t *)&int_type, "a",
null, scc_pos_create()); nullptr, scc_pos_create());
scc_ast_decl_val_init(&decl_b, (scc_ast_type_t *)&int_type, "b", scc_ast_decl_val_init(&decl_b, (scc_ast_type_t *)&int_type, "b",
null, scc_pos_create()); nullptr, scc_pos_create());
scc_ast_decl_vec_t decl_vec; scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec); scc_vec_init(decl_vec);
@@ -708,7 +715,7 @@ static void test_parser_unit(void) {
{ {
// 构造 struct list_head 类型(不完整) // 构造 struct list_head 类型(不完整)
scc_ast_type_t struct_list_head; scc_ast_type_t struct_list_head;
scc_ast_type_struct_init(&struct_list_head, "list_head", null, scc_ast_type_struct_init(&struct_list_head, "list_head", nullptr,
scc_pos_create()); scc_pos_create());
// 构造两个指针类型(分别用于 next 和 prev,指向同一结构体) // 构造两个指针类型(分别用于 next 和 prev,指向同一结构体)
@@ -720,9 +727,9 @@ static void test_parser_unit(void) {
// 构造变量声明 next 和 prev // 构造变量声明 next 和 prev
scc_ast_decl_t next_decl, prev_decl; scc_ast_decl_t next_decl, prev_decl;
scc_ast_decl_val_init(&next_decl, &ptr_to_struct1, "next", null, scc_ast_decl_val_init(&next_decl, &ptr_to_struct1, "next", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_val_init(&prev_decl, &ptr_to_struct2, "prev", null, scc_ast_decl_val_init(&prev_decl, &ptr_to_struct2, "prev", nullptr,
scc_pos_create()); scc_pos_create());
// 构造声明列表 // 构造声明列表
@@ -742,7 +749,7 @@ static void test_parser_unit(void) {
// 构造字段 int a; // 构造字段 int a;
scc_ast_decl_t field_a; scc_ast_decl_t field_a;
scc_ast_decl_val_init(&field_a, (scc_ast_type_t *)&int_type, "a", scc_ast_decl_val_init(&field_a, (scc_ast_type_t *)&int_type, "a",
null, scc_pos_create()); nullptr, scc_pos_create());
scc_ast_decl_vec_t fields; scc_ast_decl_vec_t fields;
scc_vec_init(fields); scc_vec_init(fields);
@@ -750,12 +757,12 @@ static void test_parser_unit(void) {
// 构造匿名结构体定义声明 // 构造匿名结构体定义声明
scc_ast_decl_t struct_def; scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, null, &fields, scc_ast_decl_struct_init(&struct_def, nullptr, &fields,
scc_pos_create()); // fields 被移动 scc_pos_create()); // fields 被移动
// 构造匿名结构体类型 // 构造匿名结构体类型
scc_ast_type_t anon_struct_type; scc_ast_type_t anon_struct_type;
scc_ast_type_struct_init(&anon_struct_type, null, &struct_def, scc_ast_type_struct_init(&anon_struct_type, nullptr, &struct_def,
scc_pos_create()); scc_pos_create());
// 构造指针类型指向该匿名结构体 // 构造指针类型指向该匿名结构体
@@ -807,7 +814,8 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params; scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl; scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, null, scc_pos_create()); scc_ast_decl_param_init(&void_decl, &void_type, nullptr,
scc_pos_create());
scc_ast_decl_t *array[] = {&void_decl}; scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_static_array(func_params, array); scc_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &ptr_to_array, &func_params, scc_ast_type_function_init(&func_type, &ptr_to_array, &func_params,
@@ -818,7 +826,7 @@ static void test_parser_unit(void) {
scc_ast_type_pointer_init(&ptr_to_func, &func_type, scc_pos_create()); scc_ast_type_pointer_init(&ptr_to_func, &func_type, scc_pos_create());
scc_ast_decl_t ptr_to_func_decl; scc_ast_decl_t ptr_to_func_decl;
scc_ast_decl_val_init(&ptr_to_func_decl, &ptr_to_func, "foo", null, scc_ast_decl_val_init(&ptr_to_func_decl, &ptr_to_func, "foo", nullptr,
scc_pos_create()); scc_pos_create());
SCC_CHECK_AST(&ptr_to_func_decl.base, "int (*(*foo)(void))[5];", SCC_CHECK_AST(&ptr_to_func_decl.base, "int (*(*foo)(void))[5];",
scc_parse_declaration); scc_parse_declaration);
@@ -838,13 +846,14 @@ static void test_parser_unit(void) {
scc_ast_decl_param_init(&param2, &typedef_func_type, "a", scc_ast_decl_param_init(&param2, &typedef_func_type, "a",
scc_pos_create()); scc_pos_create());
scc_ast_decl_t param3; scc_ast_decl_t param3;
scc_ast_decl_param_init(&param1, &va_list_type, null, scc_pos_create()); scc_ast_decl_param_init(&param1, &va_list_type, nullptr,
scc_pos_create());
scc_ast_decl_t *func_hard_array[] = {&param1, &param2, &param3}; scc_ast_decl_t *func_hard_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_hard_params; scc_ast_decl_vec_t func_hard_params;
scc_vec_unsafe_from_static_array(func_hard_params, func_hard_array); scc_vec_unsafe_from_static_array(func_hard_params, func_hard_array);
scc_ast_type_function_init(&func_hard_type, &ptr_to_array, scc_ast_type_function_init(&func_hard_type, &ptr_to_array,
&func_hard_params, scc_pos_create()); &func_hard_params, scc_pos_create());
scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", null, scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", nullptr,
scc_pos_create()); scc_pos_create());
scc_ast_decl_vec_t decls; scc_ast_decl_vec_t decls;
@@ -865,5 +874,5 @@ static void test_parser_unit(void) {
TEST_LIST = { TEST_LIST = {
{"parser_unit", test_parser_unit}, {"parser_unit", test_parser_unit},
{null, null}, {nullptr, nullptr},
}; };
+1 -1
View File
@@ -1,5 +1,5 @@
#include <utest/acutest.h> #include <utest/acutest.h>
TEST_LIST = { TEST_LIST = {
{NULL, NULL}, {nullptr, nullptr},
}; };
+2 -2
View File
@@ -33,7 +33,7 @@ typedef struct scc_macro_table {
* @brief 创建宏对象 * @brief 创建宏对象
* @param name 宏名称 * @param name 宏名称
* @param type 宏类型 * @param type 宏类型
* @return 创建的宏对象指针,失败返回NULL * @return 创建的宏对象指针,失败返回nullptr
*/ */
scc_pproc_macro_t *scc_pproc_macro_new(const scc_str_t *name, scc_pproc_macro_t *scc_pproc_macro_new(const scc_str_t *name,
scc_pproc_macro_type_t type); scc_pproc_macro_type_t type);
@@ -81,7 +81,7 @@ scc_pproc_macro_t *scc_pproc_macro_table_set(scc_pproc_macro_table_t *pp,
* @brief 查找宏定义 * @brief 查找宏定义
* @param pp 预处理器实例 * @param pp 预处理器实例
* @param name 宏名称 * @param name 宏名称
* @return 找到的宏对象指针,未找到返回NULL * @return 找到的宏对象指针,未找到返回nullptr
*/ */
scc_pproc_macro_t *scc_pproc_macro_table_get(scc_pproc_macro_table_t *pp, scc_pproc_macro_t *scc_pproc_macro_table_get(scc_pproc_macro_table_t *pp,
const scc_str_t *name); const scc_str_t *name);
+2 -2
View File
@@ -49,7 +49,7 @@ static inline int keyword_cmp(const char *name, int len) {
void scc_pproc_parse_macro_arguments(scc_lexer_tok_ring_t *ring, void scc_pproc_parse_macro_arguments(scc_lexer_tok_ring_t *ring,
scc_lexer_tok_vec_t *args, int need_full) { scc_lexer_tok_vec_t *args, int need_full) {
Assert(ring != null && args != null); Assert(ring != nullptr && args != nullptr);
scc_lexer_tok_t tok = {0}; scc_lexer_tok_t tok = {0};
int depth = 0; int depth = 0;
int ok; int ok;
@@ -337,7 +337,7 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
case SCC_PP_TOK_ELSE: case SCC_PP_TOK_ELSE:
case SCC_PP_TOK_ENDIF: { case SCC_PP_TOK_ENDIF: {
scc_lexer_tok_drop(&tok); scc_lexer_tok_drop(&tok);
scc_pproc_parse_if_defined(pp, type, null); scc_pproc_parse_if_defined(pp, type, nullptr);
scc_lexer_skip_until_newline(pp->cur_ring); scc_lexer_skip_until_newline(pp->cur_ring);
return; return;
} }
+15 -15
View File
@@ -22,7 +22,7 @@ static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
scc_str_append_ch(&str, '\"'); // 左引号 scc_str_append_ch(&str, '\"'); // 左引号
int need_space = 0; // 是否需要插入空格 int need_space = 0; // 是否需要插入空格
scc_lexer_tok_t *tok = null; scc_lexer_tok_t *tok = nullptr;
scc_vec_foreach(*arg_tokens, i) { scc_vec_foreach(*arg_tokens, i) {
tok = &scc_vec_at(*arg_tokens, i); tok = &scc_vec_at(*arg_tokens, i);
if (tok->type == SCC_TOK_BLANK) { if (tok->type == SCC_TOK_BLANK) {
@@ -61,10 +61,10 @@ static scc_lexer_tok_t concatenate_tokens(scc_pproc_expand_t *ctx,
const scc_lexer_tok_t *left, const scc_lexer_tok_t *left,
const scc_lexer_tok_t *right) { const scc_lexer_tok_t *right) {
scc_str_t new_lex = scc_str_from_cstr(""); scc_str_t new_lex = scc_str_from_cstr("");
if (left != null) { if (left != nullptr) {
scc_str_append(&new_lex, &left->lexeme); scc_str_append(&new_lex, &left->lexeme);
} }
if (right != null) { if (right != nullptr) {
scc_str_append(&new_lex, &right->lexeme); scc_str_append(&new_lex, &right->lexeme);
} }
@@ -154,7 +154,7 @@ void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
scc_lexer_tok_vec_t output_vec; scc_lexer_tok_vec_t output_vec;
scc_pproc_expand_by_vec(macro_table, &expaned_buffer, &output_vec, false, scc_pproc_expand_by_vec(macro_table, &expaned_buffer, &output_vec, false,
need_keep_org_pos); need_keep_org_pos);
Assert(output->cap == 0 && output->data == null); // FIXME hack it Assert(output->cap == 0 && output->data == nullptr); // FIXME hack it
*output = scc_lexer_array_to_ring(&output_vec); *output = scc_lexer_array_to_ring(&output_vec);
} }
@@ -186,7 +186,7 @@ static void disable(scc_pproc_expand_t *expand_ctx,
const scc_pproc_macro_t *macro) { const scc_pproc_macro_t *macro) {
scc_pproc_macro_t *expanded_macro = scc_pproc_macro_t *expanded_macro =
scc_pproc_macro_new(&macro->name, macro->type); scc_pproc_macro_new(&macro->name, macro->type);
if (expanded_macro == null) { if (expanded_macro == nullptr) {
LOG_FATAL("Out of memory"); LOG_FATAL("Out of memory");
} }
scc_pproc_macro_table_set(expand_ctx->expanded_set, expanded_macro); scc_pproc_macro_table_set(expand_ctx->expanded_set, expanded_macro);
@@ -200,7 +200,7 @@ static void enable(scc_pproc_expand_t *expand_ctx,
static cbool need_skip(scc_pproc_expand_t *expand_ctx, static cbool need_skip(scc_pproc_expand_t *expand_ctx,
const scc_pproc_macro_t *macro) { const scc_pproc_macro_t *macro) {
return scc_pproc_macro_table_get(expand_ctx->expanded_set, &macro->name) != return scc_pproc_macro_table_get(expand_ctx->expanded_set, &macro->name) !=
null; nullptr;
} }
static inline void static inline void
@@ -322,7 +322,7 @@ static void rescan(scc_pproc_expand_t *expand_ctx,
scc_pproc_macro_t *end_macro = scc_pproc_macro_t *end_macro =
scc_pproc_macro_table_get(expand_ctx->macro_table, &end_tok->lexeme); scc_pproc_macro_table_get(expand_ctx->macro_table, &end_tok->lexeme);
if (end_macro == null || end_macro->type != SCC_PP_MACRO_FUNCTION) { if (end_macro == nullptr || end_macro->type != SCC_PP_MACRO_FUNCTION) {
goto RETURN; goto RETURN;
} }
@@ -387,12 +387,12 @@ static void concact(scc_pproc_expand_t *ctx, scc_lexer_tok_vec_t *tok_buffer,
scc_lexer_tok_t *left; scc_lexer_tok_t *left;
if (left_idx < 0) { if (left_idx < 0) {
left = null; left = nullptr;
left_idx = 0; // FIXME for free tok_buffer left_idx = 0; // FIXME for free tok_buffer
} else { } else {
left = &scc_vec_at(*tok_buffer, left_idx); left = &scc_vec_at(*tok_buffer, left_idx);
if (gnu_va_arg_extend && left->type == SCC_TOK_COMMA) { if (gnu_va_arg_extend && left->type == SCC_TOK_COMMA) {
left = null; left = nullptr;
} }
} }
@@ -468,7 +468,7 @@ static inline void expand_function_macro(scc_pproc_expand_t *ctx,
scc_lexer_tok_t *right_tok; scc_lexer_tok_t *right_tok;
if (right_idx >= (int)scc_vec_size(macro->replaces)) { if (right_idx >= (int)scc_vec_size(macro->replaces)) {
right_tok = null; right_tok = nullptr;
} else { } else {
right_tok = &scc_vec_at(macro->replaces, right_idx); right_tok = &scc_vec_at(macro->replaces, right_idx);
} }
@@ -488,7 +488,7 @@ static inline void expand_function_macro(scc_pproc_expand_t *ctx,
} }
scc_lexer_tok_t *right = scc_lexer_tok_t *right =
scc_vec_size(right_vec) ? &scc_vec_at(right_vec, 0) : null; scc_vec_size(right_vec) ? &scc_vec_at(right_vec, 0) : nullptr;
// GNU ## extention // GNU ## extention
if (scc_strcmp(scc_str_as_cstr(&(right_tok->lexeme)), if (scc_strcmp(scc_str_as_cstr(&(right_tok->lexeme)),
@@ -559,7 +559,7 @@ static inline void expand_object_macro(scc_pproc_expand_t *ctx,
scc_lexer_tok_t *right; scc_lexer_tok_t *right;
if (right_idx >= (int)scc_vec_size(macro->replaces)) { if (right_idx >= (int)scc_vec_size(macro->replaces)) {
right = null; right = nullptr;
} else { } else {
right = &scc_vec_at(macro->replaces, right_idx); right = &scc_vec_at(macro->replaces, right_idx);
} }
@@ -588,7 +588,7 @@ static cbool parse_defined(scc_pproc_expand_t *expand_ctx, scc_pos_t *tok_pos) {
} }
if (scc_pproc_macro_table_get(expand_ctx->macro_table, if (scc_pproc_macro_table_get(expand_ctx->macro_table,
&next_tok.lexeme) == null) { &next_tok.lexeme) == nullptr) {
scc_lexer_tok_drop(&next_tok); scc_lexer_tok_drop(&next_tok);
scc_lexer_gen_number_false(&next_tok); scc_lexer_gen_number_false(&next_tok);
} else { } else {
@@ -609,7 +609,7 @@ static cbool parse_defined(scc_pproc_expand_t *expand_ctx, scc_pos_t *tok_pos) {
} else if (scc_get_tok_subtype(next_tok.type) == } else if (scc_get_tok_subtype(next_tok.type) ==
SCC_TOK_SUBTYPE_IDENTIFIER) { SCC_TOK_SUBTYPE_IDENTIFIER) {
if (scc_pproc_macro_table_get(expand_ctx->macro_table, if (scc_pproc_macro_table_get(expand_ctx->macro_table,
&next_tok.lexeme) == null) { &next_tok.lexeme) == nullptr) {
scc_lexer_tok_drop(&next_tok); scc_lexer_tok_drop(&next_tok);
scc_lexer_gen_number_false(&next_tok); scc_lexer_gen_number_false(&next_tok);
} else { } else {
@@ -649,7 +649,7 @@ void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx) {
scc_pproc_macro_t *macro = scc_pproc_macro_t *macro =
scc_pproc_macro_table_get(expand_ctx->macro_table, &tok.lexeme); scc_pproc_macro_table_get(expand_ctx->macro_table, &tok.lexeme);
if (macro == null || need_skip(expand_ctx, macro)) { if (macro == nullptr || need_skip(expand_ctx, macro)) {
// FIXME maybe keyword is error or don't parse c keyword or number // FIXME maybe keyword is error or don't parse c keyword or number
tok.type += SCC_TOK_DISABLED; tok.type += SCC_TOK_DISABLED;
scc_vec_push(expand_ctx->output, tok); scc_vec_push(expand_ctx->output, tok);
+1 -1
View File
@@ -83,7 +83,7 @@ cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type,
int defined = 0; int defined = 0;
if (tok) { if (tok) {
defined = (scc_pproc_macro_table_get(&pp->macro_table, defined = (scc_pproc_macro_table_get(&pp->macro_table,
&(tok->lexeme)) != null); &(tok->lexeme)) != nullptr);
} }
switch (type) { switch (type) {
case SCC_PP_TOK_IFDEF: case SCC_PP_TOK_IFDEF:
+1 -1
View File
@@ -43,7 +43,7 @@ FOPEN:
} }
scc_pproc_file_t *file = scc_malloc(sizeof(scc_pproc_file_t)); scc_pproc_file_t *file = scc_malloc(sizeof(scc_pproc_file_t));
Assert(file != null); Assert(file != nullptr);
if (scc_sstream_init(&(file->sstream), scc_str_as_cstr(&fpath), 1024)) { if (scc_sstream_init(&(file->sstream), scc_str_as_cstr(&fpath), 1024)) {
return -1; return -1;
} }
+5 -5
View File
@@ -6,7 +6,7 @@ scc_pproc_macro_t *scc_pproc_macro_new(const scc_str_t *name,
scc_pproc_macro_t *macro = scc_malloc(sizeof(scc_pproc_macro_t)); scc_pproc_macro_t *macro = scc_malloc(sizeof(scc_pproc_macro_t));
if (!macro) { if (!macro) {
LOG_ERROR("Failed to allocate memory for macro"); LOG_ERROR("Failed to allocate memory for macro");
return null; return nullptr;
} }
macro->name = scc_str_copy(name); macro->name = scc_str_copy(name);
@@ -96,7 +96,7 @@ cbool scc_pproc_add_function_macro(scc_pproc_macro_table_t *macros,
scc_pproc_macro_t *scc_pproc_macro_table_set(scc_pproc_macro_table_t *pp, scc_pproc_macro_t *scc_pproc_macro_table_set(scc_pproc_macro_table_t *pp,
scc_pproc_macro_t *macro) { scc_pproc_macro_t *macro) {
Assert(pp != null && macro != null && scc_str_len(&macro->name) != 0); Assert(pp != nullptr && macro != nullptr && scc_str_len(&macro->name) != 0);
scc_pproc_macro_t *old = scc_hashtable_set(&pp->table, &macro->name, macro); scc_pproc_macro_t *old = scc_hashtable_set(&pp->table, &macro->name, macro);
if (old && old != macro) { if (old && old != macro) {
LOG_WARN("same macro name `%s`", scc_str_as_cstr(&macro->name)); LOG_WARN("same macro name `%s`", scc_str_as_cstr(&macro->name));
@@ -142,7 +142,7 @@ static int hash_cmp(const void *key1, const void *key2) {
} }
void scc_pproc_marco_table_init(scc_pproc_macro_table_t *macros) { void scc_pproc_marco_table_init(scc_pproc_macro_table_t *macros) {
Assert(macros != null); Assert(macros != nullptr);
scc_hashtable_init(&macros->table, hash_func, hash_cmp); scc_hashtable_init(&macros->table, hash_func, hash_cmp);
} }
@@ -154,7 +154,7 @@ static int macro_free(const void *key, void *value, void *context) {
} }
void scc_pproc_macro_table_drop(scc_pproc_macro_table_t *macros) { void scc_pproc_macro_table_drop(scc_pproc_macro_table_t *macros) {
Assert(macros != null); Assert(macros != nullptr);
scc_hashtable_foreach(&macros->table, macro_free, null); scc_hashtable_foreach(&macros->table, macro_free, nullptr);
scc_hashtable_drop(&macros->table); scc_hashtable_drop(&macros->table);
} }
+4 -4
View File
@@ -4,7 +4,7 @@
#include <scc_pproc.h> #include <scc_pproc.h>
static int pproc_next_one_file(scc_pproc_t *pp, scc_lexer_tok_t *out) { static int pproc_next_one_file(scc_pproc_t *pp, scc_lexer_tok_t *out) {
scc_lexer_tok_ring_t *stream = null; scc_lexer_tok_ring_t *stream = nullptr;
scc_lexer_tok_t tok = {0}; scc_lexer_tok_t tok = {0};
int ok = 0; int ok = 0;
CONTINUE: CONTINUE:
@@ -57,7 +57,7 @@ CONTINUE:
// maybe expanded // maybe expanded
scc_pproc_macro_t *macro = scc_pproc_macro_t *macro =
scc_pproc_macro_table_get(&pp->macro_table, &tok.lexeme); scc_pproc_macro_table_get(&pp->macro_table, &tok.lexeme);
if (macro == null) { if (macro == nullptr) {
scc_ring_next_consume(*stream, *out, ok); scc_ring_next_consume(*stream, *out, ok);
return ok; return ok;
} }
@@ -118,7 +118,7 @@ void scc_pproc_add_builtin_macros(scc_pproc_macro_table_t *macro_table) {
} }
void scc_pproc_init(scc_pproc_t *pp, scc_lexer_tok_ring_t *input) { void scc_pproc_init(scc_pproc_t *pp, scc_lexer_tok_ring_t *input) {
Assert(pp != null && input != null); Assert(pp != nullptr && input != nullptr);
pp->org_ring = input; pp->org_ring = input;
pp->cur_ring = pp->org_ring; pp->cur_ring = pp->org_ring;
scc_ring_init(pp->expanded_ring, 0, 0, 0); scc_ring_init(pp->expanded_ring, 0, 0, 0);
@@ -171,7 +171,7 @@ scc_lexer_tok_ring_t *scc_pproc_to_ring(scc_pproc_t *pp, int ring_size,
// 销毁预处理器 // 销毁预处理器
void scc_pproc_drop(scc_pproc_t *pp) { void scc_pproc_drop(scc_pproc_t *pp) {
if (pp == null) if (pp == nullptr)
return; return;
Assert(pp->cur_ring == pp->org_ring); Assert(pp->cur_ring == pp->org_ring);
scc_lexer_drop_ring(pp->org_ring); scc_lexer_drop_ring(pp->org_ring);
+1 -1
View File
@@ -134,5 +134,5 @@ TEST_LIST = {
TEST_LIST_CASE(test_define_double_pos), TEST_LIST_CASE(test_define_double_pos),
TEST_LIST_CASE(test_define_param_pos), TEST_LIST_CASE(test_define_param_pos),
TEST_LIST_CASE(test_define_stringify_pos), TEST_LIST_CASE(test_define_stringify_pos),
{NULL, NULL}, {nullptr, nullptr},
}; };
+4 -4
View File
@@ -39,7 +39,7 @@ static cbool process_input(const char *input, scc_str_t *output) {
do { \ do { \
scc_str_t output; \ scc_str_t output; \
process_input(input, &output); \ process_input(input, &output); \
assert(output.data != NULL); \ assert(output.data != nullptr); \
TEST_CHECK(strcmp(output.data, expect) == 0); \ TEST_CHECK(strcmp(output.data, expect) == 0); \
TEST_MSG("Expected: %s", expect); \ TEST_MSG("Expected: %s", expect); \
TEST_MSG("Produced: %s", output.data); \ TEST_MSG("Produced: %s", output.data); \
@@ -50,8 +50,8 @@ static cbool process_input(const char *input, scc_str_t *output) {
do { \ do { \
scc_str_t output; \ scc_str_t output; \
process_input(input, &output); \ process_input(input, &output); \
assert(output.data != NULL); \ assert(output.data != nullptr); \
TEST_CHECK(strstr(output.data, expect) != NULL); \ TEST_CHECK(strstr(output.data, expect) != nullptr); \
TEST_MSG("Expected: %s", expect); \ TEST_MSG("Expected: %s", expect); \
TEST_MSG("Produced: %s", output.data); \ TEST_MSG("Produced: %s", output.data); \
scc_str_drop(&output); \ scc_str_drop(&output); \
@@ -649,5 +649,5 @@ TEST_LIST = {
TEST_LIST_CASE(test_real_case), TEST_LIST_CASE(test_real_case),
TEST_LIST_CASE(test_c99_docs), TEST_LIST_CASE(test_c99_docs),
{NULL, NULL}, {nullptr, nullptr},
}; };
+1 -1
View File
@@ -25,7 +25,7 @@ static inline sccf_sym_t *
sccf_builder_get_symbol_unsafe(sccf_builder_t *builder, const char *name) { sccf_builder_get_symbol_unsafe(sccf_builder_t *builder, const char *name) {
usize idx = sccf_builder_get_symbol_idx(builder, name); usize idx = sccf_builder_get_symbol_idx(builder, name);
if (idx == 0) { if (idx == 0) {
return null; return nullptr;
} }
return &scc_vec_at(builder->symtab, idx); return &scc_vec_at(builder->symtab, idx);
} }
+4 -4
View File
@@ -34,12 +34,12 @@ static inline u8 *sccf_sect_header_table(u8 *base) {
* @brief 获取指定索引的节头指针 * @brief 获取指定索引的节头指针
* @param base 文件缓冲区起始地址 * @param base 文件缓冲区起始地址
* @param idx 节索引 (0 <= idx < sect_header_num) * @param idx 节索引 (0 <= idx < sect_header_num)
* @return 指向该节头的指针, 若索引无效返回 null * @return 指向该节头的指针, 若索引无效返回 nullptr
*/ */
static inline sccf_sect_header_t *sccf_sect_header(u8 *base, usize idx) { static inline sccf_sect_header_t *sccf_sect_header(u8 *base, usize idx) {
sccf_header_t *hdr = (sccf_header_t *)base; sccf_header_t *hdr = (sccf_header_t *)base;
if (idx >= (usize)hdr->sect_header_num) if (idx >= (usize)hdr->sect_header_num)
return null; return nullptr;
u8 *table = sccf_sect_header_table(base); u8 *table = sccf_sect_header_table(base);
return (sccf_sect_header_t *)(table + idx * sizeof(sccf_sect_header_t)); return (sccf_sect_header_t *)(table + idx * sizeof(sccf_sect_header_t));
} }
@@ -76,11 +76,11 @@ static inline usize sccf_sect_data_offset(u8 *base, usize idx) {
* @brief 获取指定索引的节数据起始地址 * @brief 获取指定索引的节数据起始地址
* @param base 文件缓冲区起始地址 * @param base 文件缓冲区起始地址
* @param idx 节索引 * @param idx 节索引
* @return 数据起始地址, 若索引无效返回 null * @return 数据起始地址, 若索引无效返回 nullptr
*/ */
static inline u8 *sccf_sect_data(u8 *base, usize idx) { static inline u8 *sccf_sect_data(u8 *base, usize idx) {
usize off = sccf_sect_data_offset(base, idx); usize off = sccf_sect_data_offset(base, idx);
return (off == 0) ? null : base + off; return (off == 0) ? nullptr : base + off;
} }
/** @} */ /** @} */
+8 -8
View File
@@ -14,11 +14,11 @@ void sccf_builder_init(sccf_builder_t *builder) {
scc_vec_init(builder->relocs); scc_vec_init(builder->relocs);
scc_vec_init(builder->symtab); scc_vec_init(builder->symtab);
builder->entry_symbol_name = null; builder->entry_symbol_name = nullptr;
///< Push null ///< Push nullptr
scc_vec_push(builder->strtab, (char)'\0'); scc_vec_push(builder->strtab, (char)'\0');
///< Push null ///< Push nullptr
scc_vec_push(builder->symtab, (sccf_sym_t){0}); scc_vec_push(builder->symtab, (sccf_sym_t){0});
} }
@@ -69,12 +69,12 @@ void sccf_builder_add_section(sccf_builder_t *builder,
} }
const sccf_t *sccf_builder_to_sccf(sccf_builder_t *builder) { const sccf_t *sccf_builder_to_sccf(sccf_builder_t *builder) {
if (builder->entry_symbol_name == null) { if (builder->entry_symbol_name == nullptr) {
builder->sccf.header.entry_point = 0; builder->sccf.header.entry_point = 0;
} else { } else {
sccf_sym_t *sym = sccf_sym_t *sym =
sccf_builder_get_symbol_unsafe(builder, builder->entry_symbol_name); sccf_builder_get_symbol_unsafe(builder, builder->entry_symbol_name);
if (sym == null || sym->sccf_sect_type != SCCF_SECT_CODE) { if (sym == nullptr || sym->sccf_sect_type != SCCF_SECT_CODE) {
LOG_ERROR("entry symbol %s not found"); LOG_ERROR("entry symbol %s not found");
builder->sccf.header.entry_point = 0; builder->sccf.header.entry_point = 0;
} else { } else {
@@ -125,14 +125,14 @@ const sccf_t *sccf_builder_to_sccf(sccf_builder_t *builder) {
} }
void sccf_builder_to_buffer(sccf_builder_t *builder, sccf_buffer_t *buffer) { void sccf_builder_to_buffer(sccf_builder_t *builder, sccf_buffer_t *buffer) {
Assert(builder != null && buffer != null); Assert(builder != nullptr && buffer != nullptr);
sccf_write(sccf_builder_to_sccf(builder), buffer); sccf_write(sccf_builder_to_sccf(builder), buffer);
} }
void sccf_builder_to_file(sccf_builder_t *builder, const char *file_path) { void sccf_builder_to_file(sccf_builder_t *builder, const char *file_path) {
Assert(builder != null && file_path != null); Assert(builder != nullptr && file_path != nullptr);
scc_file_t fp = scc_fopen(file_path, SCC_FILE_WRITE); scc_file_t fp = scc_fopen(file_path, SCC_FILE_WRITE);
if (fp == null) { if (fp == nullptr) {
LOG_ERROR("file can't open %s", file_path); LOG_ERROR("file can't open %s", file_path);
return; return;
} }
+1 -1
View File
@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
ring = scc_sstream_ref_ring(&stream); ring = scc_sstream_ref_ring(&stream);
Assert(ring != null); Assert(ring != nullptr);
printf("Reading file: %s\n", filename); printf("Reading file: %s\n", filename);
+2 -2
View File
@@ -14,8 +14,8 @@ extern logger_t __scc_usr_log;
"%s:%zu:%zu: ", (pos).name, (pos).line, (pos).col); \ "%s:%zu:%zu: ", (pos).name, (pos).line, (pos).col); \
scc_snprintf(_full_msg + _n, sizeof(_full_msg) - _n, fmt, \ scc_snprintf(_full_msg + _n, sizeof(_full_msg) - _n, fmt, \
##__VA_ARGS__); \ ##__VA_ARGS__); \
__scc_usr_log.handler(&__scc_usr_log, level, null, 0, null, "%s", \ __scc_usr_log.handler(&__scc_usr_log, level, nullptr, 0, nullptr, \
_full_msg); \ "%s", _full_msg); \
} while (0) } while (0)
#define SCC_DEBUG(pos, fmt, ...) \ #define SCC_DEBUG(pos, fmt, ...) \
+1 -1
View File
@@ -7,7 +7,7 @@ static int user_log_handler(logger_t *module, log_level_t level,
/* clang-format off */ /* clang-format off */
(void) module, (void)file, (void)line, (void)func; // 不再使用 (void) module, (void)file, (void)line, (void)func; // 不再使用
const char *level_str = null; const char *level_str = nullptr;
switch (level) { switch (level) {
case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break; case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break;
case LOG_LEVEL_INFO: level_str = "INFO "; break; case LOG_LEVEL_INFO: level_str = "INFO "; break;
+7 -7
View File
@@ -67,7 +67,7 @@ static int sstream_scan_at(scc_sstream_t *stream, scc_pos_t scan_pos,
// 环形缓冲区填充回调(通过 userdata 获取流对象) // 环形缓冲区填充回调(通过 userdata 获取流对象)
static cbool fill_func(scc_sstream_char_t *out, void *userdata) { static cbool fill_func(scc_sstream_char_t *out, void *userdata) {
Assert(out != null && userdata != null); Assert(out != nullptr && userdata != nullptr);
scc_sstream_t *stream = (scc_sstream_t *)userdata; scc_sstream_t *stream = (scc_sstream_t *)userdata;
if (stream->fill_pos.offset >= stream->len) if (stream->fill_pos.offset >= stream->len)
return false; // 已到文件尾 return false; // 已到文件尾
@@ -81,9 +81,9 @@ static cbool fill_func(scc_sstream_char_t *out, void *userdata) {
} }
int scc_sstream_init(scc_sstream_t *stream, const char *fname, int ring_size) { int scc_sstream_init(scc_sstream_t *stream, const char *fname, int ring_size) {
Assert(stream != null && fname != null); Assert(stream != nullptr && fname != nullptr);
scc_file_t file = scc_fopen(fname, SCC_FILE_READ); scc_file_t file = scc_fopen(fname, SCC_FILE_READ);
if (file == null) { if (file == nullptr) {
LOG_ERROR("Failed to open file: %s", fname); LOG_ERROR("Failed to open file: %s", fname);
return 1; return 1;
} }
@@ -123,13 +123,13 @@ int scc_sstream_init_by_buffer(scc_sstream_t *stream, const char *buffer,
} }
scc_sstream_ring_t *scc_sstream_to_ring(scc_sstream_t *stream) { scc_sstream_ring_t *scc_sstream_to_ring(scc_sstream_t *stream) {
Assert(stream != null); Assert(stream != nullptr);
stream->used++; stream->used++;
return &stream->ring; return &stream->ring;
} }
void scc_sstream_drop_ring(scc_sstream_ring_t *ring) { void scc_sstream_drop_ring(scc_sstream_ring_t *ring) {
Assert(ring != null && ring->userdata != null); Assert(ring != nullptr && ring->userdata != nullptr);
scc_sstream_t *stream = (scc_sstream_t *)ring->userdata; scc_sstream_t *stream = (scc_sstream_t *)ring->userdata;
if (stream->used > 0) { if (stream->used > 0) {
stream->used--; stream->used--;
@@ -139,14 +139,14 @@ void scc_sstream_drop_ring(scc_sstream_ring_t *ring) {
} }
void scc_sstream_drop(scc_sstream_t *stream) { void scc_sstream_drop(scc_sstream_t *stream) {
Assert(stream != null); Assert(stream != nullptr);
if (stream->used) { if (stream->used) {
LOG_FATAL("drop sstream must be drop ring before ref [%d]", LOG_FATAL("drop sstream must be drop ring before ref [%d]",
stream->used); stream->used);
} }
if (stream->src && stream->owned_src) { if (stream->src && stream->owned_src) {
scc_free((void *)stream->src); scc_free((void *)stream->src);
stream->src = null; stream->src = nullptr;
} }
scc_ring_free(stream->ring); scc_ring_free(stream->ring);
} }
+2 -2
View File
@@ -384,7 +384,7 @@ typedef struct _IMAGE_SECTION_HEADER {
// 导入表相关 // 导入表相关
typedef struct _IMAGE_IMPORT_DESCRIPTOR { typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union { union {
DWORD Characteristics; // 0 for terminating null import descriptor DWORD Characteristics; // 0 for terminating nullptr import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT DWORD OriginalFirstThunk; // RVA to original unbound IAT
// (PIMAGE_THUNK_DATA) // (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME; } DUMMYUNIONNAME;
@@ -680,7 +680,7 @@ typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL;
// 符号存储类 // 符号存储类
#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE) - 1 #define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE) - 1
#define IMAGE_SYM_CLASS_NULL 0x0000 #define IMAGE_SYM_CLASS_nullptr 0x0000
#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 #define IMAGE_SYM_CLASS_AUTOMATIC 0x0001
#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 #define IMAGE_SYM_CLASS_EXTERNAL 0x0002
#define IMAGE_SYM_CLASS_STATIC 0x0003 #define IMAGE_SYM_CLASS_STATIC 0x0003
+1 -1
View File
@@ -355,7 +355,7 @@ scc_pe_section_range scc_pe_reserve_section_header(scc_pe_builder_t *builder,
void scc_pe_write_section(scc_pe_builder_t *builder, void scc_pe_write_section(scc_pe_builder_t *builder,
scc_pe_section_range *range, u8 *data, scc_pe_section_range *range, u8 *data,
usize data_size) { usize data_size) {
if (range == null || data == null || data_size == 0) { if (range == nullptr || data == nullptr || data_size == 0) {
return; return;
} }
padding_util(builder, range->file_offset); padding_util(builder, range->file_offset);
+4 -3
View File
@@ -156,11 +156,12 @@ scc_pe_buffer_t scc_pe_construct_idata(scc_pe_idata_builder_t *builder,
&scc_vec_at(lookup_table, 0), table_size); &scc_vec_at(lookup_table, 0), table_size);
} }
// 添加NULL终止的目录项 // 添加nullptr终止的目录项
IMAGE_IMPORT_DESCRIPTOR null_entry = image_import_descriptor_init(0, 0, 0); IMAGE_IMPORT_DESCRIPTOR nullptr_entry =
image_import_descriptor_init(0, 0, 0);
scc_memcpy(&scc_vec_at(builder->buffer, scc_memcpy(&scc_vec_at(builder->buffer,
import_file_count * sizeof(IMAGE_IMPORT_DESCRIPTOR)), import_file_count * sizeof(IMAGE_IMPORT_DESCRIPTOR)),
&null_entry, sizeof(IMAGE_IMPORT_DESCRIPTOR)); &nullptr_entry, sizeof(IMAGE_IMPORT_DESCRIPTOR));
// 填充Hint/Name表 // 填充Hint/Name表
scc_memcpy(&scc_vec_at(builder->buffer, hnt_offset), scc_memcpy(&scc_vec_at(builder->buffer, hnt_offset),
+10 -10
View File
@@ -22,14 +22,14 @@ static void load_from_def(pe_idata_lib_ctx_t *ctx, const char *file_path,
scc_str_append_cstr(&fpath, ".def", 4); scc_str_append_cstr(&fpath, ".def", 4);
const char *fname = scc_str_as_cstr(&fpath); const char *fname = scc_str_as_cstr(&fpath);
scc_file_t fp = scc_fopen(fname, SCC_FILE_READ); scc_file_t fp = scc_fopen(fname, SCC_FILE_READ);
if (fp == null) { if (fp == nullptr) {
LOG_ERROR("load_from_def file read error: %s", fname); LOG_ERROR("load_from_def file read error: %s", fname);
return; return;
} }
usize fsize = scc_fsize(fp); usize fsize = scc_fsize(fp);
char *buffer = scc_malloc(fsize); char *buffer = scc_malloc(fsize);
Assert(buffer != null); Assert(buffer != nullptr);
usize read_size = scc_fread(fp, buffer, fsize); usize read_size = scc_fread(fp, buffer, fsize);
Assert(read_size == fsize); Assert(read_size == fsize);
@@ -71,11 +71,11 @@ static void pe_idata_lib_init(pe_idata_lib_ctx_t *ctx, const char *find_path) {
static cbool pe_idata_get(pe_idata_lib_ctx_t *ctx, const char *name) { static cbool pe_idata_get(pe_idata_lib_ctx_t *ctx, const char *name) {
const char *lib_name = scc_hashtable_get(&ctx->str2libsym, name); const char *lib_name = scc_hashtable_get(&ctx->str2libsym, name);
if (lib_name == null) { if (lib_name == nullptr) {
return false; return false;
} }
scc_pe_idata_lib_t *lib = null; scc_pe_idata_lib_t *lib = nullptr;
scc_vec_foreach(ctx->idata_libs, i) { scc_vec_foreach(ctx->idata_libs, i) {
scc_pe_idata_lib_t *idata_lib = &scc_vec_at(ctx->idata_libs, i); scc_pe_idata_lib_t *idata_lib = &scc_vec_at(ctx->idata_libs, i);
if (scc_strcmp(lib_name, idata_lib->name) == 0) { if (scc_strcmp(lib_name, idata_lib->name) == 0) {
@@ -83,7 +83,7 @@ static cbool pe_idata_get(pe_idata_lib_ctx_t *ctx, const char *name) {
break; break;
} }
} }
if (lib == null) { if (lib == nullptr) {
scc_pe_idata_lib_t new_lib; scc_pe_idata_lib_t new_lib;
new_lib.name = lib_name; new_lib.name = lib_name;
scc_vec_init(new_lib.symbol_names); scc_vec_init(new_lib.symbol_names);
@@ -104,8 +104,8 @@ void sccf2pe(scc_pe_builder_t *builder, const sccf_t *sccf) {
sccf_sym_vec_t symtab; sccf_sym_vec_t symtab;
scc_vec_init(symtab); scc_vec_init(symtab);
sccf_sect_data_t *code_data = null; sccf_sect_data_t *code_data = nullptr;
sccf_sect_data_t *data_data = null; sccf_sect_data_t *data_data = nullptr;
int num_of_section = 1; int num_of_section = 1;
scc_vec_foreach(sccf->sect_headers, i) { scc_vec_foreach(sccf->sect_headers, i) {
sccf_sect_header_t *sect_header = &scc_vec_at(sccf->sect_headers, i); sccf_sect_header_t *sect_header = &scc_vec_at(sccf->sect_headers, i);
@@ -221,18 +221,18 @@ void sccf2pe(scc_pe_builder_t *builder, const sccf_t *sccf) {
TODO(); TODO();
} }
rva -= code_range.virual_address + reloc->offset + reloc->addend; rva -= code_range.virual_address + reloc->offset + reloc->addend;
Assert(code_data != null); Assert(code_data != nullptr);
// FIXME 需要确保宿主机与目标机器大小端一致 // FIXME 需要确保宿主机与目标机器大小端一致
*(u32 *)(scc_vec_unsafe_get_data(*code_data) + reloc->offset) = rva; *(u32 *)(scc_vec_unsafe_get_data(*code_data) + reloc->offset) = rva;
} }
scc_pe_write_header(builder, &config); scc_pe_write_header(builder, &config);
if (code_data != null) { if (code_data != nullptr) {
scc_pe_write_section(builder, &code_range, scc_pe_write_section(builder, &code_range,
(u8 *)scc_vec_unsafe_get_data(*code_data), (u8 *)scc_vec_unsafe_get_data(*code_data),
scc_vec_size(*code_data)); scc_vec_size(*code_data));
} }
if (data_data != null) { if (data_data != nullptr) {
scc_pe_write_section(builder, &data_range, scc_pe_write_section(builder, &data_range,
(u8 *)scc_vec_unsafe_get_data(*data_data), (u8 *)scc_vec_unsafe_get_data(*data_data),
scc_vec_size(*data_data)); scc_vec_size(*data_data));
+2 -2
View File
@@ -92,7 +92,7 @@ void scc_tree_dump_append_fmt(scc_tree_dump_t *td, const char *fmt, ...) {
// 计算所需长度 // 计算所需长度
va_list args_copy; va_list args_copy;
va_copy(args_copy, args); va_copy(args_copy, args);
usize len = scc_vsnprintf(null, 0, fmt, args_copy); usize len = scc_vsnprintf(nullptr, 0, fmt, args_copy);
va_end(args_copy); va_end(args_copy);
if (len == 0) { if (len == 0) {
va_end(args); va_end(args);
@@ -105,7 +105,7 @@ void scc_tree_dump_append_fmt(scc_tree_dump_t *td, const char *fmt, ...) {
new_cap = new_cap ? new_cap * 2 : 16; new_cap = new_cap ? new_cap * 2 : 16;
} }
char *new_data = (char *)scc_realloc(td->buf.data, new_cap); char *new_data = (char *)scc_realloc(td->buf.data, new_cap);
Assert(new_data != null); Assert(new_data != nullptr);
td->buf.data = new_data; td->buf.data = new_data;
td->buf.cap = new_cap; td->buf.cap = new_cap;
} }
+3 -3
View File
@@ -88,7 +88,7 @@ extern logger_t __default_logger_root;
/** /**
* @brief 初始化日志实例 其余参数设置为默认值 * @brief 初始化日志实例 其余参数设置为默认值
* @param[in] logger 日志器实例指针 * @param[in] logger 日志器实例指针
* @param[in] name 日志器名称(NULL表示获取默认日志器名称) * @param[in] name 日志器名称(nullptr表示获取默认日志器名称)
*/ */
void init_logger(logger_t *logger, const char *name); void init_logger(logger_t *logger, const char *name);
@@ -102,7 +102,7 @@ void log_set_level(logger_t *logger, int level);
/** /**
* @brief 设置自定义日志处理器 * @brief 设置自定义日志处理器
* @param[in] logger 目标日志器实例 * @param[in] logger 目标日志器实例
* @param[in] handler 自定义处理函数(NULL恢复默认处理) * @param[in] handler 自定义处理函数(nullptr恢复默认处理)
*/ */
void log_set_handler(logger_t *logger, log_handler handler); void log_set_handler(logger_t *logger, log_handler handler);
@@ -115,7 +115,7 @@ void log_set_handler(logger_t *logger, log_handler handler);
#define SCC_LOG_IMPL(_module_, _level_, _fmt_, ...) \ #define SCC_LOG_IMPL(_module_, _level_, _fmt_, ...) \
do { \ do { \
/* TODO check _module_ is NULL */ \ /* TODO check _module_ is nullptr */ \
if ((_module_)->handler && ((_module_)->level & (_level_))) \ if ((_module_)->handler && ((_module_)->level & (_level_))) \
(_module_)->handler( \ (_module_)->handler( \
SCC_LOG_HANDLE_ARGS(_module_, _level_, _fmt_, ##__VA_ARGS__)); \ SCC_LOG_HANDLE_ARGS(_module_, _level_, _fmt_, ##__VA_ARGS__)); \
+6 -6
View File
@@ -57,7 +57,7 @@
break; \ break; \
} \ } \
usize phys_tail = _scc_ring_phys(ring, (ring).tail); \ usize phys_tail = _scc_ring_phys(ring, (ring).tail); \
if ((ring).fill == null || \ if ((ring).fill == nullptr || \
!(ring).fill(&((ring).data[phys_tail]), (ring).userdata)) { \ !(ring).fill(&((ring).data[phys_tail]), (ring).userdata)) { \
ok = 0; \ ok = 0; \
break; \ break; \
@@ -97,14 +97,14 @@
* @brief 初始化环形缓冲区 * @brief 初始化环形缓冲区
* @param ring 环形缓冲区变量 * @param ring 环形缓冲区变量
* @param cap 容量 * @param cap 容量
* @param fill_func 填充回调函数 (可传 NULL) 返回true表示成功 * @param fill_func 填充回调函数 (可传 nullptr) 返回true表示成功
* *
* 内存分配失败由 scc_malloc 内部处理 (如 LOG_FATAL) * 内存分配失败由 scc_malloc 内部处理 (如 LOG_FATAL)
*/ */
#define scc_ring_init(ring, _cap, fill_func, _userdata) \ #define scc_ring_init(ring, _cap, fill_func, _userdata) \
do { \ do { \
(ring).data = \ (ring).data = \
(_cap) != 0 ? scc_malloc((_cap) * sizeof(*(ring).data)) : null; \ (_cap) != 0 ? scc_malloc((_cap) * sizeof(*(ring).data)) : nullptr; \
(ring).cap = (_cap); \ (ring).cap = (_cap); \
(ring).head = 0; \ (ring).head = 0; \
(ring).probe = 0; \ (ring).probe = 0; \
@@ -120,8 +120,8 @@
(ring).head = 0; \ (ring).head = 0; \
(ring).probe = 0; \ (ring).probe = 0; \
(ring).tail = (size); \ (ring).tail = (size); \
(ring).fill = null; \ (ring).fill = nullptr; \
(ring).userdata = null; \ (ring).userdata = nullptr; \
} while (0) } while (0)
/** /**
@@ -131,7 +131,7 @@
#define scc_ring_free(ring) \ #define scc_ring_free(ring) \
do { \ do { \
scc_free((ring).data); \ scc_free((ring).data); \
(ring).data = NULL; \ (ring).data = nullptr; \
(ring).cap = (ring).head = (ring).probe = (ring).tail = 0; \ (ring).cap = (ring).head = (ring).probe = (ring).tail = 0; \
} while (0) } while (0)
+20 -20
View File
@@ -22,12 +22,12 @@ typedef struct scc_str {
* @return cstring_t 初始化后的对象 * @return cstring_t 初始化后的对象
*/ */
static inline scc_str_t scc_str_empty(void) { static inline scc_str_t scc_str_empty(void) {
return (scc_str_t){.data = null, .size = 0, .cap = 0}; return (scc_str_t){.data = nullptr, .size = 0, .cap = 0};
} }
static inline void scc_str_init(scc_str_t *string) { static inline void scc_str_init(scc_str_t *string) {
Assert(string != null); Assert(string != nullptr);
string->data = null; string->data = nullptr;
string->size = 0; string->size = 0;
string->cap = 0; string->cap = 0;
} }
@@ -39,7 +39,7 @@ static inline void scc_str_init(scc_str_t *string) {
* @return cstring_t 新建对象,包含输入字符串的副本 * @return cstring_t 新建对象,包含输入字符串的副本
*/ */
static inline scc_str_t scc_str_from_cstr(const char *s) { static inline scc_str_t scc_str_from_cstr(const char *s) {
if (s == null) { if (s == nullptr) {
return scc_str_empty(); return scc_str_empty();
} }
@@ -49,7 +49,7 @@ static inline scc_str_t scc_str_from_cstr(const char *s) {
len++; len++;
char *data = (char *)scc_malloc(len + 1); char *data = (char *)scc_malloc(len + 1);
Assert(data != null); Assert(data != nullptr);
scc_memcpy(data, s, len); scc_memcpy(data, s, len);
data[len] = '\0'; data[len] = '\0';
@@ -66,12 +66,12 @@ static inline scc_str_t scc_str_copy(const scc_str_t *s) {
* @param str 要被释放的字符串指针 * @param str 要被释放的字符串指针
*/ */
static inline void scc_str_drop(scc_str_t *str) { static inline void scc_str_drop(scc_str_t *str) {
if (str == null) { if (str == nullptr) {
return; return;
} }
if (str->data != null) { if (str->data != nullptr) {
scc_free(str->data); scc_free(str->data);
str->data = null; str->data = nullptr;
} }
str->size = 0; str->size = 0;
str->cap = 0; str->cap = 0;
@@ -86,7 +86,7 @@ static inline void scc_str_drop(scc_str_t *str) {
*/ */
static inline void scc_str_append_cstr(scc_str_t *str, const char *data, static inline void scc_str_append_cstr(scc_str_t *str, const char *data,
usize len) { usize len) {
if (str == null || data == null || len == 0) { if (str == nullptr || data == nullptr || len == 0) {
return; return;
} }
@@ -109,7 +109,7 @@ static inline void scc_str_append_cstr(scc_str_t *str, const char *data,
} }
char *new_data = (char *)scc_realloc(str->data, new_cap); char *new_data = (char *)scc_realloc(str->data, new_cap);
Assert(new_data != null); Assert(new_data != nullptr);
str->data = new_data; str->data = new_data;
str->cap = new_cap; str->cap = new_cap;
@@ -117,7 +117,7 @@ static inline void scc_str_append_cstr(scc_str_t *str, const char *data,
scc_memcpy(str->data + str->size - 1, data, len); scc_memcpy(str->data + str->size - 1, data, len);
str->size += len; str->size += len;
Assert(str->data != null); Assert(str->data != nullptr);
str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性 str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性
} }
@@ -136,7 +136,7 @@ static inline void scc_str_append(scc_str_t *str, const scc_str_t *other) {
static inline void scc_str_append_fmt(scc_str_t *str, const char *fmt, ...) { static inline void scc_str_append_fmt(scc_str_t *str, const char *fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
usize needed = scc_vsnprintf(null, 0, fmt, args); usize needed = scc_vsnprintf(nullptr, 0, fmt, args);
va_end(args); va_end(args);
if (needed == 0) if (needed == 0)
return; return;
@@ -148,7 +148,7 @@ static inline void scc_str_append_fmt(scc_str_t *str, const char *fmt, ...) {
new_cap = new_cap ? new_cap * 2 : (needed + 16); new_cap = new_cap ? new_cap * 2 : (needed + 16);
} }
char *new_data = (char *)scc_realloc(str->data, new_cap); char *new_data = (char *)scc_realloc(str->data, new_cap);
Assert(new_data != NULL); Assert(new_data != nullptr);
str->data = new_data; str->data = new_data;
str->cap = new_cap; str->cap = new_cap;
} }
@@ -178,7 +178,7 @@ static inline void scc_str_append_ch(scc_str_t *str, char ch) {
* @return usize 字符串实际长度 * @return usize 字符串实际长度
*/ */
static inline usize scc_str_len(const scc_str_t *str) { static inline usize scc_str_len(const scc_str_t *str) {
if (str == null) { if (str == nullptr) {
return 0; return 0;
} }
if (str->size == 0) { if (str->size == 0) {
@@ -194,7 +194,7 @@ static inline usize scc_str_len(const scc_str_t *str) {
* @return cbool * @return cbool
*/ */
static inline cbool scc_str_is_empty(const scc_str_t *str) { static inline cbool scc_str_is_empty(const scc_str_t *str) {
return str == null || str->size == 0; return str == nullptr || str->size == 0;
} }
/** /**
@@ -218,8 +218,8 @@ static inline void scc_str_clear(scc_str_t *str) {
* @return char* 返回指向内部缓冲区的 C 风格字符串指针 * @return char* 返回指向内部缓冲区的 C 风格字符串指针
*/ */
static inline char *scc_str_as_cstr(const scc_str_t *str) { static inline char *scc_str_as_cstr(const scc_str_t *str) {
if (str == null || str->data == null) { if (str == nullptr || str->data == nullptr) {
return null; return nullptr;
} }
return str->data; return str->data;
} }
@@ -229,11 +229,11 @@ static inline int scc_str_equal(const scc_str_t *str1, const scc_str_t *str2) {
} }
static inline char *scc_str_move_cstr(scc_str_t *str) { static inline char *scc_str_move_cstr(scc_str_t *str) {
if (str == null || str->data == null) { if (str == nullptr || str->data == nullptr) {
return null; return nullptr;
} }
char *ret = str->data; char *ret = str->data;
str->data = null; str->data = nullptr;
str->cap = 0; str->cap = 0;
str->size = 0; str->size = 0;
return ret; return ret;
+7 -7
View File
@@ -26,14 +26,14 @@ typedef float f32;
typedef double f64; typedef double f64;
typedef bool cbool; typedef bool cbool;
/// void / null /// void / nullptr
#define null NULL #ifndef nullptr
#define nullptr NULL
#endif
/* clang-format on */ /* clang-format on */
static_assert(sizeof(cbool) == 1, "cbool size must 1");
#else
/* clang-format off */ /* clang-format off */
#else
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
@@ -58,8 +58,8 @@ typedef double f64;
typedef bool cbool; typedef bool cbool;
#ifndef null #ifndef nullptr
#define null NULL #define nullptr nullptr
#endif #endif
/* clang-format on */ /* clang-format on */
+2 -2
View File
@@ -106,7 +106,7 @@ typedef size_t usize;
int cap = (vec).cap ? (vec).cap * 2 : 4; \ int cap = (vec).cap ? (vec).cap * 2 : 4; \
scc_vec_realloc(vec, cap); \ scc_vec_realloc(vec, cap); \
} \ } \
Assert((vec).data != null); \ Assert((vec).data != nullptr); \
(vec).data[(vec).size++] = value; \ (vec).data[(vec).size++] = value; \
} while (0) } while (0)
@@ -147,7 +147,7 @@ typedef size_t usize;
#define scc_vec_free(vec) \ #define scc_vec_free(vec) \
do { \ do { \
__scc_vec_free((vec).data); \ __scc_vec_free((vec).data); \
(vec).data = NULL; \ (vec).data = nullptr; \
(vec).size = (vec).cap = 0; \ (vec).size = (vec).cap = 0; \
} while (0) } while (0)
+2 -2
View File
@@ -51,7 +51,7 @@ void reset_token_fill(void) { token_id = 0; }
void free_token(test_token_t *tok) { void free_token(test_token_t *tok) {
if (tok->data) { if (tok->data) {
scc_free(tok->data); scc_free(tok->data);
tok->data = NULL; tok->data = nullptr;
} }
} }
@@ -323,4 +323,4 @@ TEST_LIST = {{"test_char_ring_basic", test_char_ring_basic},
{"test_char_ring_wrap", test_char_ring_wrap}, {"test_char_ring_wrap", test_char_ring_wrap},
{"test_token_ring_basic", test_token_ring_basic}, {"test_token_ring_basic", test_token_ring_basic},
{"test_token_ring_full", test_token_ring_full}, {"test_token_ring_full", test_token_ring_full},
{NULL, NULL}}; {nullptr, nullptr}};
+8 -7
View File
@@ -10,9 +10,9 @@
#ifndef __KLLIST_H__ #ifndef __KLLIST_H__
#define __KLLIST_H__ #define __KLLIST_H__
#ifndef NULL #ifndef nullptr
#define NULL (0) #define nullptr (0)
#define __NULL_KLIST_DEFINED__ #define __nullptr_KLIST_DEFINED__
#endif #endif
#ifndef container_of #ifndef container_of
@@ -88,8 +88,8 @@ static inline void __list_del(struct list_head *prev, struct list_head *next) {
static inline void list_del(struct list_head *entry) { static inline void list_del(struct list_head *entry) {
__list_del(entry->prev, entry->next); __list_del(entry->prev, entry->next);
entry->next = NULL; entry->next = nullptr;
entry->prev = NULL; entry->prev = nullptr;
} }
/** /**
@@ -159,8 +159,9 @@ typedef int (*list_cmp_func_t)(void *, const struct list_head *,
static void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp); static void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);
#endif #endif
#if defined(__NULL_KLIST_DEFINED__) && !defined(__NULL_KLIST_DEFINED_NOMOVE__) #if defined(__nullptr_KLIST_DEFINED__) && \
#undef NULL !defined(__nullptr_KLIST_DEFINED_NOMOVE__)
#undef nullptr
#endif #endif
#endif #endif
+3 -3
View File
@@ -76,7 +76,7 @@ void scc_hashtable_init(scc_hashtable_t *ht,
* @param ht 哈希表实例指针 * @param ht 哈希表实例指针
* @param key 键指针 * @param key 键指针
* @param value 值指针 * @param value 值指针
* @return 被替换的旧值指针(无替换返回NULL) * @return 被替换的旧值指针(无替换返回nullptr)
*/ */
void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value); void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value);
@@ -84,7 +84,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value);
* @brief 查找键对应值 * @brief 查找键对应值
* @param ht 哈希表实例指针 * @param ht 哈希表实例指针
* @param key 查找键指针 * @param key 查找键指针
* @return 找到返回值指针,未找到返回NULL * @return 找到返回值指针,未找到返回nullptr
*/ */
void *scc_hashtable_get(scc_hashtable_t *ht, const void *key); void *scc_hashtable_get(scc_hashtable_t *ht, const void *key);
@@ -92,7 +92,7 @@ void *scc_hashtable_get(scc_hashtable_t *ht, const void *key);
* @brief 删除键值对 * @brief 删除键值对
* @param ht 哈希表实例指针 * @param ht 哈希表实例指针
* @param key 要删除的键指针 * @param key 要删除的键指针
* @return 被删除的值指针(不存在返回NULL) * @return 被删除的值指针(不存在返回nullptr)
* *
* @note 实际采用墓碑标记方式删除 * @note 实际采用墓碑标记方式删除
*/ */
+11 -11
View File
@@ -13,7 +13,7 @@ void scc_hashtable_init(scc_hashtable_t *ht,
ht->tombstone_count = 0; ht->tombstone_count = 0;
ht->cmp_func = cmp_func; ht->cmp_func = cmp_func;
ht->hash_func = hash_func; ht->hash_func = hash_func;
Assert(ht->cmp_func != null && ht->hash_func != null); Assert(ht->cmp_func != nullptr && ht->hash_func != nullptr);
} }
static int next_power_of_two(int n) { static int next_power_of_two(int n) {
@@ -29,12 +29,12 @@ static int next_power_of_two(int n) {
static scc_hashtable_entry_t *find_entry(scc_hashtable_t *ht, const void *key, static scc_hashtable_entry_t *find_entry(scc_hashtable_t *ht, const void *key,
u32 hash) { u32 hash) {
if (ht->entries.cap == 0) if (ht->entries.cap == 0)
return NULL; return nullptr;
u32 index = hash & (ht->entries.cap - 1); // 容量是2的幂 u32 index = hash & (ht->entries.cap - 1); // 容量是2的幂
u32 probe = 0; u32 probe = 0;
scc_hashtable_entry_t *tombstone = NULL; scc_hashtable_entry_t *tombstone = nullptr;
while (1) { while (1) {
scc_hashtable_entry_t *entry = &scc_vec_at(ht->entries, index); scc_hashtable_entry_t *entry = &scc_vec_at(ht->entries, index);
@@ -56,7 +56,7 @@ static scc_hashtable_entry_t *find_entry(scc_hashtable_t *ht, const void *key,
break; break;
} }
LOG_ERROR("hashset_find: hash table is full"); LOG_ERROR("hashset_find: hash table is full");
return NULL; return nullptr;
} }
static void adjust_capacity(scc_hashtable_t *ht, usize new_cap) { static void adjust_capacity(scc_hashtable_t *ht, usize new_cap) {
@@ -71,7 +71,7 @@ static void adjust_capacity(scc_hashtable_t *ht, usize new_cap) {
ht->entries.size = new_cap; ht->entries.size = new_cap;
ht->entries.cap = new_cap; ht->entries.cap = new_cap;
ht->entries.data = ht->entries.data =
scc_realloc(NULL, new_cap * sizeof(scc_hashtable_entry_t)); scc_realloc(nullptr, new_cap * sizeof(scc_hashtable_entry_t));
scc_memset(ht->entries.data, 0, new_cap * sizeof(scc_hashtable_entry_t)); scc_memset(ht->entries.data, 0, new_cap * sizeof(scc_hashtable_entry_t));
// rehash the all of the old data // rehash the all of the old data
@@ -99,7 +99,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value) {
u32 hash = ht->hash_func(key); u32 hash = ht->hash_func(key);
scc_hashtable_entry_t *entry = find_entry(ht, key, hash); scc_hashtable_entry_t *entry = find_entry(ht, key, hash);
void *old_value = NULL; void *old_value = nullptr;
if (entry->state == ENTRY_ACTIVE) { if (entry->state == ENTRY_ACTIVE) {
old_value = entry->value; old_value = entry->value;
} else { } else {
@@ -117,22 +117,22 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value) {
void *scc_hashtable_get(scc_hashtable_t *ht, const void *key) { void *scc_hashtable_get(scc_hashtable_t *ht, const void *key) {
if (ht->entries.cap == 0) if (ht->entries.cap == 0)
return NULL; return nullptr;
u32 hash = ht->hash_func(key); u32 hash = ht->hash_func(key);
scc_hashtable_entry_t *entry = find_entry(ht, key, hash); scc_hashtable_entry_t *entry = find_entry(ht, key, hash);
return (entry && entry->state == ENTRY_ACTIVE) ? entry->value : NULL; return (entry && entry->state == ENTRY_ACTIVE) ? entry->value : nullptr;
} }
void *scc_hashtable_del(scc_hashtable_t *ht, const void *key) { void *scc_hashtable_del(scc_hashtable_t *ht, const void *key) {
if (ht->entries.cap == 0) if (ht->entries.cap == 0)
return NULL; return nullptr;
u32 hash = ht->hash_func(key); u32 hash = ht->hash_func(key);
scc_hashtable_entry_t *entry = find_entry(ht, key, hash); scc_hashtable_entry_t *entry = find_entry(ht, key, hash);
if (entry == NULL || entry->state != ENTRY_ACTIVE) if (entry == nullptr || entry->state != ENTRY_ACTIVE)
return NULL; return nullptr;
void *value = entry->value; void *value = entry->value;
entry->state = ENTRY_TOMBSTONE; entry->state = ENTRY_TOMBSTONE;
+1 -1
View File
@@ -15,7 +15,7 @@ const char *scc_strpool_intern(scc_strpool_t *pool, const char *str) {
char *new_str = scc_malloc(len); char *new_str = scc_malloc(len);
if (!new_str) { if (!new_str) {
LOG_ERROR("strpool: Failed to allocate memory for string"); LOG_ERROR("strpool: Failed to allocate memory for string");
return NULL; return nullptr;
} }
scc_memcpy(new_str, str, len); scc_memcpy(new_str, str, len);
+13 -13
View File
@@ -69,7 +69,7 @@ int main(int argc, const char **argv, const char **envp) {
#endif #endif
scc_argparse_lang_t argparse_lang = SCC_DEFAULT_ARGPARSE_LANG; scc_argparse_lang_t argparse_lang = SCC_DEFAULT_ARGPARSE_LANG;
for (const char **env = envp; *env != null; env++) { for (const char **env = envp; *env != nullptr; env++) {
const char *env_str = *env; const char *env_str = *env;
if (scc_strcmp(env_str, "LANG=zh_CN.UTF-8") == 0) { if (scc_strcmp(env_str, "LANG=zh_CN.UTF-8") == 0) {
argparse_lang = SCC_ARGPARSE_LANG_ZH; argparse_lang = SCC_ARGPARSE_LANG_ZH;
@@ -77,9 +77,9 @@ int main(int argc, const char **argv, const char **envp) {
} }
scc_config_t config = { scc_config_t config = {
.input_file = null, .input_file = nullptr,
.verbose = 0, .verbose = 0,
.output_file = null, .output_file = nullptr,
.emit_ast = false, .emit_ast = false,
.emit_ir = false, .emit_ir = false,
.target_description = "x86_64-pc-windows-msvc", .target_description = "x86_64-pc-windows-msvc",
@@ -95,12 +95,12 @@ int main(int argc, const char **argv, const char **envp) {
} }
scc_argparse_drop(&argparse); scc_argparse_drop(&argparse);
scc_file_t fp = null; scc_file_t fp = nullptr;
if (config.output_file) { if (config.output_file) {
cbool is_stdout = scc_strcmp(config.output_file, "-") == 0; cbool is_stdout = scc_strcmp(config.output_file, "-") == 0;
if (!is_stdout) { if (!is_stdout) {
fp = scc_fopen(config.output_file, SCC_FILE_WRITE); fp = scc_fopen(config.output_file, SCC_FILE_WRITE);
if (fp == null) { if (fp == nullptr) {
LOG_FATAL("Failed to open file %s", config.output_file); LOG_FATAL("Failed to open file %s", config.output_file);
return 1; return 1;
} }
@@ -122,8 +122,8 @@ int main(int argc, const char **argv, const char **envp) {
scc_lexer_init(&lexer, scc_sstream_to_ring(&sstream)); scc_lexer_init(&lexer, scc_sstream_to_ring(&sstream));
if (config.emit_lex) { if (config.emit_lex) {
scc_lexer_tok_ring_t *tok_ring = scc_lexer_tok_ring_t *tok_ring =
scc_lexer_to_ring(&lexer, 8, fp == null ? false : true); scc_lexer_to_ring(&lexer, 8, fp == nullptr ? false : true);
if (fp == null) { if (fp == nullptr) {
print_ring(tok_ring, config.verbose); print_ring(tok_ring, config.verbose);
} else { } else {
print_file(tok_ring, fp); print_file(tok_ring, fp);
@@ -166,7 +166,7 @@ int main(int argc, const char **argv, const char **envp) {
if (config.emit_pp) { if (config.emit_pp) {
scc_lexer_tok_ring_t *tok_ring = scc_lexer_tok_ring_t *tok_ring =
scc_pproc_to_ring(&pproc, 8, true, true); scc_pproc_to_ring(&pproc, 8, true, true);
if (fp == null) { if (fp == nullptr) {
print_ring(tok_ring, config.verbose); print_ring(tok_ring, config.verbose);
} else { } else {
print_file(tok_ring, fp); print_file(tok_ring, fp);
@@ -198,14 +198,14 @@ sstream_drop:
if (config.emit_ast) { if (config.emit_ast) {
scc_tree_dump_t tree_dump; scc_tree_dump_t tree_dump;
if (fp == null) { if (fp == nullptr) {
scc_tree_dump_init(&tree_dump, true); scc_tree_dump_init(&tree_dump, true);
} else { } else {
scc_tree_dump_init(&tree_dump, false); scc_tree_dump_init(&tree_dump, false);
} }
scc_ast_dump_node(&tree_dump, (scc_ast_node_t *)translation_unit); scc_ast_dump_node(&tree_dump, (scc_ast_node_t *)translation_unit);
scc_tree_dump_flush(&tree_dump, tree_dump_output, scc_tree_dump_flush(&tree_dump, tree_dump_output,
fp == null ? scc_stdout : fp); fp == nullptr ? scc_stdout : fp);
scc_tree_dump_drop(&tree_dump); scc_tree_dump_drop(&tree_dump);
return 0; return 0;
} }
@@ -221,7 +221,7 @@ sstream_drop:
if (config.emit_ir) { if (config.emit_ir) {
scc_ir_dump_ctx_t ir_dump_ctx; scc_ir_dump_ctx_t ir_dump_ctx;
scc_tree_dump_t tree_dump; scc_tree_dump_t tree_dump;
if (fp == null) { if (fp == nullptr) {
scc_tree_dump_init(&tree_dump, true); scc_tree_dump_init(&tree_dump, true);
} else { } else {
scc_tree_dump_init(&tree_dump, false); scc_tree_dump_init(&tree_dump, false);
@@ -231,7 +231,7 @@ sstream_drop:
scc_ir_dump_cprog_linear(&ir_dump_ctx); scc_ir_dump_cprog_linear(&ir_dump_ctx);
scc_tree_dump_flush(&tree_dump, tree_dump_output, scc_tree_dump_flush(&tree_dump, tree_dump_output,
fp == null ? scc_stdout : fp); fp == nullptr ? scc_stdout : fp);
scc_tree_dump_drop(&tree_dump); scc_tree_dump_drop(&tree_dump);
return 0; return 0;
} }
@@ -247,7 +247,7 @@ sstream_drop:
scc_pe_builder_t pe_builder; scc_pe_builder_t pe_builder;
sccf2pe(&pe_builder, sccf); sccf2pe(&pe_builder, sccf);
if (fp == null) { if (fp == nullptr) {
scc_printf("output exe at %s\n", config.output_file); scc_printf("output exe at %s\n", config.output_file);
} else { } else {
scc_pe_dump_to_file(&pe_builder, config.output_file); scc_pe_dump_to_file(&pe_builder, config.output_file);