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

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

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) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_STRING;
spec->raw_value = null;
spec->store.ptr_store = null;
spec->raw_value = nullptr;
spec->store.ptr_store = nullptr;
spec->choices.count = 0;
spec->choices.values = null;
spec->choices.values = nullptr;
spec->flag_required = false;
spec->flag_store_as_count = false;

View File

@@ -5,7 +5,7 @@ void scc_argparse_init(scc_argparse_t *parser, const char *program_name,
parser->prog_name = program_name;
parser->version = "0.1.0";
parser->description = description;
parser->epilog = null;
parser->epilog = nullptr;
parser->lang = SCC_ARGPARSE_LANG_EN;
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,
const char *name) {
if (!scc_vec_size(cmd->subcmds)) {
return null;
return nullptr;
}
scc_vec_foreach(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 null;
return nullptr;
}
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);
}
static void push_help(scc_argparse_cmd_t *cmd) {
if (cmd == null) {
if (cmd == nullptr) {
return;
}
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_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;
scc_argparse_print_error(ctx, errcode);
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 value == null or value != null
// // opt value == nullptr or value != nullptr
// scc_argparse_opt_t *org_opt =
// (scc_argparse_opt_t *)opt_res.opt->user_data;
// if (parser->need_help) {
@@ -218,7 +219,7 @@ static int handle_positional_arg(scc_argparse_context_t *ctx,
(void)parser; // TODO
scc_argparse_cmd_t *subcmd =
is_subcommand(ctx->current_cmd, ctx->result.value);
if (subcmd != NULL) {
if (subcmd != nullptr) {
ctx->current_cmd = subcmd;
parse_cmd(&ctx->optparse, &ctx->opts, ctx->current_cmd);
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,
// opt_res.value);
// if (cmd != null) {
// if (cmd != nullptr) {
// current_cmd = cmd;
// parse_cmd(&optparse, &opts, current_cmd);
// } else {
@@ -275,9 +276,9 @@ int scc_argparse_parse(scc_argparse_t *parser, int argc, const char **argv) {
break;
}
if (ctx.result.opt != null) {
if (ctx.result.opt != nullptr) {
errcode = handle_option(&ctx, parser);
} else if (ctx.result.value != null) {
} else if (ctx.result.value != nullptr) {
errcode = handle_positional_arg(&ctx, parser);
} else {
UNREACHABLE(); // 不应到达此处

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 *arg) {
if (arg == null || cmd == null) {
return null;
if (arg == nullptr || cmd == nullptr) {
return nullptr;
}
if (arg[0] == '-' && arg[1] == '-' && arg[2] != '\0') {
// opt arg

View File

@@ -45,21 +45,21 @@ void test_simple_short_options(void) {
// 解析第一个选项 -h
TEST_CHECK(scc_optparse_parse(&parser, &res) != 0);
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.value == NULL);
TEST_CHECK(res.value == nullptr);
// 解析第二个选项 -v
TEST_CHECK(scc_optparse_parse(&parser, &res) != 0);
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.value == NULL);
TEST_CHECK(res.value == nullptr);
// 没有更多选项
TEST_CHECK(scc_optparse_parse(&parser, &res) == 0);
TEST_CHECK(res.opt == NULL);
TEST_CHECK(res.value == NULL);
TEST_CHECK(res.opt == nullptr);
TEST_CHECK(res.value == nullptr);
}
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(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(scc_optparse_parse(&parser, &res) != 0);
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(scc_optparse_parse(&parser, &res) == 0);
TEST_CHECK(res.opt == NULL);
TEST_CHECK(res.value == NULL);
TEST_CHECK(res.opt == nullptr);
TEST_CHECK(res.value == nullptr);
}
// 测试3: 带参数的短选项
@@ -95,14 +95,14 @@ void test_short_options_with_args(void) {
// 解析 -f file.txt
scc_optparse_parse(&parser, &res);
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(strcmp(res.value, "file.txt") == 0);
// 解析 -o output.txt
scc_optparse_parse(&parser, &res);
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(strcmp(res.value, "output.txt") == 0);
}
@@ -119,20 +119,20 @@ void test_long_options(void) {
// 解析 --help
scc_optparse_parse(&parser, &res);
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);
// 解析 --file=test.txt
scc_optparse_parse(&parser, &res);
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(strcmp(res.value, "test.txt") == 0);
// 解析 --output out.txt
scc_optparse_parse(&parser, &res);
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(strcmp(res.value, "out.txt") == 0);
}
@@ -160,13 +160,13 @@ void test_mixed_options_positional(void) {
// 解析第一个位置参数
scc_optparse_parse(&parser, &res);
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);
// 解析第二个位置参数
scc_optparse_parse(&parser, &res);
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);
}
@@ -250,13 +250,13 @@ void test_option_terminator(void) {
// 解析 -f (作为位置参数)
scc_optparse_parse(&parser, &res);
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);
// 解析 file.txt (作为位置参数)
scc_optparse_parse(&parser, &res);
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);
}
@@ -270,8 +270,8 @@ void test_edge_cases(void) {
INIT_OPTPARSE(argv1);
scc_optparse_parse(&parser, &res);
TEST_CHECK(res.opt == NULL);
TEST_CHECK(res.value == NULL);
TEST_CHECK(res.opt == nullptr);
TEST_CHECK(res.value == nullptr);
// 测试空字符串参数
const char *argv2[] = {"program", "-f", "", "-o", " "};
@@ -302,23 +302,23 @@ void test_multi_argument_option(void) {
scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt && res.opt->short_name == 'l');
TEST_CHECK(res.value == NULL);
TEST_CHECK(res.value == nullptr);
// 由于 -l 可以接受多个参数,后续的参数应该作为 -l 的值
// 但根据当前实现,可能需要多次调用
scc_optparse_parse(&parser, &res);
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);
scc_optparse_parse(&parser, &res);
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);
scc_optparse_parse(&parser, &res);
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);
}
@@ -344,7 +344,7 @@ void test_long_option_with_equal_no_value(void) {
scc_optparse_parse(&parser, &res);
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);
}
@@ -382,14 +382,14 @@ void test_combined_short_with_arg(void) {
// 解析 -v
scc_optparse_parse(&parser, &res);
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.value == NULL);
TEST_CHECK(res.value == nullptr);
// 解析 -finput.txt
scc_optparse_parse(&parser, &res);
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(strcmp(res.value, "input.txt") == 0);
}
@@ -405,14 +405,14 @@ void test_too_many_arguments(void) {
// 解析 -f file1
scc_optparse_parse(&parser, &res);
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(strcmp(res.value, "file1") == 0);
// 尝试给 -f 第二个参数,应该返回错误
scc_optparse_parse(&parser, &res);
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);
}
@@ -438,7 +438,7 @@ void test_mixed_short_and_positional(void) {
// 解析位置参数
scc_optparse_parse(&parser, &res);
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);
}
@@ -471,7 +471,7 @@ void test_complex_multi_argument(void) {
// 第4个参数应该是位置参数
scc_optparse_parse(&parser, &res);
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);
}
@@ -487,7 +487,7 @@ void test_long_option_multi_args(void) {
scc_optparse_parse(&parser, &res);
TEST_CHECK(res.error == SCC_OPT_ERROR_NONE);
TEST_CHECK(res.opt && strcmp(res.opt->long_name, "list") == 0);
TEST_CHECK(res.value == NULL);
TEST_CHECK(res.value == nullptr);
// 解析 item1
scc_optparse_parse(&parser, &res);
@@ -518,7 +518,7 @@ void test_empty_long_name(void) {
scc_optparse_parse(&parser, &res);
TEST_CHECK(parser.handle_positional == 1);
TEST_CHECK(res.opt == NULL);
TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "--") == 0);
}
@@ -538,7 +538,7 @@ void test_non_dash_prefix(void) {
scc_optparse_parse(&parser, &res);
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->prefix == '/');
}
@@ -550,7 +550,7 @@ void test_default_value(void) {
// scc_optparse_result_t res;
// 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(),
// };
@@ -602,7 +602,7 @@ void test_callback_function(void) {
// // 调用回调函数
// if (res.opt->invoke) {
// res.opt->invoke(NULL);
// res.opt->invoke(nullptr);
// TEST_CHECK(callback_called == 1);
// }
}
@@ -644,7 +644,7 @@ void test_single_dash(void) {
// 解析单个横杠(通常表示标准输入)
scc_optparse_parse(&parser, &res);
TEST_CHECK(res.opt == NULL);
TEST_CHECK(res.opt == nullptr);
TEST_CHECK(strcmp(res.value, "-") == 0);
// 解析 --
@@ -724,5 +724,5 @@ TEST_LIST = {
{"test_complex_short_combination", test_complex_short_combination},
{"test_single_dash", test_single_dash},
{"test_parser_state_reset", test_parser_state_reset},
{NULL, NULL},
{nullptr, nullptr},
};

View File

@@ -176,7 +176,7 @@ struct scc_ast_type {
} pointer;
struct {
scc_ast_type_t *element;
scc_ast_expr_t *size; // 可为 null <=> 不定长数组
scc_ast_expr_t *size; // 可为 nullptr <=> 不定长数组
} array;
struct {
scc_ast_type_t *return_type;
@@ -184,7 +184,7 @@ struct scc_ast_type {
} function;
struct {
const char *name;
scc_ast_decl_t *decl; // can be null
scc_ast_decl_t *decl; // can be nullptr
} record;
struct {
const char *name;
@@ -354,7 +354,7 @@ struct scc_ast_stmt {
struct {
scc_ast_expr_t *cond;
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;
// while do-while 语句
struct {
@@ -363,9 +363,9 @@ struct scc_ast_stmt {
} while_stmt;
// for 语句
struct {
scc_ast_node_t *init; // expr or decl or null
scc_ast_expr_t *cond; // 可为 null
scc_ast_expr_t *incr; // 可为 null
scc_ast_node_t *init; // expr or decl or nullptr
scc_ast_expr_t *cond; // 可为 nullptr
scc_ast_expr_t *incr; // 可为 nullptr
scc_ast_stmt_t *body;
} for_stmt;
// switch 语句
@@ -388,7 +388,7 @@ struct scc_ast_stmt {
} jump;
// return 语句
struct {
scc_ast_expr_t *expr; // 可为 null
scc_ast_expr_t *expr; // 可为 nullptr
} return_stmt;
// goto 语句
struct {
@@ -416,12 +416,12 @@ struct scc_ast_decl {
// 变量声明
struct {
scc_ast_type_t *type;
scc_ast_expr_t *init; // 可为 NULL
scc_ast_expr_t *init; // 可为 nullptr
} var;
// 函数声明
struct {
scc_ast_type_t *type; // 函数类型
scc_ast_stmt_t *body; // 可为 null 表示只有声明
scc_ast_stmt_t *body; // 可为 nullptr 表示只有声明
} func;
// 参数声明
struct {

View File

@@ -4,14 +4,14 @@
#include "ast_def.h"
#include "ast_dump.h"
// decls can be null but maybe warning
// decls can be nullptr but maybe warning
static inline void
scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit,
scc_ast_decl_vec_t *decls, scc_pos_t loc) {
Assert(translation_unit != null);
Assert(translation_unit != nullptr);
translation_unit->base.type = SCC_AST_TRANSLATION_UNIT;
translation_unit->base.loc = loc;
if (decls == null) {
if (decls == nullptr) {
scc_vec_init(translation_unit->declarations);
} else {
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,
scc_ast_decl_vec_t *list_move,
scc_pos_t loc) {
Assert(decl != null && list_move != null);
Assert(decl != nullptr && list_move != nullptr);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_LIST;
decl->name = null;
decl->name = nullptr;
decl->list.vars = *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,
scc_ast_type_t *type,
const char *name,
scc_ast_expr_t *var_init,
scc_pos_t loc) {
Assert(decl != null && type != null);
Assert(decl != nullptr && type != nullptr);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_VAR;
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;
}
// var_init can be null
// var_init can be nullptr
static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl,
scc_ast_type_t *type, const char *name,
scc_ast_expr_t *var_init,
scc_pos_t loc) {
Assert(decl != null && name != null && type != null);
Assert(decl != nullptr && name != nullptr && type != nullptr);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_VAR;
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;
}
// body can be null
// body can be nullptr
static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl,
scc_ast_type_t *type,
const char *name,
scc_ast_stmt_t *body, scc_pos_t loc) {
Assert(decl != null && name != null && type != null);
Assert(decl != nullptr && name != nullptr && type != nullptr);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_FUNC;
decl->name = name;
@@ -71,11 +71,11 @@ static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl,
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,
scc_ast_type_t *type,
const char *name, scc_pos_t loc) {
Assert(decl != null && type != null);
Assert(decl != nullptr && type != nullptr);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_PARAM;
decl->name = name;
@@ -87,11 +87,11 @@ static inline void _scc_ast_decl_record_init(scc_ast_decl_t *decl,
const char *name,
scc_ast_decl_vec_t *fields_move,
scc_pos_t loc) {
Assert(decl != null);
Assert(decl != nullptr);
decl->base.loc = loc;
decl->base.type = type;
decl->name = name;
if (fields_move == null) {
if (fields_move == nullptr) {
scc_vec_init(decl->record.fields);
} else {
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,
const char *name,
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);
}
// 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,
const char *name,
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);
}
// 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,
const char *name,
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,
scc_ast_type_t *type,
scc_pos_t loc) {
Assert(decl != null && name != null && type != null);
Assert(decl != nullptr && name != nullptr && type != nullptr);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_TYPEDEF;
decl->name = name;
decl->typedef_decl.type = type;
}
// items can be null
// items can be nullptr
static inline void scc_ast_stmt_compound_init(
scc_ast_stmt_t *stmt, scc_ast_block_item_vec_t *items_move, scc_pos_t loc) {
Assert(stmt != null);
Assert(stmt != nullptr);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_COMPOUND;
if (items_move == null) {
if (items_move == nullptr) {
scc_vec_init(stmt->compound.block_items);
} else {
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,
scc_ast_expr_t *expr, scc_pos_t loc) {
Assert(stmt != null);
Assert(stmt != nullptr);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_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,
scc_ast_expr_t *cond,
scc_ast_stmt_t *then,
scc_ast_stmt_t *opt_else,
scc_pos_t loc) {
Assert(stmt != null && cond != null && then != null);
Assert(stmt != nullptr && cond != nullptr && then != nullptr);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_IF;
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_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.type = SCC_AST_STMT_WHILE;
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_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.type = SCC_AST_STMT_DO_WHILE;
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 *incr,
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.type = SCC_AST_STMT_FOR;
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_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.type = SCC_AST_STMT_SWITCH;
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,
scc_ast_expr_t *cond,
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.type = SCC_AST_STMT_CASE;
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,
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.type = SCC_AST_STMT_DEFAULT;
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,
scc_pos_t loc) {
Assert(stmt != null);
Assert(stmt != nullptr);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null);
Assert(stmt != nullptr);
stmt->base.loc = loc;
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,
scc_ast_expr_t *expr,
scc_pos_t loc) {
Assert(stmt != null);
Assert(stmt != nullptr);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_RETURN;
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,
const char *label, scc_pos_t loc) {
Assert(stmt != null && label != null);
Assert(stmt != nullptr && label != nullptr);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_GOTO;
stmt->goto_stmt.label = label;
stmt->goto_stmt._target = null;
stmt->goto_stmt._target = nullptr;
}
static inline void scc_ast_stmt_label_init(scc_ast_stmt_t *stmt,
const char *label,
scc_ast_stmt_t *body,
scc_pos_t loc) {
Assert(stmt != null);
Assert(stmt != nullptr);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_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 *rhs,
scc_pos_t loc) {
Assert(expr != null && lhs != null && rhs != null);
Assert(expr != nullptr && lhs != nullptr && rhs != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_BINARY;
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_t *operand,
scc_pos_t loc) {
Assert(expr != null && operand != null);
Assert(expr != nullptr && operand != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_UNARY;
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 *else_expr,
scc_pos_t loc) {
Assert(expr != null && cond != null && then_expr != null &&
else_expr != null);
Assert(expr != nullptr && cond != nullptr && then_expr != nullptr &&
else_expr != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_COND;
expr->cond.cond = cond;
@@ -323,16 +323,16 @@ static inline void scc_ast_expr_cond_init(scc_ast_expr_t *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,
scc_ast_expr_t *callee,
scc_ast_expr_vec_t *args,
scc_pos_t loc) {
Assert(expr != null && callee != null);
Assert(expr != nullptr && callee != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_CALL;
expr->call.callee = callee;
if (args == null) {
if (args == nullptr) {
scc_vec_init(expr->call.args);
} else {
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 *index,
scc_pos_t loc) {
Assert(expr != null && array != null && index != null);
Assert(expr != nullptr && array != nullptr && index != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_ARRAY_SUBSCRIPT;
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,
const char *member,
scc_pos_t loc) {
Assert(expr != null && object != null && member != null);
Assert(expr != nullptr && object != nullptr && member != nullptr);
expr->base.loc = loc;
expr->base.type = type;
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_expr_t *operand,
scc_pos_t loc) {
Assert(expr != null && type != null && operand != null);
Assert(expr != nullptr && type != nullptr && operand != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_CAST;
expr->cast.type = type;
expr->cast.expr = operand;
}
// type and target_expr can be 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,
scc_ast_type_t *type,
scc_ast_expr_t *target_expr,
scc_pos_t loc) {
Assert(expr != null);
Assert(expr != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_SIZE_OF;
expr->attr_of.type = type;
expr->attr_of.expr = target_expr;
}
// type and target_expr can be 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,
scc_ast_type_t *type,
scc_ast_expr_t *target_expr,
scc_pos_t loc) {
Assert(expr != null);
Assert(expr != nullptr);
expr->base.loc = loc;
expr->base.type =
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;
}
// 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,
scc_ast_expr_t *base,
scc_ast_expr_vec_t *lhs_exprs,
scc_ast_expr_vec_t *rhs_exprs,
scc_pos_t loc) {
Assert(expr != null && base != null);
Assert(expr != nullptr && base != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_COMPOUND;
expr->compound.base = base;
if (lhs_exprs == null) {
if (lhs_exprs == nullptr) {
scc_vec_init(expr->compound.lhs_exprs);
} else {
expr->compound.lhs_exprs = *lhs_exprs;
scc_vec_init(*lhs_exprs);
}
if (rhs_exprs == null) {
if (rhs_exprs == nullptr) {
scc_vec_init(expr->compound.rhs_exprs);
} else {
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,
const char *value, cbool owned,
scc_pos_t loc) {
Assert(expr != null && value != null);
Assert(expr != nullptr && value != nullptr);
expr->base.loc = loc;
expr->base.type = type;
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,
const char *name,
scc_pos_t loc) {
Assert(expr != null && name != null);
Assert(expr != nullptr && name != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_IDENTIFIER;
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,
scc_ast_type_t *type,
scc_pos_t loc) {
Assert(expr != null && type != null);
Assert(expr != nullptr && type != nullptr);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_LVALUE;
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,
scc_ast_builtin_type_t builtin,
scc_pos_t loc) {
Assert(type != null);
Assert(type != nullptr);
type->base.loc = loc;
type->base.type = SCC_AST_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,
scc_ast_type_t *pointee,
scc_pos_t loc) {
Assert(type != null && pointee != null);
Assert(type != nullptr && pointee != nullptr);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_POINTER;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->pointer.pointee = pointee;
}
// size can be null
// size can be nullptr
static inline void scc_ast_type_array_init(scc_ast_type_t *type,
scc_ast_type_t *element,
scc_ast_expr_t *size,
scc_pos_t loc) {
Assert(type != null && element != null);
Assert(type != nullptr && element != nullptr);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_ARRAY;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
@@ -531,17 +531,17 @@ static inline void scc_ast_type_array_init(scc_ast_type_t *type,
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,
scc_ast_type_t *return_type,
scc_ast_decl_vec_t *params,
scc_pos_t loc) {
Assert(type != null);
Assert(type != nullptr);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_FUNCTION;
type->function.return_type = return_type;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
if (params == null) {
if (params == nullptr) {
scc_vec_init(type->function.params);
} else {
type->function.params = *params;
@@ -554,7 +554,7 @@ static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_t *decl,
scc_pos_t loc) {
Assert(type != null);
Assert(type != nullptr);
type->base.loc = loc;
type->base.type = type_kind;
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;
}
// 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,
const char *name,
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);
}
// 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,
const char *name,
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);
}
// 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,
const char *name,
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,
scc_ast_decl_t *target,
scc_pos_t loc) {
Assert(type != null && target != null);
Assert(type != nullptr && target != nullptr);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_TYPEDEF;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME

View File

@@ -269,7 +269,7 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_t *td) {
break;
case SCC_AST_TYPE_ARRAY:
dump_child_node(td, (scc_ast_node_t *)type->array.element,
type->array.size == NULL);
type->array.size == nullptr);
if (type->array.size)
dump_child_node(td, (scc_ast_node_t *)type->array.size, true);
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:
if (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)
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:
if (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)
dump_child_node(td, (scc_ast_node_t *)decl->func.body, true);
}

View File

@@ -130,7 +130,7 @@ static const scc_type_abi_t scc_win_x64_type_abi[] = {
.alignment = 8,
},
{
// NULL
// nullptr
.ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN,
.ir_type = SCC_IR_TYPE_unknown,
.size = 0,

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_ast_type_t *ast_type) {
if (ctx == null || ast_type == null) {
LOG_ERROR("args is null");
if (ctx == nullptr || ast_type == nullptr) {
LOG_ERROR("args is nullptr");
return 0;
}
scc_ir_type_t ir_type;
@@ -42,17 +42,13 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
}
break;
}
case SCC_AST_TYPE_POINTER: {
scc_ir_type_init(&ir_type, SCC_IR_TYPE_PTR);
scc_ir_type_ref_t pointee_type =
scc_ast2ir_type(ctx, ast_type->pointer.pointee);
ir_type.data.pointer.base = pointee_type;
break;
}
case SCC_AST_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);
ir_type.data.array.base = element_type;
// TODO: 处理数组大小表达式
ir_type.data.array.len = 0;
if (ast_type->array.size) {
// TODO constant expression
@@ -73,7 +68,6 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
}
break;
}
case SCC_AST_TYPE_FUNCTION: {
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;
break;
}
// SCC_AST_TYPE_STRUCT, // 结构体类型
// SCC_AST_TYPE_UNION, // 联合类型
// SCC_AST_TYPE_ENUM, // 枚举类型
case SCC_AST_TYPE_TYPEDEF:
break;
default:
LOG_FATAL("Unsupported AST type: %d", ast_type->base.type);
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,
cbool is_lvalue) {
if (ctx == null || expr == null) {
LOG_ERROR("args is null");
if (ctx == nullptr || expr == nullptr) {
LOG_ERROR("args is nullptr");
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);
}
case SCC_AST_EXPR_UNARY: {
if (expr->unary.op == SCC_AST_OP_ADDRESS_OF) {
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);
return 0;
}
UNREACHABLE();
break;
}
case SCC_AST_EXPR_COND: {
TODO();
break;
}
case SCC_AST_EXPR_CALL: {
// 转换参数
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);
return node;
}
// SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标
// SCC_AST_EXPR_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_LVALUE, // 右值
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
case SCC_AST_EXPR_INT_LITERAL: {
// FIXME maybe using some array to int;
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();
break;
}
case SCC_AST_EXPR_IDENTIFIER: {
if (expr->identifier._target == null) {
if (expr->identifier._target == nullptr) {
LOG_ERROR("unknown identifier %s", expr->identifier.name);
}
// 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) {
return in;
} 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
*/
void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
if (stmt == null) {
if (stmt == nullptr) {
return;
}
@@ -537,12 +538,10 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
}
break;
}
case SCC_AST_STMT_EXPR: {
scc_ast2ir_expr(ctx, stmt->expr.expr, false);
break;
}
case SCC_AST_STMT_IF: {
/*
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);
break;
}
case SCC_AST_STMT_WHILE: {
scc_ir_bblock_ref_t cond_block =
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);
break;
}
case SCC_AST_STMT_DO_WHILE: {
scc_ir_bblock_ref_t cond_block =
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);
break;
}
case SCC_AST_STMT_FOR: {
scc_ir_bblock_ref_t cond_block =
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);
break;
}
// SCC_AST_STMT_SWITCH, // switch 语句
// SCC_AST_STMT_CASE, // case 语句
// 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
*/
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");
return;
}
@@ -709,11 +704,10 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
switch (decl->base.type) {
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_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,
(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_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);
break;
}
case SCC_AST_DECL_FUNC: {
scc_ir_type_ref_t func_type_ref = scc_ast2ir_type(ctx, decl->func.type);
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);
}
if (decl->func.body == null) {
if (decl->func.body == nullptr) {
// function decl
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_module_get_func(ctx->builder.ctx.module, func_ref);
Assert(func != null);
Assert(func != nullptr);
scc_ir_builder_begin_bblock(&ctx->builder, "entry");
scc_vec_foreach(decl->func.type->function.params, i) {
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_t *param_node = scc_ir_module_get_value(
ctx->builder.ctx.module, param_node_ref);
Assert(param_node != null);
Assert(param_node != nullptr);
param_node->name = param->name;
scc_hashtable_set(&ctx->decl2ir_ref, param,
(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);
break;
}
case SCC_AST_DECL_LIST: {
scc_vec_foreach(decl->list.vars, i) {
scc_ast_decl_t *sub_decl = scc_vec_at(decl->list.vars, i);
@@ -784,11 +797,9 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
break;
case SCC_AST_DECL_UNION:
break;
case SCC_AST_DECL_ENUM:
case SCC_AST_DECL_TYPEDEF:
break;
default:
LOG_FATAL("Unsupported declaration type: %d", decl->base.type);
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,
scc_ast_translation_unit_t *tu) {
Assert(ctx != null && tu != null);
Assert(ctx != nullptr && tu != nullptr);
scc_vec_foreach(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,
scc_ir_cprog_t *cprog) {
Assert(ctx != null);
Assert(ctx != nullptr);
ctx->abi = abi;
scc_ir_builder_init(&ctx->builder, cprog);
scc_hashtable_init(&ctx->decl2ir_ref, scc_hash_node, scc_cmp_node);

View File

@@ -68,15 +68,32 @@ SCC_IR_BUILDER_TYPE_FUNC(f32)
SCC_IR_BUILDER_TYPE_FUNC(f64)
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
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_const_int_t value) {
scc_ir_value_t node;
scc_ir_node_init(&node, null, SCC_IR_VALUE_TAG_CONST_INT);
node.data.const_int = value;
node.type = type;
return scc_ir_module_add_value(&builder->cprog->module, &node);
scc_ir_const_int_t val) {
scc_ir_value_t value;
scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_CONST_INT);
value.data.const_int = val;
value.type = type;
return scc_ir_module_add_value(&builder->cprog->module, &value);
}
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 = {
.tag = SCC_IR_TYPE_ARRAY,
.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_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. 创建聚合节点
scc_ir_value_t const_array_value = {
.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';
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_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. 创建全局变量节点,类型为指针,初始值指向常量数组
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){
.name = name,
.tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC,
.type = ptr_type_ref,
.type = array_type_ref,
.data.global_alloc.value = const_array_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){
.tag = SCC_IR_VALUE_TAG_GET_PTR,
.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);
return pointer_to_global_value;
@@ -144,7 +155,7 @@ scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str,
/**
* @brief 开始构建函数
* @param func_ref 函数引用
* @param param_names 参数名列表(可为NULL
* @param param_names 参数名列表(可为nullptr
* @return void
*/
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 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。
* @param builder IR构建器
* @param label 基本块标签(可为 NULL,自动生成)
* @param label 基本块标签(可为 nullptr,自动生成)
* @return 新基本块的引用
*/
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 开始构建新的基本块
* @param label 基本块标签(可为NULL,自动生成)
* @param label 基本块标签(可为nullptr,自动生成)
* @return 基本块引用
*/
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指令在当前基本块中
* @param type 分配的类型
* @param name 变量名(可为NULL
* @param name 变量名(可为nullptr
*/
scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
scc_ir_type_ref_t type,

View File

@@ -3,7 +3,7 @@
#include <scc_core.h>
#define SCC_IR_REF_NULL 0
#define SCC_IR_REF_nullptr 0
typedef unsigned int ir_handle_t;
typedef const char *scc_ir_label_t;
@@ -86,7 +86,8 @@ struct scc_ir_func {
};
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_UINT,
SCC_IR_VALUE_TAG_CONST_FLOAT,
@@ -175,12 +176,60 @@ typedef union {
u8 float_any[16];
} 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 {
scc_ir_type_ref_t type;
scc_ir_label_t name;
scc_ir_node_ref_vec_t used_by;
scc_ir_value_tag_t tag;
union {
scc_ir_builtin_t builtin;
scc_ir_const_int_t const_int;
scc_ir_const_uint_t const_uint;
scc_ir_const_float_t const_float;

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 *
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);
Assert(value != null);
Assert(value != nullptr);
return scc_ir_module_get_type(ctx, value->type);
}

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_func_init(scc_ir_func_t *in, const char *name);
// node name can be null ptr
void scc_ir_node_init(scc_ir_value_t *in, const char *name,
scc_ir_value_tag_t tag);
// node name can be nullptr ptr
void scc_ir_value_init(scc_ir_value_t *in, const char *name,
scc_ir_value_tag_t tag);
#endif /* __SCC_IR_H__ */

View File

@@ -4,8 +4,8 @@
#define GET_MODULE(builder) (&(builder->cprog->module))
void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog) {
builder->current_bblock = SCC_IR_REF_NULL;
builder->current_func = SCC_IR_REF_NULL;
builder->current_bblock = SCC_IR_REF_nullptr;
builder->current_func = SCC_IR_REF_nullptr;
builder->cprog = cprog;
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_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");
return;
}
if (func_ptr == null) {
if (func_ptr == nullptr) {
LOG_ERROR("Invalid function reference");
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;
func_type = null;
func_type = nullptr;
scc_vec_foreach(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),
&(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR,
.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;
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) {
scc_ir_func_t *func_ptr =
scc_ir_module_get_func(GET_MODULE(builder), builder->current_func);
if (func_ptr == null) {
if (func_ptr == nullptr) {
LOG_FATAL("Invalid function reference");
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});
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_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_type_ref_t type,
const char *name,
usize arg_idx) {
scc_ir_value_t node = {0};
node.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF;
node.type = type;
node.name = name;
node.data.arg_ref.idx = arg_idx;
scc_ir_value_t value = {0};
value.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF;
value.type = type;
value.name = name;
value.data.arg_ref.idx = arg_idx;
scc_ir_value_ref_t node_ref =
scc_ir_module_add_value(GET_MODULE(builder), &node);
scc_ir_value_ref_t value_ref =
scc_ir_module_add_value(GET_MODULE(builder), &value);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}
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_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 target,
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};
store_node.tag = SCC_IR_VALUE_TAG_STORE;
store_node.data.store.target = target;
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_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,
@@ -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;
}
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_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,
@@ -268,13 +268,13 @@ scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder,
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_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,
@@ -291,13 +291,13 @@ scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder,
cmp_node.type =
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_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,
@@ -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.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_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,
@@ -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.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_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,
@@ -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_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,
@@ -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.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_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) {
@@ -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.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_builder_add_instr(builder, node_ref);
return node_ref;
scc_ir_builder_add_instr(builder, value_ref);
return value_ref;
}

View File

@@ -88,21 +88,17 @@ static int cmp_type(const void *_key1, const void *_key2) {
return 0; // 基本类型tag相同即可
case SCC_IR_TYPE_PTR:
return key1->data.pointer.base != key2->data.pointer.base;
case SCC_IR_TYPE_ARRAY:
return (key1->data.array.base != key2->data.array.base) ||
(key1->data.array.len != key2->data.array.len);
case SCC_IR_TYPE_FUNC: {
if (key1->data.function.ret_type != key2->data.function.ret_type) {
return 1;
}
if (key1->data.function.params.size !=
key2->data.function.params.size) {
return 1;
}
for (usize i = 0; i < key1->data.function.params.size; i++) {
if (key1->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,
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);
if (found) {

View File

@@ -6,7 +6,8 @@
static const char *get_node_type_str(scc_ir_value_tag_t tag) {
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_UINT] = "ConstUint",
[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,
const scc_ir_value_t *node) {
const scc_ir_value_t *value) {
scc_tree_dump_push(ctx->dump_ctx, true);
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);
}
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_begin_line(ctx->dump_ctx);
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);
if (node->data.op.lhs)
dump_child_node_ref(ctx, node->data.op.lhs,
node->data.op.rhs ? false : true);
if (node->data.op.rhs)
dump_child_node_ref(ctx, node->data.op.rhs, true);
if (value->data.op.lhs)
dump_child_node_ref(ctx, value->data.op.lhs,
value->data.op.rhs ? false : true);
if (value->data.op.rhs)
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) {
if (node->data.load.target)
dump_child_node_ref(ctx, node->data.load.target, true);
static void dump_load_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *value) {
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,
const scc_ir_value_t *node) {
if (node->data.store.target)
dump_child_node_ref(ctx, node->data.store.target, false);
if (node->data.store.value)
dump_child_node_ref(ctx, node->data.store.value, true);
const scc_ir_value_t *value) {
if (value->data.store.target)
dump_child_node_ref(ctx, value->data.store.target, false);
if (value->data.store.value)
dump_child_node_ref(ctx, value->data.store.value, true);
}
static void dump_get_ptr_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *node) {
if (node->data.get_ptr.src_addr)
dump_child_node_ref(ctx, node->data.get_ptr.src_addr, false);
if (node->data.get_ptr.index)
dump_child_node_ref(ctx, node->data.get_ptr.index, true);
const scc_ir_value_t *value) {
if (value->data.get_ptr.src_addr)
dump_child_node_ref(ctx, value->data.get_ptr.src_addr, false);
if (value->data.get_ptr.index)
dump_child_node_ref(ctx, value->data.get_ptr.index, true);
}
static void dump_branch_node(scc_ir_dump_ctx_t *ctx,
const scc_ir_value_t *node) {
if (node->data.branch.cond)
dump_child_node_ref(ctx, node->data.branch.cond, false);
const scc_ir_value_t *value) {
if (value->data.branch.cond)
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(
GET_MODULE(ctx), node->data.branch.true_bblock);
GET_MODULE(ctx), value->data.branch.true_bblock);
if (true_bblock) {
scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "TrueBlock: ");
@@ -139,9 +141,9 @@ static void dump_branch_node(scc_ir_dump_ctx_t *ctx,
: "<unnamed>");
}
}
if (node->data.branch.false_bblock) {
if (value->data.branch.false_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) {
scc_tree_dump_begin_line(ctx->dump_ctx);
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);
if (node->data.jump.target_bblock) {
if (value->data.jump.target_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)
scc_tree_dump_value(ctx->dump_ctx, "to '%s'",
target->label ? target->label : "<unnamed>");
else
scc_tree_dump_value(ctx->dump_ctx, "to invalid block");
} 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);
if (node->data.call.callee) {
if (value->data.call.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'",
callee ? (callee->name ? callee->name : "<unnamed>")
: "<invalid>");
} 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++) {
cbool is_last = (i + 1 == scc_vec_size(node->data.call.args));
for (usize i = 0; i < scc_vec_size(value->data.call.args); i++) {
cbool is_last = (i + 1 == scc_vec_size(value->data.call.args));
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);
scc_tree_dump_pop(ctx->dump_ctx);
}
}
static void dump_ret_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *node) {
if (node->data.ret.ret_val)
dump_child_node_ref(ctx, node->data.ret.ret_val, true);
static void dump_ret_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *value) {
if (value->data.ret.ret_val)
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,
@@ -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;
}
void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t node_ref) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (!node) {
LOG_ERROR("Invalid node ref");
void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t value_ref) {
scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref);
if (!value) {
LOG_ERROR("Invalid value ref");
return;
}
scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "%s", get_node_type_str(node->tag));
if (node->name && node->name[0])
scc_tree_dump_value(ctx->dump_ctx, " [%s]", node->name);
if (node->type) {
scc_tree_dump_node(ctx->dump_ctx, "%s", get_node_type_str(value->tag));
if (value->name && value->name[0])
scc_tree_dump_value(ctx->dump_ctx, " [%s]", value->name);
if (value->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) {
scc_tree_dump_append(ctx->dump_ctx, " : ");
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:
dump_const_int_node(ctx, node);
dump_const_int_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_ALLOC:
break;
case SCC_IR_VALUE_TAG_LOAD:
dump_load_node(ctx, node);
dump_load_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_STORE:
dump_store_node(ctx, node);
dump_store_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_GET_PTR:
dump_get_ptr_node(ctx, node);
dump_get_ptr_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_OP:
dump_op_node(ctx, node);
dump_op_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_BRANCH:
dump_branch_node(ctx, node);
dump_branch_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_JUMP:
dump_jump_node(ctx, node);
dump_jump_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_CALL:
dump_call_node(ctx, node);
dump_call_node(ctx, value);
break;
case SCC_IR_VALUE_TAG_RET:
dump_ret_node(ctx, node);
dump_ret_node(ctx, value);
break;
default:
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;
}
}
@@ -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,
scc_ir_value_ref_t node_ref) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (!node) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%%%u", node_ref);
static void format_ref_or_value(scc_ir_dump_ctx_t *ctx,
scc_ir_value_ref_t value_ref) {
scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref);
if (!value) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%%%u", value_ref);
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",
node->data.const_int.int32);
value->data.const_int.int32);
return;
}
if (node->name && node->name[0] != '\0') {
scc_tree_dump_node(ctx->dump_ctx, "%%%u[%s]", node_ref, node->name);
if (value->name && value->name[0] != '\0') {
scc_tree_dump_node(ctx->dump_ctx, "%%%u[%s]", value_ref, value->name);
} 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_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,
scc_ir_value_ref_t node_ref) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (!node) {
scc_tree_dump_append(ctx->dump_ctx, "<invalid node>\n");
void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx,
scc_ir_value_ref_t value_ref) {
scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref);
if (!value) {
scc_tree_dump_append(ctx->dump_ctx, "<invalid value>\n");
return;
}
cbool needs_equals = (node->tag != SCC_IR_VALUE_TAG_BRANCH &&
node->tag != SCC_IR_VALUE_TAG_JUMP &&
node->tag != SCC_IR_VALUE_TAG_RET &&
node->tag != SCC_IR_VALUE_TAG_STORE);
cbool needs_equals = (value->tag != SCC_IR_VALUE_TAG_BRANCH &&
value->tag != SCC_IR_VALUE_TAG_JUMP &&
value->tag != SCC_IR_VALUE_TAG_RET &&
value->tag != SCC_IR_VALUE_TAG_STORE);
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, " = ");
}
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:
// 值已经在 format 中输出,这里不需要再做
break;
case SCC_IR_VALUE_TAG_CONST_UINT: {
scc_ir_type_t *type =
scc_ir_module_get_type(GET_MODULE(ctx), node->type);
Assert(type != null);
scc_ir_module_get_type(GET_MODULE(ctx), value->type);
Assert(type != nullptr);
if (type->tag == SCC_IR_TYPE_u8) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%c",
node->data.const_uint.uint8);
value->data.const_uint.uint8);
} else {
scc_tree_dump_append_fmt(ctx->dump_ctx, "%u",
node->data.const_uint.uint32);
value->data.const_uint.uint32);
}
break;
}
case SCC_IR_VALUE_TAG_CONST_FLOAT:
scc_tree_dump_append_fmt(ctx->dump_ctx, "%f",
node->data.const_float.float32);
value->data.const_float.float32);
break;
case SCC_IR_VALUE_TAG_AGGREGATE:
// 聚合类型:递归输出每个元素(每个占一行)
scc_vec_foreach(node->data.aggregate.elements, i) {
scc_ir_dump_node_linear(
ctx, scc_vec_at(node->data.aggregate.elements, i));
scc_vec_foreach(value->data.aggregate.elements, i) {
scc_ir_dump_value_linear(
ctx, scc_vec_at(value->data.aggregate.elements, i));
scc_tree_dump_append(ctx->dump_ctx, "\n");
}
return;
@@ -509,88 +539,89 @@ void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx,
break;
case SCC_IR_VALUE_TAG_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;
case SCC_IR_VALUE_TAG_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, " -> ");
format_node_ref_or_value(ctx, node->data.store.target);
format_ref_or_value(ctx, value->data.store.target);
break;
case SCC_IR_VALUE_TAG_GET_ELEM_PTR:
case SCC_IR_VALUE_TAG_GET_PTR:
scc_tree_dump_append(
ctx->dump_ctx,
node->tag == SCC_IR_VALUE_TAG_GET_PTR ? "getptr " : "getelemptr ");
format_node_ref_or_value(ctx, node->data.get_ptr.src_addr);
value->tag == SCC_IR_VALUE_TAG_GET_PTR ? "getptr " : "getelemptr ");
format_ref_or_value(ctx, value->data.get_ptr.src_addr);
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;
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 ",
get_op_str(node->data.op.op));
format_node_ref_or_value(ctx, node->data.op.rhs);
get_op_str(value->data.op.op));
format_ref_or_value(ctx, value->data.op.rhs);
break;
case SCC_IR_VALUE_TAG_BRANCH:
if (node->data.branch.cond) {
if (value->data.branch.cond) {
scc_tree_dump_append(ctx->dump_ctx, "br ");
format_node_ref_or_value(ctx, node->data.branch.cond);
scc_tree_dump_append_fmt(
ctx->dump_ctx, ", label %%L%u, label %%L%u",
node->data.branch.true_bblock, node->data.branch.false_bblock);
format_ref_or_value(ctx, value->data.branch.cond);
scc_tree_dump_append_fmt(ctx->dump_ctx,
", label %%L%u, label %%L%u",
value->data.branch.true_bblock,
value->data.branch.false_bblock);
} else {
scc_tree_dump_append_fmt(ctx->dump_ctx, "br label %%L%u",
node->data.branch.true_bblock);
value->data.branch.true_bblock);
}
break;
case SCC_IR_VALUE_TAG_JUMP:
scc_tree_dump_append_fmt(ctx->dump_ctx, "jmp label %%%u",
node->data.jump.target_bblock);
scc_tree_dump_append_fmt(ctx->dump_ctx, "jmp label %%L%u",
value->data.jump.target_bblock);
break;
case SCC_IR_VALUE_TAG_CALL: {
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(",
func ? (func->name ? func->name : "<unnamed>")
: "<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)
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, ")");
break;
}
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 ");
format_node_ref_or_value(ctx, node->data.ret.ret_val);
format_ref_or_value(ctx, value->data.ret.ret_val);
} else {
scc_tree_dump_append(ctx->dump_ctx, "ret void");
}
break;
case SCC_IR_VALUE_TAG_FUNC_ARG_REF:
scc_tree_dump_append_fmt(ctx->dump_ctx, "arg[%zu]",
node->data.arg_ref.idx);
value->data.arg_ref.idx);
break;
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC:
scc_tree_dump_append_fmt(ctx->dump_ctx, "global %s\n", node->name);
scc_ir_dump_node_linear(ctx, node->data.global_alloc.value);
scc_tree_dump_append_fmt(ctx->dump_ctx, "global %s\n", value->name);
scc_ir_dump_value_linear(ctx, value->data.global_alloc.value);
return;
case SCC_IR_VALUE_TAG_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_vec_foreach(node->data.const_array.elements, i) {
u8 ch = scc_vec_at(node->data.const_array.elements, i);
scc_vec_foreach(value->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(ctx->dump_ctx, " ]");
break;
default:
scc_tree_dump_append_fmt(ctx->dump_ctx, "<%s node %u>",
get_node_type_str(node->tag), node_ref);
scc_tree_dump_append_fmt(ctx->dump_ctx, "<%s value %u>",
get_node_type_str(value->tag), value_ref);
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++) {
scc_tree_dump_begin_line(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) {
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++) {
scc_ir_func_ref_t func_decl = scc_vec_at(ctx->cprog->func_decls, i);

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_ref_t ref) {
if (ref == 0)
return null;
return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2type);
if (idx >= ctx->types.size)
return null;
return nullptr;
return &ctx->types.data[idx];
}
scc_ir_value_t *scc_ir_module_get_value(scc_ir_module_t *ctx,
scc_ir_value_ref_t ref) {
if (ref == 0)
return null;
return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2value);
if (idx >= ctx->values.size)
return null;
return nullptr;
return &ctx->values.data[idx];
}
scc_ir_bblock_t *scc_ir_module_get_bblock(scc_ir_module_t *ctx,
scc_ir_bblock_ref_t ref) {
if (ref == 0)
return null;
return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2bblock);
if (idx >= ctx->bblocks.size)
return null;
return nullptr;
return &ctx->bblocks.data[idx];
}
scc_ir_func_t *scc_ir_module_get_func(scc_ir_module_t *ctx,
scc_ir_func_ref_t ref) {
if (ref == 0)
return null;
return nullptr;
usize idx = GET_ENTITY_INDEX(ctx, ref, uid2func);
if (idx >= ctx->funcs.size)
return null;
return nullptr;
return &ctx->funcs.data[idx];
}

View File

@@ -1,9 +1,9 @@
#include <scc_ir.h>
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->name = null;
in->name = nullptr;
switch (tag) {
case SCC_IR_TYPE_unknown:
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) {
Assert(in != null);
Assert(label != null);
Assert(in != nullptr);
Assert(label != nullptr);
in->label = label;
scc_vec_init(in->instrs);
}
void scc_ir_func_init(scc_ir_func_t *in, const char *name) {
Assert(in != null);
Assert(name != null);
Assert(in != nullptr);
Assert(name != nullptr);
in->name = name;
in->type = 0;
scc_vec_init(in->bblocks);
scc_vec_init(in->params);
}
void scc_ir_node_init(scc_ir_value_t *in, const char *name,
scc_ir_value_tag_t tag) {
Assert(in != null);
void scc_ir_value_init(scc_ir_value_t *in, const char *name,
scc_ir_value_tag_t tag) {
Assert(in != nullptr);
in->name = name;
in->tag = tag;
scc_vec_init(in->used_by);
in->type = 0;
switch (tag) {
case SCC_IR_VALUE_TAG_NULL:
case SCC_IR_VALUE_TAG_NULLPTR:
break;
case SCC_IR_VALUE_TAG_BUILTIN:
break;
case SCC_IR_VALUE_TAG_CONST_INT:
// TODO

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);

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; }

View File

@@ -2,22 +2,10 @@
#include <amd64/scc_amd64_abi.h>
#include <reg_alloc.h>
#include <scc_ir2mcode.h>
#include <type_manager.h>
#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) {
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);
@@ -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,
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);
if (node == null) {
if (node == nullptr) {
LOG_FATAL("invalid node ref");
UNREACHABLE();
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,
patch_vec_t *patches) {
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");
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);
scc_ir_type_t *base_type = scc_ir_module_get_type(
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);
// 间接加载到 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_AMD64_RCX);
} 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);
@@ -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);
scc_ir_type_t *base_type = scc_ir_module_get_type(
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) {
@@ -242,30 +232,47 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
}
break;
}
///< 获取指针
///< 获取指针
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(
GET_MODULE(ctx), node->data.get_ptr.src_addr);
Assert(src_addr != null);
if (src_addr->tag != SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
Panic();
Assert(src_addr != nullptr);
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_ADDRidx 是虚拟偏移(正数)
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);
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);
store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX);
break;
}
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_module_get_bblock(GET_MODULE(ctx), bblock_ref);
if (bblock == null) {
if (bblock == nullptr) {
LOG_FATAL("<invalid block>\n");
return;
}
@@ -593,7 +600,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
Assert(galloc->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC);
scc_ir_value_t *value = scc_ir_module_get_value(
GET_MODULE(ctx), galloc->data.global_alloc.value);
Assert(value != null);
Assert(value != nullptr);
sccf_sym_t sym = (sccf_sym_t){
.sccf_sect_offset = scc_vec_size(ctx->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_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);
parse_function(ctx, func);
}

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; }
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_t *bblock =
scc_ir_module_get_bblock(ctx->ir_module, bblock_ref);
Assert(bblock != null);
Assert(bblock != nullptr);
scc_vec_foreach(bblock->instrs, j) {
scc_ir_value_ref_t node_ref = scc_vec_at(bblock->instrs, j);
scc_ir_value_t *node =
scc_ir_module_get_value(ctx->ir_module, node_ref);
Assert(node != null);
Assert(node != nullptr);
loc.kind = SCC_REG_KIND_UNDEF;
switch (node->tag) {
case SCC_IR_VALUE_TAG_LOAD:
@@ -65,8 +66,17 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
// 为 alloc 分配栈偏移,但不作为普通值存储
loc.kind =
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;
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);

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 */
}

View File

@@ -24,7 +24,7 @@ void test_example(const char *input, cbool need_sema, const char *name) {
scc_sema_init(&sema_callbacks);
scc_parser_init(&parser, tok_ring, &sema_callbacks);
} 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);

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);
static inline void scc_lexer_tok_drop(scc_lexer_tok_t *tok) {
Assert(tok != null);
Assert(tok != nullptr);
tok->type = SCC_TOK_UNKNOWN;
tok->loc.col = 0;
tok->loc.line = 0;
tok->loc.name = null;
tok->loc.name = nullptr;
tok->loc.offset = 0;
scc_str_drop(&tok->lexeme);
}
@@ -209,7 +209,7 @@ static inline cbool scc_lexer_tok_match(const scc_lexer_tok_t *tok,
// 深拷贝 token
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;
dst.lexeme = scc_str_copy(&src->lexeme);
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
static inline void scc_lexer_tok_move(scc_lexer_tok_t *dst,
scc_lexer_tok_t *src) {
Assert(src != null);
Assert(src != nullptr);
*dst = *src;
src->lexeme.data = null;
src->lexeme.data = nullptr;
src->lexeme.size = 0;
src->lexeme.cap = 0;
}

View File

@@ -4,13 +4,13 @@
#include "scc_lexer.h"
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->lexeme = scc_str_from_cstr("1");
}
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->lexeme = scc_str_from_cstr("0");
}

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) {
Assert(lexer != null);
Assert(lexer != nullptr);
if (lexer->ring_ref_count) {
LOG_FATAL("drop sstream must be drop ring before ref [%d]",
lexer->ring_ref_count);

View File

@@ -24,12 +24,12 @@ int g_num_arr[3];
int main(int argc, char *argv[]) {
// int num = 0;
if (argc == 3 && strcmp(argv[2], "--debug") == 0) {
log_set_level(NULL, LOG_LEVEL_ALL);
log_set_level(nullptr, LOG_LEVEL_ALL);
} else {
// FIXME it is a hack lexer_logger
log_set_level(&__scc_lexer_log, LOG_LEVEL_NOTSET);
log_set_level(NULL, LOG_LEVEL_INFO | LOG_LEVEL_WARN | LOG_LEVEL_ERROR |
LOG_LEVEL_FATAL);
log_set_level(nullptr, LOG_LEVEL_INFO | LOG_LEVEL_WARN |
LOG_LEVEL_ERROR | LOG_LEVEL_FATAL);
}
const char *file_name = __FILE__;

View File

@@ -412,5 +412,5 @@ TEST_LIST = {
{"edge_cases", test_edge_cases},
{"sequences", test_sequences},
{"error_recovery", test_error_recovery},
{NULL, NULL},
{nullptr, nullptr},
};

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);
}
// ==================== 符号/零扩展加载(内存操作数) ====================
/**
* @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 位 ----------
@@ -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);
}
/**
* @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 位示例,其他宽度可类似添加
@@ -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);
}
/**
* @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
*

View File

@@ -5,20 +5,20 @@
static inline const scc_lexer_tok_t *scc_parser_peek(scc_parser_t *parser) {
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);
if (ok == false) {
return null;
return nullptr;
}
return tok;
}
static inline const scc_lexer_tok_t *scc_parser_next(scc_parser_t *parser) {
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);
if (ok == false) {
return null;
return nullptr;
}
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,
scc_tok_type_t type) {
cbool ok = false;
scc_lexer_tok_t *tok = null;
scc_lexer_tok_t *tok = nullptr;
scc_ring_unsafe_peek_ref(*parser->ring, tok, ok);
if (ok == false) {
return null;
return nullptr;
}
if (tok->type == type) {
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;
}
// 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,
scc_lexer_tok_t *tok) {
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);
if (tok == null) {
if (tok == nullptr) {
scc_lexer_tok_drop(raw_tok_ref);
} else {
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) {
const scc_lexer_tok_t *tok = scc_parser_peek(parser);
scc_pos_t pos = scc_pos_create();
if (tok != null)
if (tok != nullptr)
pos = tok->loc;
return pos;
}

View File

@@ -27,7 +27,7 @@ typedef struct scc_parser {
* @brief 初始化解析器
* @param parser 解析器实例
* @param lexer 词法分析器实例
* @param callbacks 语义分析回调(可为 null)
* @param callbacks 语义分析回调(可为 nullptr)
*/
void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring,
scc_sema_callbacks_t *callbacks);

View File

@@ -173,10 +173,10 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
[ constant-expression ]
. identifier
*/
const scc_lexer_tok_t *tok_ptr = null;
const scc_lexer_tok_t *tok_ptr = nullptr;
scc_lexer_tok_t tok = {0};
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)) {
// TODO int a = 1, b = 1;
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);
init = scc_malloc(sizeof(scc_ast_expr_t));
Assert(init != null);
Assert(init != nullptr);
scc_ast_expr_vec_t lhs_exprs;
scc_vec_init(lhs_exprs);
scc_ast_expr_vec_t rhs_exprs;
scc_vec_init(rhs_exprs);
scc_ast_expr_t *lhs = null;
scc_ast_expr_t *rhs = null;
scc_ast_expr_t *lhs = nullptr;
scc_ast_expr_t *rhs = nullptr;
scc_ast_expr_t *ptr = base;
while (1) {
tok_ptr = scc_parser_peek(parser);
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);
if (tok_ptr && tok_ptr->type == SCC_TOK_IDENT) {
scc_parser_next_consume(parser, &tok);
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),
tok.loc);
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;
}
rhs = scc_parse_initializer(parser, lhs);
if (rhs == null) {
if (rhs == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected initializer");
Panic();
@@ -224,34 +224,34 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
"Expected 'identifier' after '.'");
}
} 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);
Assert(idx != null);
Assert(idx != nullptr);
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ']'");
}
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);
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
ptr = lhs;
continue;
}
rhs = scc_parse_initializer(parser, lhs);
Assert(rhs != null);
Assert(rhs != nullptr);
scc_vec_push(lhs_exprs, lhs);
scc_vec_push(rhs_exprs, rhs);
ptr = base;
} else if (tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
} else if (tok_ptr->type == SCC_TOK_COMMA) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
continue;
} else {
// FIXME
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);
}
}
@@ -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) {
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_vec_init(decl_list_vec);
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type == null) {
return null;
if (type == nullptr) {
return nullptr;
}
scc_ast_decl_specifier_t spec = type->quals;
// FIXME drop typedef inline and ...
type->quals.is_typedef = false;
scc_ast_decl_t *decl = null;
scc_ast_decl_t *decl = nullptr;
CONTINUE:
decl = scc_parse_declarator(parser, type);
if (decl == null) {
return null;
if (decl == nullptr) {
return nullptr;
}
tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_ASSIGN) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
// TODO maybe memory leak
scc_ast_expr_t *lvalue = scc_malloc(sizeof(scc_ast_expr_t));
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) {
scc_parse_decl_sema(parser, decl);
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_ast_decl_t *param =
scc_vec_at(decl->func.type->function.params, i);
@@ -299,19 +299,19 @@ CONTINUE:
}
scc_ast_stmt_t *body = scc_parse_statement(parser);
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);
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.body != null);
Assert(decl->func.body != nullptr);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
goto RETURN;
}
tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_SEMICOLON) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
if (decl_list)
scc_vec_push(decl_list_vec, decl);
if (spec.is_typedef) {
@@ -326,7 +326,7 @@ CONTINUE:
decl->base.loc);
}
}
if (decl_list != null) {
if (decl_list != nullptr) {
scc_vec_foreach(decl_list_vec, i) {
decl = scc_vec_at(decl_list_vec, i);
scc_parse_decl_sema(parser, decl);
@@ -340,10 +340,10 @@ CONTINUE:
}
goto RETURN;
} else if (tok_ptr->type == SCC_TOK_COMMA) {
scc_parser_next_consume(parser, null);
if (decl_list == null) {
scc_parser_next_consume(parser, nullptr);
if (decl_list == nullptr) {
decl_list = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl_list != null);
Assert(decl_list != nullptr);
scc_vec_push(decl_list_vec, decl);
} else {
Assert(scc_vec_size(decl_list_vec) != 0);
@@ -361,5 +361,5 @@ CONTINUE:
RETURN:
return decl;
ERROR:
return null;
return nullptr;
}

View File

@@ -324,7 +324,7 @@ static scc_ast_expr_op_t map_token_to_assign_op(scc_tok_type_t type) {
// 跳过直到遇到同步 token分号、右括号、逗号、EOF
static void parser_sync(scc_parser_t *parser) {
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;
if (type == SCC_TOK_SEMICOLON || type == SCC_TOK_R_PAREN ||
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开始
scc_ast_expr_t *left = parse_cast_expression(parser);
if (!left)
return null;
return nullptr;
while (1) {
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);
if (!right) {
parser_sync(parser);
return null;
return nullptr;
}
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
Assert(expr != nullptr);
// FIXME pos
scc_ast_expr_binary_init(expr, op, left, right, left->base.loc);
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) {
// 先解析左侧的 unary-expressionC 标准规定赋值左边必须是
// unary-expression
scc_ast_expr_t *left = null;
scc_ast_expr_t *left = nullptr;
left = parse_conditional_expression(parser);
if (!left)
return null;
return nullptr;
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr)
@@ -406,11 +406,11 @@ scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
if (!right) {
// 错误恢复
parser_sync(parser);
return null;
return nullptr;
}
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);
left = expr;
}
@@ -422,7 +422,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
scc_ast_expr_t *cond_expr =
parse_expression_with_precedence(parser, PREC_LOGICAL_OR);
if (!cond_expr)
return null;
return nullptr;
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
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);
if (!then_expr) {
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),
"Expected ':' after '?'");
parser_sync(parser);
return null;
return nullptr;
}
// 解析 else 部分(右结合,再次调用 parse_conditional_expression
scc_ast_expr_t *else_expr = parse_conditional_expression(parser);
if (!else_expr) {
parser_sync(parser);
return null;
return nullptr;
}
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);
cond_expr = cond;
}
@@ -466,7 +466,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
// 类型转换表达式 (type-name) cast-expression
static scc_ast_expr_t *parse_cast_expression(scc_parser_t *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) {
// 尝试解析类型名
scc_parser_store(parser);
@@ -487,7 +487,7 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
return operand;
}
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
Assert(expr != nullptr);
// FIXME pos
scc_ast_expr_cast_init(expr, type, operand, type->base.loc);
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);
if (!tok_ptr)
return null;
return nullptr;
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
{
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_pos_t pos = tok.loc;
scc_lexer_tok_drop(&tok);
// 一元运算符右结合,递归调用 parse_unary_expression
scc_ast_expr_t *operand = null;
scc_ast_expr_t *operand = nullptr;
if (tok_ptr->type == SCC_TOK_ADD_ADD ||
tok_ptr->type == SCC_TOK_SUB_SUB) {
operand = parse_unary_expression(parser);
@@ -555,11 +555,11 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
}
if (!operand) {
parser_sync(parser);
return null;
return nullptr;
}
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);
return expr;
}
@@ -575,7 +575,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
scc_lexer_tok_t tok_ptr;
if (!scc_parser_next_consume(parser, &tok_ptr) ||
tok_ptr.type != SCC_TOK_SIZEOF) {
return null;
return nullptr;
}
scc_pos_t pos = tok_ptr.loc;
scc_lexer_tok_drop(&tok_ptr);
@@ -584,7 +584,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
if (!next) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected end after sizeof");
return null;
return nullptr;
}
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_next(parser);
scc_ast_type_t *type_name = scc_parse_type_name(parser);
if (type_name == null) {
if (type_name == nullptr) {
scc_parser_restore(parser);
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");
}
Assert(type_name != null);
scc_ast_expr_sizeof_init(expr, type_name, null, pos);
Assert(type_name != nullptr);
scc_ast_expr_sizeof_init(expr, type_name, nullptr, pos);
return expr;
}
next:
// 尝试解析 sizeof unary-expression
scc_ast_expr_t *operand = parse_unary_expression(parser);
if (operand != null) {
scc_ast_expr_sizeof_init(expr, null, operand, pos);
if (operand != nullptr) {
scc_ast_expr_sizeof_init(expr, nullptr, operand, pos);
return expr;
}
@@ -622,12 +622,12 @@ next:
// 后缀表达式
static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *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();
if (!left) {
tok_ptr = scc_parser_peek(parser);
if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN)) {
return null;
return nullptr;
}
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);
if (!type) {
scc_parser_restore(parser);
return null;
return nullptr;
}
scc_parser_commit(parser);
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) {
case SCC_TOK_L_BRACKET: // left[expr]
{
if (!scc_parser_next_consume(parser, null))
if (!scc_parser_next_consume(parser, nullptr))
return left;
pos = left->base.loc;
scc_ast_expr_t *index = scc_parse_expression(parser);
if (!index) {
parser_sync(parser);
return null;
return nullptr;
}
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ']' after subscript");
parser_sync(parser);
return null;
return nullptr;
}
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);
left = subscript;
break;
}
case SCC_TOK_L_PAREN: // left(args)
{
if (!scc_parser_next_consume(parser, null))
if (!scc_parser_next_consume(parser, nullptr))
return left;
pos = left->base.loc;
scc_ast_expr_vec_t args;
@@ -705,11 +705,11 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
// 释放已解析的参数
// TODO: 释放 args 中的表达式
parser_sync(parser);
return null;
return nullptr;
}
}
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);
left = call;
break;
@@ -726,12 +726,12 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
"Expected identifier after member access");
scc_lexer_tok_drop(&op_tok);
parser_sync(parser);
return null;
return nullptr;
}
const char *name = scc_str_as_cstr(&ident_tok.lexeme);
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) {
scc_ast_expr_member_init(member, left, name, ident_tok.loc);
} else {
@@ -750,7 +750,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
return left;
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));
Assert(expr != null);
Assert(expr != nullptr);
scc_ast_expr_unary_init(expr, op, left, op_tok.loc);
scc_lexer_tok_drop(&op_tok);
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);
if (!tok_ptr)
return null;
return nullptr;
scc_lexer_tok_t tok = {0};
scc_ast_expr_t *expr = null;
scc_ast_expr_t *expr = nullptr;
switch (tok_ptr->type) {
case SCC_TOK_IDENT: {
if (!scc_parser_next_consume(parser, &tok))
return null;
return nullptr;
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),
tok.loc);
break;
}
case SCC_TOK_INT_LITERAL: {
if (!scc_parser_next_consume(parser, &tok))
return null;
return nullptr;
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,
tok.loc);
break;
}
case SCC_TOK_FLOAT_LITERAL: {
if (!scc_parser_next_consume(parser, &tok))
return null;
return nullptr;
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),
false, tok.loc);
break;
}
case SCC_TOK_CHAR_LITERAL: {
if (!scc_parser_next_consume(parser, &tok))
return null;
return nullptr;
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),
false, tok.loc);
break;
@@ -822,7 +822,7 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
scc_lexer_tok_t tok;
while (1) {
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
break;
}
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));
Assert(expr != null);
Assert(expr != nullptr);
// FIXME loc
scc_ast_expr_literal_string_init(expr, scc_str_as_cstr(&string), true,
tok.loc);
break;
}
case SCC_TOK_L_PAREN:
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
expr = scc_parse_expression(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
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;
}
if (expr == null) {
return null;
if (expr == nullptr) {
return nullptr;
}
scc_parse_expr_sema(parser, 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 *left = scc_parse_assignment_expression(parser);
if (!left)
return null;
return nullptr;
const scc_lexer_tok_t *tok_ptr = null;
const scc_lexer_tok_t *tok_ptr = nullptr;
while (1) {
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;
}
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);
if (!right) {
parser_sync(parser);
return null;
return nullptr;
}
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);
left = expr;
}

View File

@@ -52,7 +52,7 @@ A.2.3 Statements
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));
if (stmt == null) {
if (stmt == nullptr) {
LOG_FATAL("Out of memory");
}
return stmt;
@@ -77,7 +77,7 @@ static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser,
scc_pos_t pos) {
scc_lexer_tok_t tok = {0};
if (!scc_parser_next_consume(parser, &tok)) {
return null;
return nullptr;
}
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);
if (statement == null) {
if (statement == nullptr) {
Panic("expect stmt");
}
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);
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,
scc_pos_t pos) {
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);
if (expr == null) {
if (expr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected constant expression after case.");
return null;
return nullptr;
}
if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected `:` after case.");
return null;
return nullptr;
}
scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) {
if (statement == nullptr) {
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,
scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_DEFAULT)) {
return null;
return nullptr;
}
if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected constant expression after case.");
return null;
return nullptr;
}
scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) {
if (statement == nullptr) {
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,
scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACE)) {
return null;
return nullptr;
}
scc_ast_block_item_vec_t block_items;
scc_vec_init(block_items);
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)) {
/// TODO
// 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);
if (ret == null) {
if (ret == nullptr) {
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");
// TODO free
parser->errcode = 1;
return null;
return nullptr;
}
scc_vec_push(block_items, ret);
}
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_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) {
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_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)) {
opt_else = scc_parse_statement(parser);
} else {
opt_else = null;
opt_else = nullptr;
}
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,
scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_SWITCH)) {
return null;
return nullptr;
}
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,
scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_WHILE)) {
return null;
return nullptr;
}
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,
scc_pos_t pos) {
if (!scc_parser_consume_if(parser, SCC_TOK_DO)) {
return null;
return nullptr;
}
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.");
// TODO 使用更好的错误处理,未来应当采用更好的内存管理器
scc_free(statement);
return null;
return nullptr;
}
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,
scc_pos_t pos) {
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 )` .");
}
scc_ast_node_t *init = null;
scc_ast_expr_t *cond = null;
scc_ast_expr_t *incr = null;
scc_ast_stmt_t *body = null;
scc_ast_node_t *init = nullptr;
scc_ast_expr_t *cond = nullptr;
scc_ast_expr_t *incr = nullptr;
scc_ast_stmt_t *body = nullptr;
// TODO use decl or expr
init = (scc_ast_node_t *)scc_parse_declaration(parser);
if (init == null) {
if (init == nullptr) {
init = (scc_ast_node_t *)scc_parse_expression(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
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)) {
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;
}
scc_ast_expr_t *expr = scc_parse_expression(parser);
if (expr == null) {
return null;
if (expr == nullptr) {
return nullptr;
}
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;
tok_ref = scc_parser_peek(parser);
if (!tok_ref) {
return null;
return nullptr;
}
scc_pos_t pos = tok_ref->loc;
switch (tok_ref->type) {
@@ -376,7 +376,7 @@ scc_ast_stmt_t *scc_parse_statement(scc_parser_t *parser) {
case SCC_TOK_IDENT:
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);
break;
}

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() {
scc_ast_type_t *ast_type = scc_malloc(sizeof(scc_ast_type_t));
ast_type->base.type = SCC_AST_UNKNOWN;
if (ast_type == null) {
if (ast_type == nullptr) {
LOG_FATAL("Out of memory");
}
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) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return false;
}
switch (tok_ptr->type) {
@@ -230,7 +230,7 @@ cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) {
// typedef 名称(标识符也可能是类型说明符)
case SCC_TOK_IDENT:
return scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)) !=
null;
nullptr;
default:
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) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return false;
}
switch (tok_ptr->type) {
@@ -261,7 +261,7 @@ cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) {
case SCC_TOK_IDENT:
// 需要检查标识符是否在符号表中定义为 typedef
return scc_parse_got_type(parser, scc_str_as_cstr(&tok_ptr->lexeme)) !=
null;
nullptr;
default:
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) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return false;
}
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) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return false;
}
switch (tok_ptr->type) {
@@ -320,10 +320,10 @@ parse_type_qualifier_list(scc_parser_t *parser,
type-qualifier
type-qualifier-list type-qualifier
*/
const scc_lexer_tok_t *tok_ptr = null;
const scc_lexer_tok_t *tok_ptr = nullptr;
CONTINUE:
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return quals;
}
switch (tok_ptr->type) {
@@ -340,7 +340,7 @@ CONTINUE:
default:
return quals;
}
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
goto CONTINUE;
duplicate_error:
SCC_ERROR(scc_parser_got_current_pos(parser), "Duplicate type specifier");
@@ -350,10 +350,10 @@ duplicate_error:
static scc_ast_decl_specifier_t
parse_declaration_specifiers_list(scc_parser_t *parser,
scc_ast_decl_specifier_t quals) {
const scc_lexer_tok_t *tok_ptr = null;
const scc_lexer_tok_t *tok_ptr = nullptr;
CONTINUE:
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return quals;
}
switch (tok_ptr->type) {
@@ -385,7 +385,7 @@ CONTINUE:
default:
return quals;
}
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
goto CONTINUE;
duplicate_error:
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;
}
// 如果用户定义了类型struct/typedef不能与任何其他类型说明符混合
if (info->user_type != null && basic_count > 0) {
if (info->user_type != nullptr && basic_count > 0) {
SCC_ERROR(
scc_parser_got_current_pos(parser),
"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);
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");
return null;
return nullptr;
}
const char *name = null;
scc_ast_decl_t *decl = null;
const char *name = nullptr;
scc_ast_decl_t *decl = nullptr;
scc_ast_decl_vec_t 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) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
while (1) {
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected EOF in enum specifier");
break;
}
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type != null) {
if (type != nullptr) {
decl = scc_parse_declarator(parser, type);
if (decl != null) {
if (decl != nullptr) {
scc_vec_push(member, decl);
continue;
}
@@ -610,20 +610,20 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
if (tok_ptr->type == SCC_TOK_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) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
} else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected token in struct/union specifier");
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
}
}
decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null);
Assert(decl != nullptr);
if (type_kind == SCC_AST_TYPE_STRUCT) {
scc_ast_decl_struct_init(decl, name, &member, pos);
} else {
@@ -631,11 +631,11 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
}
scc_parse_decl_sema(parser, decl);
} else {
if (name == null) {
if (name == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected name in struct/union specifier");
// 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;
if (tok.type != SCC_TOK_ENUM) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expected 'enum'");
return null;
return nullptr;
}
scc_lexer_tok_drop(&tok);
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");
return null;
return nullptr;
}
scc_ast_type_t *type = ast_type_alloc();
const char *name = null;
scc_ast_decl_t *decl = null;
const char *name = nullptr;
scc_ast_decl_t *decl = nullptr;
scc_ast_decl_vec_t 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) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
while (1) {
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Unexpected EOF in enum specifier");
break;
@@ -703,13 +703,13 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
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)) {
enum_item_init = scc_parser_constant_expression(parser);
}
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_str_as_cstr(&tok.lexeme), enum_item_init,
tok.loc);
@@ -719,34 +719,35 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
cbool got_comma = false;
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);
got_comma = true;
}
if (tok_ptr && tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
} else {
if (got_comma) {
continue;
}
SCC_ERROR(tok_ptr != null ? tok_ptr->loc
: scc_parser_got_current_pos(parser),
SCC_ERROR(tok_ptr != nullptr
? tok_ptr->loc
: scc_parser_got_current_pos(parser),
"Unexpected token in enum specifier");
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
}
}
decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null);
Assert(decl != nullptr);
scc_ast_decl_enum_init(decl, name, &member, pos);
scc_parse_decl_sema(parser, decl);
} else {
if (name == null) {
if (name == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected name in enum specifier");
// 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) {
type_spec_info_t info = {0};
if (!scc_parse_is_type_specifier_start(parser))
return null;
const scc_lexer_tok_t *tok_ptr = null;
return nullptr;
const scc_lexer_tok_t *tok_ptr = nullptr;
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
return null;
if (tok_ptr == nullptr) {
return nullptr;
}
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:
info.user_type =
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),
"Expected type specifier %s",
scc_str_as_cstr(&tok_ptr->lexeme));
}
scc_parser_next_consume(parser, null);
Assert(info.user_type != null);
scc_parser_next_consume(parser, nullptr);
Assert(info.user_type != nullptr);
goto done;
default:
break;
@@ -792,7 +793,7 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
while (1) {
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
break;
}
switch (tok_ptr->type) {
@@ -800,32 +801,32 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
if (info.is_void)
goto duplicate_error;
info.is_void = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_CHAR:
if (info.is_char)
goto duplicate_error;
info.is_char = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_SHORT:
if (info.is_short)
goto duplicate_error;
info.is_short = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_INT:
if (info.is_int)
goto duplicate_error;
info.is_int = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_LONG:
// long 可以出现两次
if (info.is_long_long) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Three 'long's in type specifier");
return null;
return nullptr;
}
if (info.is_long) {
info.is_long_long = true;
@@ -833,49 +834,49 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
} else {
info.is_long = true;
}
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_FLOAT:
if (info.is_float)
goto duplicate_error;
info.is_float = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_DOUBLE:
if (info.is_double)
goto duplicate_error;
info.is_double = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_BOOL:
if (info.is_bool)
goto duplicate_error;
info.is_bool = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_SIGNED:
if (info.is_unsigned || info.is_signed) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Both 'signed' and 'unsigned' in type specifier");
return null;
return nullptr;
}
info.is_signed = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_UNSIGNED:
if (info.is_unsigned || info.is_signed) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Both 'signed' and 'unsigned' in type specifier");
return null;
return nullptr;
}
info.is_unsigned = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
case SCC_TOK_COMPLEX:
if (info.is_complex)
goto duplicate_error;
info.is_complex = true;
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
break;
default:
goto done;
@@ -883,12 +884,12 @@ static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) {
}
done:
if (!check_type_combinations(parser, &info)) {
return null;
return nullptr;
}
return build_type_from_info(&info, pos);
duplicate_error:
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,
@@ -900,15 +901,15 @@ static scc_ast_type_t *parse_pointer(scc_parser_t *parser,
* type-qualifier-list(opt) pointer
*/
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;
}
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();
if (pointee == null) {
Assert(delay_pointee_ptr != null);
if (pointee == nullptr) {
Assert(delay_pointee_ptr != nullptr);
*delay_pointee_ptr = pointer;
pointee = pointer;
}
@@ -931,17 +932,17 @@ static void parse_parameter_type_list(scc_parser_t *parser,
declaration-specifiers declarator
declaration-specifiers abstract-declarator(opt)
*/
scc_ast_decl_t *param = null;
scc_ast_decl_t *decl = null;
const scc_lexer_tok_t *tok_ptr = null;
scc_ast_decl_t *param = nullptr;
scc_ast_decl_t *decl = nullptr;
const scc_lexer_tok_t *tok_ptr = nullptr;
while (1) {
// FIXME
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type == null) {
if (type == nullptr) {
break;
}
decl = scc_parse_declarator(parser, type);
if (decl == null) {
if (decl == nullptr) {
break;
}
@@ -957,18 +958,18 @@ static void parse_parameter_type_list(scc_parser_t *parser,
break;
}
scc_parser_next_consume(parser, null);
scc_parser_next_consume(parser, nullptr);
tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_ELLIPSIS) {
param = scc_malloc(sizeof(scc_ast_decl_t));
Assert(param != null);
Assert(param != nullptr);
// FIXME
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,
tok_ptr->loc);
scc_ast_decl_param_init(param, type, null, tok_ptr->loc);
scc_parser_next_consume(parser, null);
scc_ast_decl_param_init(param, type, nullptr, tok_ptr->loc);
scc_parser_next_consume(parser, nullptr);
scc_vec_push(*params, param);
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) {
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return false;
}
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) {
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)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expect '['");
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};
if (scc_parse_is_type_qualifier_start(parser)) {
// static assignment-expression
@@ -1019,7 +1020,7 @@ static scc_ast_expr_t *parse_array_size_type(scc_parser_t *parser) {
// TODO
}
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);
}
} 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 {
// assignment-expression(opt)
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);
}
}
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "expect ']'");
parser->errcode = 1;
return null;
return nullptr;
}
return size;
}
@@ -1071,16 +1072,16 @@ static scc_ast_type_t *
parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr,
scc_lexer_tok_t *tok_ident) {
const scc_lexer_tok_t *tok_ptr = null;
scc_ast_type_t *ret = null;
const scc_lexer_tok_t *tok_ptr = nullptr;
scc_ast_type_t *ret = nullptr;
// direct-abstract-declarator
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return base;
}
if (tok_ptr->type == SCC_TOK_IDENT) {
Assert(tok_ident != null);
Assert(tok_ident != nullptr);
if (tok_ident->type != SCC_TOK_UNKNOWN) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Got double identifier in declarator");
@@ -1092,8 +1093,8 @@ parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
tok_ident);
} else if (tok_ptr->type == SCC_TOK_L_PAREN) {
// () SCC_TOK_L_PAREN
scc_parser_next_consume(parser, null);
scc_ast_type_t *delay_pointee = null;
scc_parser_next_consume(parser, nullptr);
scc_ast_type_t *delay_pointee = nullptr;
if (parse_function_parameters_start(parser)) {
scc_ast_decl_vec_t 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,
tok_ident);
} else {
ret = parse_declarator(parser, null, &delay_pointee, tok_ident);
if (ret == null) {
ret = parse_declarator(parser, nullptr, &delay_pointee, tok_ident);
if (ret == nullptr) {
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)) {
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,
tok_ident);
Assert(SCC_AST_IS_A(scc_ast_type_t, base));
Assert(delay_pointee != null);
Assert(delay_pointee != nullptr);
delay_pointee->pointer.pointee = base;
return ret;
}
@@ -1158,18 +1159,18 @@ parse_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
static scc_ast_type_t *
parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr) {
const scc_lexer_tok_t *tok_ptr = null;
scc_ast_type_t *ret = null;
const scc_lexer_tok_t *tok_ptr = nullptr;
scc_ast_type_t *ret = nullptr;
// direct-abstract-declarator
tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
if (tok_ptr == nullptr) {
return base;
}
if (tok_ptr->type == SCC_TOK_L_PAREN) {
// () SCC_TOK_L_PAREN
scc_parser_next_consume(parser, null);
scc_ast_type_t *delay_pointee = null;
scc_parser_next_consume(parser, nullptr);
scc_ast_type_t *delay_pointee = nullptr;
if (parse_function_parameters_start(parser)) {
scc_ast_decl_vec_t 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,
delay_pointee_ptr);
} else {
ret = parse_abstract_declarator(parser, null, &delay_pointee);
Assert(ret != null);
ret = parse_abstract_declarator(parser, nullptr, &delay_pointee);
Assert(ret != nullptr);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "expect ')'");
}
base = parse_direct_abstract_declarator(parser, base,
delay_pointee_ptr);
Assert(delay_pointee != null);
Assert(delay_pointee != nullptr);
delay_pointee->pointer.pointee = base;
}
return ret;
@@ -1208,20 +1209,21 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
scc_ast_type_t *type) {
scc_lexer_tok_t decl_name_tok = {0};
scc_ast_type_t *decl_type =
parse_declarator(parser, type, null, &decl_name_tok);
scc_ast_decl_t *decl = null;
parse_declarator(parser, type, nullptr, &decl_name_tok);
scc_ast_decl_t *decl = nullptr;
decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null);
Assert(decl != nullptr);
Assert(decl_name_tok.type == SCC_TOK_IDENT ||
decl_name_tok.type == SCC_TOK_UNKNOWN);
// FIXME memory leak
const char *name = decl_name_tok.type == SCC_TOK_IDENT
? scc_str_as_cstr(&decl_name_tok.lexeme)
: null;
: nullptr;
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
if (type->quals.is_inline) {
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;
}
} 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);
}
@@ -1237,17 +1239,17 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
if (decl_type->base.type == SCC_AST_TYPE_STRUCT ||
decl_type->base.type == SCC_AST_TYPE_UNION ||
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));
Assert(decl != null);
Assert(decl != nullptr);
if (decl_type->base.type == SCC_AST_TYPE_STRUCT) {
scc_ast_decl_struct_init(decl, decl_type->record.name, null,
decl_type->base.loc);
scc_ast_decl_struct_init(decl, decl_type->record.name,
nullptr, decl_type->base.loc);
} else if (decl_type->base.type == SCC_AST_TYPE_UNION) {
scc_ast_decl_union_init(decl, decl_type->record.name, null,
decl_type->base.loc);
scc_ast_decl_union_init(decl, decl_type->record.name,
nullptr, decl_type->base.loc);
} 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);
}
} else {
@@ -1256,7 +1258,7 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser,
}
} else {
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);
}
}
@@ -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) {
if (!scc_parse_is_decl_specifier_start(parser)) {
return null;
return nullptr;
}
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);
scc_ast_type_t *specifier = parse_type_specifier(parser);
if (specifier == null) {
if (specifier == nullptr) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"declaration specifier can't have type specifier");
return null;
return nullptr;
}
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) {
if (!(scc_parse_is_type_specifier_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};
spec = parse_type_qualifier_list(parser, spec);
ret = parse_type_specifier(parser);
if (ret != null) {
if (ret != nullptr) {
ret->quals = spec;
}
ret = parse_abstract_declarator(parser, ret, null);
ret = parse_abstract_declarator(parser, ret, nullptr);
return ret;
}

View File

@@ -13,7 +13,7 @@ static scc_ast_type_t *dummy_got_type_callback(void *context,
const char *name) {
(void)context;
(void)name;
return null;
return nullptr;
}
#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,
scc_sema_callbacks_t *callbacks) {
Assert(parser != null && tok_ring != null);
Assert(parser != nullptr && tok_ring != nullptr);
parser->ring = tok_ring;
parser->errcode = 0;
parser->translation_unit = null;
parser->translation_unit = nullptr;
if (callbacks) {
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_decl,
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_type = dummy_sema_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_malloc(sizeof(scc_ast_translation_unit_t));
if (!unit)
return null;
return nullptr;
unit->base.type = SCC_AST_TRANSLATION_UNIT;
scc_vec_init(unit->declarations);
@@ -66,7 +66,7 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
*/
while (1) {
scc_ast_decl_t *decl = scc_parse_declaration(parser);
if (decl != null) {
if (decl != nullptr) {
scc_vec_push(unit->declarations, decl);
} else {
break;
@@ -77,7 +77,7 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
break;
}
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;
}
}
@@ -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",
parser->errcode);
scc_free(unit);
return null;
return nullptr;
}
Assert(unit->base.type == SCC_AST_TRANSLATION_UNIT);

View File

@@ -15,14 +15,14 @@ static void expr_callback(void *context, scc_ast_node_type_t node_type,
void *node) {
scc_sema_symtab_t *sema_symtab = context;
if (node_type == SCC_AST_UNKNOWN || node == null) {
if (node_type == SCC_AST_UNKNOWN || node == nullptr) {
return;
}
scc_ast_expr_t *expr = SCC_AST_CAST_TO(scc_ast_expr_t, node);
if (node_type == SCC_AST_EXPR_IDENTIFIER) {
scc_ast_node_t *node =
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",
expr->identifier.name);
} 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);
return;
}
if (node_type == SCC_AST_UNKNOWN || node == null) {
if (node_type == SCC_AST_UNKNOWN || node == nullptr) {
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);
return;
}
if (node_type == SCC_AST_UNKNOWN || node == null) {
if (node_type == SCC_AST_UNKNOWN || node == nullptr) {
return;
}
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));
Assert(type != null);
Assert(type != nullptr);
if (node_type == SCC_AST_DECL_STRUCT) {
scc_ast_type_struct_init(type, decl->name, decl, decl->base.loc);
// FIXME memory leak
scc_str_t name = scc_str_from_cstr("$S_");
if (decl->name == null) {
if (decl->name == nullptr) {
decl->name = "<anonymous struct>";
}
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) {
scc_ast_type_union_init(type, decl->name, decl, decl->base.loc);
scc_str_t name = scc_str_from_cstr("$U_");
if (decl->name == null) {
if (decl->name == nullptr) {
decl->name = "<anonymous union>";
}
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) {
scc_ast_type_enum_init(type, decl->name, decl, decl->base.loc);
scc_str_t name = scc_str_from_cstr("$E_");
if (decl->name == null) {
if (decl->name == nullptr) {
decl->name = "<anonymous enum>";
}
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);
}
} else if (node_type == SCC_AST_DECL_TYPEDEF) {
if (decl->name == null) {
if (decl->name == nullptr) {
SCC_ERROR(decl->base.loc, "typedef without name");
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) {
scc_sema_symtab_add_symbol(sema_symtab, decl->name, &decl->base);
} 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 &&
(decl->param.type->builtin.type ==
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);
} 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");
} else {
// FIXME 重名函数...
@@ -150,12 +150,12 @@ static scc_ast_type_t *got_type_callback(void *context, const char *name) {
*type = *(scc_ast_type_t *)node;
return type;
}
return null;
return nullptr;
}
void scc_sema_init(scc_sema_callbacks_t *callbacks) {
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");
return;
}
@@ -176,15 +176,16 @@ void scc_sema_init(scc_sema_callbacks_t *callbacks) {
&type->base);
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_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_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_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",
&builin_func->base);
scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_end",

View File

@@ -1,7 +1,7 @@
#include <sema_symtab.h>
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_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) {
while (symtab->current_scope != null) {
while (symtab->current_scope != nullptr) {
scc_hashtable_drop(&symtab->current_scope->symbols);
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) {
scc_sema_scope_t *scope = scc_malloc(sizeof(scc_sema_scope_t));
if (scope == null) {
if (scope == nullptr) {
LOG_FATAL("out of memory");
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,
const char *name) {
scc_ast_node_t *node = null;
for (scc_sema_scope_t *scope = symtab->current_scope; scope != null;
scc_ast_node_t *node = nullptr;
for (scc_sema_scope_t *scope = symtab->current_scope; scope != nullptr;
scope = scope->parent) {
node = scc_hashtable_get(&scope->symbols, name);
if (node != null) {
if (node != nullptr) {
return node;
}
}
return null;
return nullptr;
}

View File

@@ -26,7 +26,7 @@ static scc_ast_node_t *process_input(const char *input,
scc_sema_init(&sema_callbacks);
scc_parser_init(&parser, tok_ring, &sema_callbacks);
} else {
scc_parser_init(&parser, tok_ring, null);
scc_parser_init(&parser, tok_ring, nullptr);
}
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) {
// FIXME MAYBE free
LOG_FATAL("Didn't consume all tokens");
return null;
return nullptr;
}
scc_lexer_drop_ring(parser.ring);

View File

@@ -170,14 +170,14 @@ static void test_unary_expr(void) {
TEST_CASE("sizeof expression");
{
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);
}
TEST_CASE("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);
}
}
@@ -391,5 +391,5 @@ TEST_LIST = {
{"test_comma_expr", test_comma_expr},
{"test_complex_expr", test_complex_expr},
{"test_detail_expr", test_detail_expr},
{NULL, NULL},
{nullptr, nullptr},
};

View File

@@ -106,7 +106,7 @@ static void test_array_type(void) {
{
// 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_CHECK_AST(&array_unknown_int.base, "int []", scc_parse_type_name);
}
@@ -159,7 +159,7 @@ static void test_function_type(void) {
{
// int ()
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_CHECK_AST(&func_type.base, "int ()", scc_parse_type_name);
}
@@ -168,7 +168,7 @@ static void test_function_type(void) {
{
// int (void)
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_ast_decl_vec_t params;
@@ -189,8 +189,9 @@ static void test_function_type(void) {
scc_pos_create());
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_float, &float_type, null,
scc_ast_decl_param_init(&param_int, &int_type, nullptr,
scc_pos_create());
scc_ast_decl_param_init(&param_float, &float_type, nullptr,
scc_pos_create());
scc_ast_decl_vec_t params;
@@ -212,7 +213,8 @@ static void test_function_type(void) {
scc_pos_create());
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_pos_create());
@@ -231,7 +233,7 @@ static void test_function_type(void) {
{
// int *()
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_CHECK_AST(&func_type.base, "int *()", scc_parse_type_name);
}
@@ -240,7 +242,7 @@ static void test_function_type(void) {
{
// int (*)(void)
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_ast_decl_vec_t params;
@@ -262,7 +264,7 @@ static void test_struct_union_type(void) {
{
// struct S
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);
}
@@ -270,7 +272,7 @@ static void test_struct_union_type(void) {
{
// union U
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);
}
@@ -278,17 +280,19 @@ static void test_struct_union_type(void) {
{
// struct { int 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_vec_init(fields);
scc_vec_push(fields, &field_x);
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_struct_init(&struct_type, null, &struct_decl,
scc_ast_type_struct_init(&struct_type, nullptr, &struct_decl,
scc_pos_create());
SCC_CHECK_AST(&struct_type.base, "struct { int x; }",
scc_parse_type_name);
@@ -298,7 +302,8 @@ static void test_struct_union_type(void) {
{
// struct S { int 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_vec_init(fields);
@@ -322,8 +327,9 @@ static void test_struct_union_type(void) {
scc_pos_create());
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_b, &float_type, "b", null,
scc_ast_decl_val_init(&field_a, &int_type, "a", nullptr,
scc_pos_create());
scc_ast_decl_val_init(&field_b, &float_type, "b", nullptr,
scc_pos_create());
scc_ast_decl_vec_t fields;
@@ -332,10 +338,11 @@ static void test_struct_union_type(void) {
scc_vec_push(fields, &field_b);
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_union_init(&union_type, null, &union_decl,
scc_ast_type_union_init(&union_type, nullptr, &union_decl,
scc_pos_create());
SCC_CHECK_AST(&union_type.base, "union { int a; float b; }",
scc_parse_type_name);
@@ -347,7 +354,7 @@ static void test_enum_type(void) {
{
// enum E
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);
}
@@ -357,10 +364,11 @@ static void test_enum_type(void) {
scc_ast_type_t enum_type;
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(&green, &enum_type, "GREEN", null,
scc_ast_decl_val_init(&red, &enum_type, "RED", nullptr,
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_ast_decl_vec_t enumerators;
@@ -370,10 +378,11 @@ static void test_enum_type(void) {
scc_vec_push(enumerators, &blue);
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_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_parse_type_name);
}
@@ -384,10 +393,11 @@ static void test_enum_type(void) {
scc_ast_type_t enum_type;
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(&green, &enum_type, "GREEN", null,
scc_ast_decl_val_init(&red, &enum_type, "RED", nullptr,
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_ast_decl_vec_t enumerators;
@@ -397,7 +407,7 @@ static void test_enum_type(void) {
scc_vec_push(enumerators, &blue);
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_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)
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_ast_decl_vec_t params;
scc_vec_init(params);
@@ -533,7 +543,7 @@ static void test_hard_type(void) {
// 3) 函数类型,返回上述指针,无参数
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_ast_decl_vec_t params;
scc_vec_init(params);
@@ -556,7 +566,7 @@ static void test_hard_type(void) {
{
// 1) 函数类型 int (void)
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_ast_decl_vec_t params;
scc_vec_init(params);
@@ -572,7 +582,7 @@ static void test_hard_type(void) {
// 3) 外部函数类型,返回上述指针,无参数
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_CHECK_AST(&outer_func.base, "int (*())(void)", scc_parse_type_name);
@@ -588,5 +598,5 @@ TEST_LIST = {
{"test_enum_type", test_enum_type},
{"test_specifier_type", test_specifier_type},
{"test_hard_type", test_hard_type},
{null, null},
{nullptr, nullptr},
};

View File

@@ -32,7 +32,7 @@ static void test_parser_unit(void) {
// 1. 变量声明 int a;
{
scc_ast_decl_t int_decl;
scc_ast_decl_val_init(&int_decl, &int_type, "a", null,
scc_ast_decl_val_init(&int_decl, &int_type, "a", nullptr,
scc_pos_create());
SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration);
}
@@ -43,14 +43,15 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, 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_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create());
// 构造复合语句块(空)
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null, scc_pos_create());
scc_ast_stmt_compound_init(&compound, nullptr, scc_pos_create());
// 构造函数声明
scc_ast_decl_t func_decl;
@@ -66,14 +67,15 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, 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_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params,
scc_pos_create());
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null, scc_pos_create());
scc_ast_stmt_compound_init(&compound, nullptr, scc_pos_create());
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound,
@@ -114,7 +116,8 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, 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_vec_unsafe_from_static_array(func_params, array);
scc_ast_type_function_init(&func_type, &int_type, &func_params,
@@ -139,11 +142,13 @@ static void test_parser_unit(void) {
{
// 变量声明 int a;
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;
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
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_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_func_init(&func_decl, &func_type, "main", &compound,
@@ -284,8 +289,8 @@ static void test_parser_unit(void) {
// 函数类型(返回 int无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&int_type,
null,
scc_pos_create()); // null 表示无参数
nullptr,
scc_pos_create()); // nullptr 表示无参数
// 函数声明 int main() { ... }
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_pos_create());
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, (scc_ast_type_t *)&va_list_type, null,
scc_pos_create());
scc_ast_decl_param_init(&param2, (scc_ast_type_t *)&va_list_type,
nullptr, scc_pos_create());
scc_ast_decl_t *params_array[] = {&param0, &param1, &param2};
scc_vec_unsafe_from_static_array(params, params_array);
scc_ast_type_t decl_func_type;
scc_ast_type_function_init(&decl_func_type, (scc_ast_type_t *)&int_type,
&params, scc_pos_create());
scc_ast_decl_t decl_func;
scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", null,
scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", nullptr,
scc_pos_create());
SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);",
scc_parse_declaration);
@@ -343,7 +348,7 @@ static void test_parser_unit(void) {
scc_pos_create());
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_ast_node_t *array[] = {&typedef_decl.base, &i32a_decl.base};
@@ -364,7 +369,7 @@ static void test_parser_unit(void) {
scc_pos_create());
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_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; } (匿名结构体定义)
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_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, 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_parse_declaration);
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_ast_type_t typedef_type;
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_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_ast_node_t *array[] = {&typedef_decl.base, &typedef_impl_decl.base};
scc_ast_stmt_t stmt;
@@ -431,7 +437,8 @@ static void test_parser_unit(void) {
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &int_type, "b", scc_pos_create());
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_vec_t func_params;
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_pos_create());
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_ast_decl_t *decls_array[] = {&type_decl, &func_decl};
@@ -512,7 +519,7 @@ static void test_parser_unit(void) {
// 6. 函数声明
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());
// 7. 与解析结果比较
@@ -664,9 +671,9 @@ static void test_parser_unit(void) {
{
scc_ast_decl_t decl_a, decl_b;
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",
null, scc_pos_create());
nullptr, scc_pos_create());
scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec);
@@ -708,7 +715,7 @@ static void test_parser_unit(void) {
{
// 构造 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());
// 构造两个指针类型(分别用于 next 和 prev指向同一结构体
@@ -720,9 +727,9 @@ static void test_parser_unit(void) {
// 构造变量声明 next 和 prev
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_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());
// 构造声明列表
@@ -742,7 +749,7 @@ static void test_parser_unit(void) {
// 构造字段 int a;
scc_ast_decl_t field_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_vec_init(fields);
@@ -750,12 +757,12 @@ static void test_parser_unit(void) {
// 构造匿名结构体定义声明
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_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());
// 构造指针类型指向该匿名结构体
@@ -807,7 +814,8 @@ static void test_parser_unit(void) {
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &void_type, 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_vec_unsafe_from_static_array(func_params, array);
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_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_CHECK_AST(&ptr_to_func_decl.base, "int (*(*foo)(void))[5];",
scc_parse_declaration);
@@ -838,13 +846,14 @@ static void test_parser_unit(void) {
scc_ast_decl_param_init(&param2, &typedef_func_type, "a",
scc_pos_create());
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_vec_t func_hard_params;
scc_vec_unsafe_from_static_array(func_hard_params, func_hard_array);
scc_ast_type_function_init(&func_hard_type, &ptr_to_array,
&func_hard_params, scc_pos_create());
scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", null,
scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", nullptr,
scc_pos_create());
scc_ast_decl_vec_t decls;
@@ -865,5 +874,5 @@ static void test_parser_unit(void) {
TEST_LIST = {
{"parser_unit", test_parser_unit},
{null, null},
{nullptr, nullptr},
};

View File

@@ -1,5 +1,5 @@
#include <utest/acutest.h>
TEST_LIST = {
{NULL, NULL},
{nullptr, nullptr},
};

View File

@@ -33,7 +33,7 @@ typedef struct scc_macro_table {
* @brief 创建宏对象
* @param name 宏名称
* @param type 宏类型
* @return 创建的宏对象指针,失败返回NULL
* @return 创建的宏对象指针,失败返回nullptr
*/
scc_pproc_macro_t *scc_pproc_macro_new(const scc_str_t *name,
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 查找宏定义
* @param pp 预处理器实例
* @param name 宏名称
* @return 找到的宏对象指针,未找到返回NULL
* @return 找到的宏对象指针,未找到返回nullptr
*/
scc_pproc_macro_t *scc_pproc_macro_table_get(scc_pproc_macro_table_t *pp,
const scc_str_t *name);

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,
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};
int depth = 0;
int ok;
@@ -337,7 +337,7 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
case SCC_PP_TOK_ELSE:
case SCC_PP_TOK_ENDIF: {
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);
return;
}

View File

@@ -22,7 +22,7 @@ static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
scc_str_append_ch(&str, '\"'); // 左引号
int need_space = 0; // 是否需要插入空格
scc_lexer_tok_t *tok = null;
scc_lexer_tok_t *tok = nullptr;
scc_vec_foreach(*arg_tokens, i) {
tok = &scc_vec_at(*arg_tokens, i);
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 *right) {
scc_str_t new_lex = scc_str_from_cstr("");
if (left != null) {
if (left != nullptr) {
scc_str_append(&new_lex, &left->lexeme);
}
if (right != null) {
if (right != nullptr) {
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_pproc_expand_by_vec(macro_table, &expaned_buffer, &output_vec, false,
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);
}
@@ -186,7 +186,7 @@ static void disable(scc_pproc_expand_t *expand_ctx,
const scc_pproc_macro_t *macro) {
scc_pproc_macro_t *expanded_macro =
scc_pproc_macro_new(&macro->name, macro->type);
if (expanded_macro == null) {
if (expanded_macro == nullptr) {
LOG_FATAL("Out of memory");
}
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,
const scc_pproc_macro_t *macro) {
return scc_pproc_macro_table_get(expand_ctx->expanded_set, &macro->name) !=
null;
nullptr;
}
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_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;
}
@@ -387,12 +387,12 @@ static void concact(scc_pproc_expand_t *ctx, scc_lexer_tok_vec_t *tok_buffer,
scc_lexer_tok_t *left;
if (left_idx < 0) {
left = null;
left = nullptr;
left_idx = 0; // FIXME for free tok_buffer
} else {
left = &scc_vec_at(*tok_buffer, left_idx);
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;
if (right_idx >= (int)scc_vec_size(macro->replaces)) {
right_tok = null;
right_tok = nullptr;
} else {
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_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
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;
if (right_idx >= (int)scc_vec_size(macro->replaces)) {
right = null;
right = nullptr;
} else {
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,
&next_tok.lexeme) == null) {
&next_tok.lexeme) == nullptr) {
scc_lexer_tok_drop(&next_tok);
scc_lexer_gen_number_false(&next_tok);
} 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) ==
SCC_TOK_SUBTYPE_IDENTIFIER) {
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_gen_number_false(&next_tok);
} else {
@@ -649,7 +649,7 @@ void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx) {
scc_pproc_macro_t *macro =
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
tok.type += SCC_TOK_DISABLED;
scc_vec_push(expand_ctx->output, tok);

View File

@@ -83,7 +83,7 @@ cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type,
int defined = 0;
if (tok) {
defined = (scc_pproc_macro_table_get(&pp->macro_table,
&(tok->lexeme)) != null);
&(tok->lexeme)) != nullptr);
}
switch (type) {
case SCC_PP_TOK_IFDEF:

View File

@@ -43,7 +43,7 @@ FOPEN:
}
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)) {
return -1;
}

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));
if (!macro) {
LOG_ERROR("Failed to allocate memory for macro");
return null;
return nullptr;
}
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 *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);
if (old && old != macro) {
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) {
Assert(macros != null);
Assert(macros != nullptr);
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) {
Assert(macros != null);
scc_hashtable_foreach(&macros->table, macro_free, null);
Assert(macros != nullptr);
scc_hashtable_foreach(&macros->table, macro_free, nullptr);
scc_hashtable_drop(&macros->table);
}

View File

@@ -4,7 +4,7 @@
#include <scc_pproc.h>
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};
int ok = 0;
CONTINUE:
@@ -57,7 +57,7 @@ CONTINUE:
// maybe expanded
scc_pproc_macro_t *macro =
scc_pproc_macro_table_get(&pp->macro_table, &tok.lexeme);
if (macro == null) {
if (macro == nullptr) {
scc_ring_next_consume(*stream, *out, 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) {
Assert(pp != null && input != null);
Assert(pp != nullptr && input != nullptr);
pp->org_ring = input;
pp->cur_ring = pp->org_ring;
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) {
if (pp == null)
if (pp == nullptr)
return;
Assert(pp->cur_ring == pp->org_ring);
scc_lexer_drop_ring(pp->org_ring);

View File

@@ -134,5 +134,5 @@ TEST_LIST = {
TEST_LIST_CASE(test_define_double_pos),
TEST_LIST_CASE(test_define_param_pos),
TEST_LIST_CASE(test_define_stringify_pos),
{NULL, NULL},
{nullptr, nullptr},
};

View File

@@ -39,7 +39,7 @@ static cbool process_input(const char *input, scc_str_t *output) {
do { \
scc_str_t output; \
process_input(input, &output); \
assert(output.data != NULL); \
assert(output.data != nullptr); \
TEST_CHECK(strcmp(output.data, expect) == 0); \
TEST_MSG("Expected: %s", expect); \
TEST_MSG("Produced: %s", output.data); \
@@ -50,8 +50,8 @@ static cbool process_input(const char *input, scc_str_t *output) {
do { \
scc_str_t output; \
process_input(input, &output); \
assert(output.data != NULL); \
TEST_CHECK(strstr(output.data, expect) != NULL); \
assert(output.data != nullptr); \
TEST_CHECK(strstr(output.data, expect) != nullptr); \
TEST_MSG("Expected: %s", expect); \
TEST_MSG("Produced: %s", output.data); \
scc_str_drop(&output); \
@@ -649,5 +649,5 @@ TEST_LIST = {
TEST_LIST_CASE(test_real_case),
TEST_LIST_CASE(test_c99_docs),
{NULL, NULL},
{nullptr, nullptr},
};

View File

@@ -25,7 +25,7 @@ static inline sccf_sym_t *
sccf_builder_get_symbol_unsafe(sccf_builder_t *builder, const char *name) {
usize idx = sccf_builder_get_symbol_idx(builder, name);
if (idx == 0) {
return null;
return nullptr;
}
return &scc_vec_at(builder->symtab, idx);
}

View File

@@ -34,12 +34,12 @@ static inline u8 *sccf_sect_header_table(u8 *base) {
* @brief 获取指定索引的节头指针
* @param base 文件缓冲区起始地址
* @param idx 节索引 (0 <= idx < sect_header_num)
* @return 指向该节头的指针, 若索引无效返回 null
* @return 指向该节头的指针, 若索引无效返回 nullptr
*/
static inline sccf_sect_header_t *sccf_sect_header(u8 *base, usize idx) {
sccf_header_t *hdr = (sccf_header_t *)base;
if (idx >= (usize)hdr->sect_header_num)
return null;
return nullptr;
u8 *table = sccf_sect_header_table(base);
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 获取指定索引的节数据起始地址
* @param base 文件缓冲区起始地址
* @param idx 节索引
* @return 数据起始地址, 若索引无效返回 null
* @return 数据起始地址, 若索引无效返回 nullptr
*/
static inline u8 *sccf_sect_data(u8 *base, usize idx) {
usize off = sccf_sect_data_offset(base, idx);
return (off == 0) ? null : base + off;
return (off == 0) ? nullptr : base + off;
}
/** @} */

View File

@@ -14,11 +14,11 @@ void sccf_builder_init(sccf_builder_t *builder) {
scc_vec_init(builder->relocs);
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');
///< Push null
///< Push nullptr
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) {
if (builder->entry_symbol_name == null) {
if (builder->entry_symbol_name == nullptr) {
builder->sccf.header.entry_point = 0;
} else {
sccf_sym_t *sym =
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");
builder->sccf.header.entry_point = 0;
} 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) {
Assert(builder != null && buffer != null);
Assert(builder != nullptr && buffer != nullptr);
sccf_write(sccf_builder_to_sccf(builder), buffer);
}
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);
if (fp == null) {
if (fp == nullptr) {
LOG_ERROR("file can't open %s", file_path);
return;
}

View File

@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
return 1;
}
ring = scc_sstream_ref_ring(&stream);
Assert(ring != null);
Assert(ring != nullptr);
printf("Reading file: %s\n", filename);

View File

@@ -14,8 +14,8 @@ extern logger_t __scc_usr_log;
"%s:%zu:%zu: ", (pos).name, (pos).line, (pos).col); \
scc_snprintf(_full_msg + _n, sizeof(_full_msg) - _n, fmt, \
##__VA_ARGS__); \
__scc_usr_log.handler(&__scc_usr_log, level, null, 0, null, "%s", \
_full_msg); \
__scc_usr_log.handler(&__scc_usr_log, level, nullptr, 0, nullptr, \
"%s", _full_msg); \
} while (0)
#define SCC_DEBUG(pos, fmt, ...) \

View File

@@ -7,7 +7,7 @@ static int user_log_handler(logger_t *module, log_level_t level,
/* clang-format off */
(void) module, (void)file, (void)line, (void)func; // 不再使用
const char *level_str = null;
const char *level_str = nullptr;
switch (level) {
case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break;
case LOG_LEVEL_INFO: level_str = "INFO "; break;

View File

@@ -67,7 +67,7 @@ static int sstream_scan_at(scc_sstream_t *stream, scc_pos_t scan_pos,
// 环形缓冲区填充回调(通过 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;
if (stream->fill_pos.offset >= stream->len)
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) {
Assert(stream != null && fname != null);
Assert(stream != nullptr && fname != nullptr);
scc_file_t file = scc_fopen(fname, SCC_FILE_READ);
if (file == null) {
if (file == nullptr) {
LOG_ERROR("Failed to open file: %s", fname);
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) {
Assert(stream != null);
Assert(stream != nullptr);
stream->used++;
return &stream->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;
if (stream->used > 0) {
stream->used--;
@@ -139,14 +139,14 @@ void scc_sstream_drop_ring(scc_sstream_ring_t *ring) {
}
void scc_sstream_drop(scc_sstream_t *stream) {
Assert(stream != null);
Assert(stream != nullptr);
if (stream->used) {
LOG_FATAL("drop sstream must be drop ring before ref [%d]",
stream->used);
}
if (stream->src && stream->owned_src) {
scc_free((void *)stream->src);
stream->src = null;
stream->src = nullptr;
}
scc_ring_free(stream->ring);
}

View File

@@ -384,7 +384,7 @@ typedef struct _IMAGE_SECTION_HEADER {
// 导入表相关
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD Characteristics; // 0 for terminating nullptr import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT
// (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME;
@@ -680,7 +680,7 @@ typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL;
// 符号存储类
#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_EXTERNAL 0x0002
#define IMAGE_SYM_CLASS_STATIC 0x0003

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,
scc_pe_section_range *range, u8 *data,
usize data_size) {
if (range == null || data == null || data_size == 0) {
if (range == nullptr || data == nullptr || data_size == 0) {
return;
}
padding_util(builder, range->file_offset);

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);
}
// 添加NULL终止的目录项
IMAGE_IMPORT_DESCRIPTOR null_entry = image_import_descriptor_init(0, 0, 0);
// 添加nullptr终止的目录项
IMAGE_IMPORT_DESCRIPTOR nullptr_entry =
image_import_descriptor_init(0, 0, 0);
scc_memcpy(&scc_vec_at(builder->buffer,
import_file_count * sizeof(IMAGE_IMPORT_DESCRIPTOR)),
&null_entry, sizeof(IMAGE_IMPORT_DESCRIPTOR));
&nullptr_entry, sizeof(IMAGE_IMPORT_DESCRIPTOR));
// 填充Hint/Name表
scc_memcpy(&scc_vec_at(builder->buffer, hnt_offset),

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);
const char *fname = scc_str_as_cstr(&fpath);
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);
return;
}
usize fsize = scc_fsize(fp);
char *buffer = scc_malloc(fsize);
Assert(buffer != null);
Assert(buffer != nullptr);
usize read_size = scc_fread(fp, buffer, 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) {
const char *lib_name = scc_hashtable_get(&ctx->str2libsym, name);
if (lib_name == null) {
if (lib_name == nullptr) {
return false;
}
scc_pe_idata_lib_t *lib = null;
scc_pe_idata_lib_t *lib = nullptr;
scc_vec_foreach(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) {
@@ -83,7 +83,7 @@ static cbool pe_idata_get(pe_idata_lib_ctx_t *ctx, const char *name) {
break;
}
}
if (lib == null) {
if (lib == nullptr) {
scc_pe_idata_lib_t new_lib;
new_lib.name = lib_name;
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;
scc_vec_init(symtab);
sccf_sect_data_t *code_data = null;
sccf_sect_data_t *data_data = null;
sccf_sect_data_t *code_data = nullptr;
sccf_sect_data_t *data_data = nullptr;
int num_of_section = 1;
scc_vec_foreach(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();
}
rva -= code_range.virual_address + reloc->offset + reloc->addend;
Assert(code_data != null);
Assert(code_data != nullptr);
// FIXME 需要确保宿主机与目标机器大小端一致
*(u32 *)(scc_vec_unsafe_get_data(*code_data) + reloc->offset) = rva;
}
scc_pe_write_header(builder, &config);
if (code_data != null) {
if (code_data != nullptr) {
scc_pe_write_section(builder, &code_range,
(u8 *)scc_vec_unsafe_get_data(*code_data),
scc_vec_size(*code_data));
}
if (data_data != null) {
if (data_data != nullptr) {
scc_pe_write_section(builder, &data_range,
(u8 *)scc_vec_unsafe_get_data(*data_data),
scc_vec_size(*data_data));

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_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);
if (len == 0) {
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;
}
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.cap = new_cap;
}