#include #include static void type_callback(void *context, scc_ast_node_type_t node_type, void *node) { scc_sema_symtab_t *sema_symtab = context; (void)context; (void)node_type; (void)node; return; } static void decl_callback(void *context, scc_ast_node_type_t node_type, void *node) { if (node_type == SCC_AST_UNKNOWN || node == null) { return; } scc_sema_symtab_t *sema_symtab = context; 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); if (decl->name == null) { return; } if (decl->base.type == SCC_AST_DECL_STRUCT) { scc_ast_type_struct_init(type, decl->name, decl); scc_cstring_t name = scc_cstring_from_cstr("$S_"); scc_cstring_append_cstr(&name, decl->name, scc_strlen(decl->name)); scc_sema_symtab_add_symbol(sema_symtab, scc_cstring_as_cstr(&name), &type->base); } else if (decl->base.type == SCC_AST_DECL_UNION) { scc_ast_type_union_init(type, decl->name, decl); scc_cstring_t name = scc_cstring_from_cstr("$U_"); scc_cstring_append_cstr(&name, decl->name, scc_strlen(decl->name)); scc_sema_symtab_add_symbol(sema_symtab, scc_cstring_as_cstr(&name), &type->base); } else if (decl->base.type == SCC_AST_DECL_ENUM) { scc_ast_type_enum_init(type, decl->name, decl); scc_cstring_t name = scc_cstring_from_cstr("$E_"); scc_cstring_append_cstr(&name, decl->name, scc_strlen(decl->name)); scc_sema_symtab_add_symbol(sema_symtab, scc_cstring_as_cstr(&name), &type->base); } else if (decl->base.type == SCC_AST_DECL_TYPEDEF) { scc_ast_type_typedef_init(type, decl->name, decl); scc_sema_symtab_add_symbol(sema_symtab, decl->name, &type->base); } return; } static scc_ast_type_t *got_type_callback(void *context, const char *name) { scc_sema_symtab_t *sema_symtab = context; scc_ast_node_t *node = scc_sema_symtab_lookup_symbol(sema_symtab, name); if (SCC_AST_IS_A(scc_ast_type_t, node)) { scc_ast_type_t *type = scc_malloc(sizeof(scc_ast_type_t)); *type = *(scc_ast_type_t *)node; return type; } return null; } 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) { LOG_FATAL("out of memory"); return; } callbacks->context = sema_symtab; callbacks->on_decl = decl_callback; callbacks->on_expr = null; callbacks->on_stmt = null; callbacks->on_type = type_callback; callbacks->got_type = got_type_callback; scc_sema_symtab_init(sema_symtab); scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_list", &scc_ast_builtin_type_va_list.base); scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_size_t", &scc_ast_builtin_type_long_long.base); scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_ptrdiff_t", &scc_ast_builtin_type_long_long.base); } void scc_sema_drop(scc_sema_callbacks_t *callbacks) {}