From: yu.dongliang <18588496441@163.com> Date: Thu, 16 Jul 2026 07:36:28 +0000 (+0800) Subject: support 'typedef' for 'struct, union, array & function pointer' X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=0aba129da9ebbe06298c5896674239488f91156a;p=scf.git support 'typedef' for 'struct, union, array & function pointer' --- diff --git a/core/scf_ast.c b/core/scf_ast.c index 1dc0fa4..bad662e 100644 --- a/core/scf_ast.c +++ b/core/scf_ast.c @@ -202,6 +202,35 @@ static int _find_var_by_name(scf_node_t* node, void* arg, scf_vector_t* vec) return 0; } +static int _find_typedef_by_name(scf_node_t* node, void* arg, scf_vector_t* vec) +{ + if (SCF_FUNCTION == node->type) + return 1; + + if (node->class_flag) + return 1; + + if (SCF_OP_BLOCK == node->type) { + + scf_block_t* b = (scf_block_t*)node; + + if (!b->scope) + return 0; + + scf_variable_t* v = scf_scope_find_typedef(b->scope, arg); + if (!v) + return 0; + + assert(!v->local_flag && !v->member_flag); + + if (v->static_flag) + return 0; + + return scf_vector_add(vec, v); + } + return 0; +} + int scf_ast_find_global_function(scf_function_t** pf, scf_ast_t* ast, char* fname) { scf_vector_t* vec = scf_vector_alloc(); @@ -300,6 +329,55 @@ int scf_ast_find_global_variable(scf_variable_t** pv, scf_ast_t* ast, char* name return 0; } +int scf_ast_find_global_typedef(scf_variable_t** pv, scf_ast_t* ast, char* name) +{ + scf_vector_t* vec = scf_vector_alloc(); + if (!vec) + return -ENOMEM; + + int ret = scf_node_search_bfs((scf_node_t*)ast->root_block, name, vec, -1, _find_type_by_name); + if (ret < 0) { + scf_vector_free(vec); + return ret; + } + + if (0 == vec->size) { + *pv = NULL; + scf_vector_free(vec); + return 0; + } + + scf_variable_t* v2 = vec->data[0]; + scf_variable_t* v; + int n = 0; + int i; + for (i = 0; i < vec->size; i++) { + v = vec->data[i]; + + if (!v->extern_flag) { + v2 = v; + n++; + } + } + + if (n > 1) { + for (i = 0; i < vec->size; i++) { + v = vec->data[i]; + + if (!v->extern_flag) + scf_loge("multi-define: '%s' in file: %s, line: %d\n", name, v->w->file->data, v->w->line); + } + + scf_vector_free(vec); + return -1; + } + + *pv = v2; + + scf_vector_free(vec); + return 0; +} + static int _type_check(scf_type_t** pt, scf_vector_t* vec) { scf_type_t* t2 = vec->data[0]; @@ -394,6 +472,15 @@ int scf_ast_find_variable(scf_variable_t** pv, scf_ast_t* ast, char* name) return scf_ast_find_global_variable(pv, ast, name); } +int scf_ast_find_typedef(scf_variable_t** pv, scf_ast_t* ast, char* name) +{ + *pv = scf_block_find_typedef(ast->current_block, name); + if (*pv) + return 0; + + return scf_ast_find_global_typedef(pv, ast, name); +} + int scf_ast_find_type(scf_type_t** pt, scf_ast_t* ast, char* name) { *pt = scf_block_find_type(ast->current_block, name); diff --git a/core/scf_ast.h b/core/scf_ast.h index 55da0d1..8657eb9 100644 --- a/core/scf_ast.h +++ b/core/scf_ast.h @@ -59,11 +59,15 @@ scf_string_t* scf_variable_type_name(scf_ast_t* ast, scf_variable_t* v); int scf_ast_find_proper_function (scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv); int scf_ast_find_global_function (scf_function_t** pf, scf_ast_t* ast, char* name); int scf_ast_find_global_variable (scf_variable_t** pv, scf_ast_t* ast, char* name); + +int scf_ast_find_global_typedef (scf_variable_t** pv, scf_ast_t* ast, char* name); int scf_ast_find_global_type (scf_type_t** pt, scf_ast_t* ast, char* name); int scf_ast_find_global_type_type(scf_type_t** pt, scf_ast_t* ast, int type); int scf_ast_find_function (scf_function_t** pf, scf_ast_t* ast, char* name); int scf_ast_find_variable (scf_variable_t** pv, scf_ast_t* ast, char* name); + +int scf_ast_find_typedef (scf_variable_t** pv, scf_ast_t* ast, char* name); int scf_ast_find_type (scf_type_t** pt, scf_ast_t* ast, char* name); int scf_ast_find_type_type(scf_type_t** pt, scf_ast_t* ast, int type); diff --git a/core/scf_block.c b/core/scf_block.c index 3691b63..c41d3d2 100644 --- a/core/scf_block.c +++ b/core/scf_block.c @@ -100,6 +100,23 @@ scf_type_t* scf_block_find_type_type(scf_block_t* b, const int type) return NULL; } +scf_variable_t* scf_block_find_typedef(scf_block_t* b, const char* name) +{ + assert(b); + while (b) { + if (SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type || b->node.type >= SCF_STRUCT) { + + if (b->scope) { + scf_variable_t* v = scf_scope_find_typedef(b->scope, name); + if (v) + return v; + } + } + b = (scf_block_t*)(b->node.parent); + } + return NULL; +} + scf_variable_t* scf_block_find_variable(scf_block_t* b, const char* name) { assert(b); diff --git a/core/scf_block.h b/core/scf_block.h index 30d3fd0..41ae89f 100644 --- a/core/scf_block.h +++ b/core/scf_block.h @@ -14,20 +14,20 @@ struct scf_block_s { }; -scf_block_t* scf_block_alloc(scf_lex_word_t* w); +scf_block_t* scf_block_alloc(scf_lex_word_t* w); -scf_block_t* scf_block_alloc_cstr(const char* name); +scf_block_t* scf_block_alloc_cstr(const char* name); -void scf_block_free(scf_block_t* b); +void scf_block_free(scf_block_t* b); -scf_type_t* scf_block_find_type(scf_block_t* b, const char* name); +scf_type_t* scf_block_find_type (scf_block_t* b, const char* name); +scf_type_t* scf_block_find_type_type(scf_block_t* b, const int type); +scf_variable_t* scf_block_find_typedef (scf_block_t* b, const char* name); -scf_type_t* scf_block_find_type_type(scf_block_t* b, const int type); +scf_variable_t* scf_block_find_variable(scf_block_t* b, const char* name); -scf_variable_t* scf_block_find_variable(scf_block_t* b, const char* name); +scf_function_t* scf_block_find_function(scf_block_t* b, const char* name); -scf_function_t* scf_block_find_function(scf_block_t* b, const char* name); - -scf_label_t* scf_block_find_label(scf_block_t* b, const char* name); +scf_label_t* scf_block_find_label(scf_block_t* b, const char* name); #endif diff --git a/core/scf_function.h b/core/scf_function.h index 08b7818..a655887 100644 --- a/core/scf_function.h +++ b/core/scf_function.h @@ -10,6 +10,8 @@ struct scf_function_s { scf_string_t* signature; + scf_vector_t* typedef_vars; + scf_list_t list; // for scope scf_vector_t* rets; // return values diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index 15dfb57..71f0edc 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -170,7 +170,6 @@ enum scf_lex_words SCF_LEX_WORD_KEY_VA_START, // va_start SCF_LEX_WORD_KEY_VA_END, // va_end - // class SCF_LEX_WORD_KEY_CLASS, // class SCF_LEX_WORD_KEY_TYPEDEF, // typedef diff --git a/core/scf_scope.c b/core/scf_scope.c index 732b59e..07bb36f 100644 --- a/core/scf_scope.c +++ b/core/scf_scope.c @@ -12,6 +12,13 @@ scf_scope_t* scf_scope_alloc() return NULL; } + scope->typedef_vars = scf_vector_alloc(); + if (!scope->typedef_vars) { + scf_vector_free(scope->vars); + free(scope); + return NULL; + } + scf_list_init(&scope->list); scf_list_init(&scope->types); scf_list_init(&scope->operators); @@ -20,7 +27,7 @@ scf_scope_t* scf_scope_alloc() return scope; } -void scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var) +int scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var) { scf_vector_add(scope->vars, var); } @@ -87,6 +94,20 @@ scf_type_t* scf_scope_find_type_type(scf_scope_t* scope, const int type) return NULL; } +scf_variable_t* scf_scope_find_typedef(scf_scope_t* scope, const char* name) +{ + scf_variable_t* v; + int i; + + for (i = 0; i < scope->typedef_vars->size; i++) { + v = scope->typedef_vars->data[i]; + + if (v->w && !strcmp(name, v->w->text->data)) + return v; + } + return NULL; +} + scf_variable_t* scf_scope_find_variable(scf_scope_t* scope, const char* name) { scf_variable_t* v; diff --git a/core/scf_scope.h b/core/scf_scope.h index ac823f1..288c043 100644 --- a/core/scf_scope.h +++ b/core/scf_scope.h @@ -10,17 +10,19 @@ struct scf_scope_s { scf_list_t list; // scope list - scf_vector_t* vars; // vars in this scope, should not have the same name - scf_list_t types; // type list in this scope, not define the same type - scf_list_t operators; // operator list in this scope - scf_list_t functions; // function list in this scope - scf_list_t labels; // label list in this scope + scf_vector_t* vars; // vars in this scope, should not have the same name + scf_list_t types; // type list in this scope, not define the same type + scf_list_t operators; // operator list in this scope + scf_list_t functions; // function list in this scope + scf_list_t labels; // label list in this scope + + scf_vector_t* typedef_vars; // typedef vars for type alias name }; scf_scope_t* scf_scope_alloc(); void scf_scope_free(scf_scope_t* scope); -void scf_scope_push_var (scf_scope_t* scope, scf_variable_t* var); +int scf_scope_push_var (scf_scope_t* scope, scf_variable_t* var); void scf_scope_push_type(scf_scope_t* scope, scf_type_t* t); void scf_scope_push_operator(scf_scope_t* scope, scf_function_t* op); @@ -28,6 +30,7 @@ void scf_scope_push_function(scf_scope_t* scope, scf_function_t* f); scf_type_t* scf_scope_find_type (scf_scope_t* scope, const char* name); scf_type_t* scf_scope_find_type_type(scf_scope_t* scope, const int type); +scf_variable_t* scf_scope_find_typedef (scf_scope_t* scope, const char* name); scf_variable_t* scf_scope_find_variable (scf_scope_t* scope, const char* name); scf_function_t* scf_scope_find_function (scf_scope_t* scope, const char* name); diff --git a/core/scf_type.h b/core/scf_type.h index 3ece46b..5f2b702 100644 --- a/core/scf_type.h +++ b/core/scf_type.h @@ -21,6 +21,8 @@ struct scf_type_s scf_scope_t* scope; scf_string_t* name; + scf_vector_t* typedef_vars; + // list for scope's type_list_head scf_list_t list; diff --git a/core/scf_variable.h b/core/scf_variable.h index 9880670..aa501f5 100644 --- a/core/scf_variable.h +++ b/core/scf_variable.h @@ -60,6 +60,7 @@ struct scf_variable_s { uint32_t static_flag :1; uint32_t extern_flag :1; uint32_t extra_flag :1; + uint32_t typedef_flag:1; uint32_t tmp_flag :1; uint32_t local_flag :1; diff --git a/examples/c_func_ptr_array.c b/examples/c_func_ptr_array.c new file mode 100644 index 0000000..cc1441f --- /dev/null +++ b/examples/c_func_ptr_array.c @@ -0,0 +1,11 @@ +int printf(const char* fmt, ...); + +typedef int (*pf_t[2])(const char* fmt, ...); + +int main() +{ + pf_t pf = {printf, printf}; + + pf[0]("hello world\n"); + return 0; +} diff --git a/examples/struct_only_declare.c b/examples/struct_only_declare.c new file mode 100644 index 0000000..9c0bf5a --- /dev/null +++ b/examples/struct_only_declare.c @@ -0,0 +1,11 @@ +int printf(const char* fmt, ...); + +struct a_s; + +int main() +{ + a_s* p = NULL; + + printf("a_s* p: %p\n", p); + return 0; +} diff --git a/examples/typedef.c b/examples/typedef.c new file mode 100644 index 0000000..a993299 --- /dev/null +++ b/examples/typedef.c @@ -0,0 +1,21 @@ +int printf(const char* fmt, ...); + +typedef struct a_s { + int x; +} a_t, *a_p; + +typedef a_t a2_t[2]; + +typedef int* intptr; + +int main() +{ + a2_t a = {{1}, {2}}; + a_p p = &a[1]; + + int i = 3; + intptr pi = &i; + + printf("typedef p: %p, p->x: %d, pi: %p, *pi: %d\n", p, p->x, pi, *pi); + return 0; +} diff --git a/examples/typedef_func_ptr.c b/examples/typedef_func_ptr.c new file mode 100644 index 0000000..f701a67 --- /dev/null +++ b/examples/typedef_func_ptr.c @@ -0,0 +1,16 @@ +int printf(const char* fmt, ...); + +typedef int (*add_pt)(int a, int b); + +int add(int a, int b) +{ + return a + b; +} + +int main() +{ + add_pt f = add; + + printf("typedef f: %p, f(1, 2): %d\n", f, f(1, 2)); + return 0; +} diff --git a/native/x64/scf_x64_peephole.c b/native/x64/scf_x64_peephole.c index 8c90a38..e4e41a8 100644 --- a/native/x64/scf_x64_peephole.c +++ b/native/x64/scf_x64_peephole.c @@ -193,6 +193,8 @@ static int _x64_peephole_mov(scf_vector_t* save_insts, scf_vector_t* peep_insts, if (x64_inst_data_is_reg(&inst->dst)) __x64_peep_mov_by_lea(inst, std); + + std->nb_used++; break; } else if (scf_inst_data_same(&std->src, &inst->src)) diff --git a/parse/scf_dfa_class.c b/parse/scf_dfa_class.c index a3764d2..f6cd515 100644 --- a/parse/scf_dfa_class.c +++ b/parse/scf_dfa_class.c @@ -10,16 +10,10 @@ typedef struct { int nb_lbs; int nb_rbs; -} dfa_class_data_t; -static int _class_is_class(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; + uint8_t typedef_flag:1; +} dfa_class_data_t; - return SCF_LEX_WORD_KEY_CLASS == w->type - || SCF_LEX_WORD_KEY_STRUCT == w->type - || SCF_LEX_WORD_KEY_UNION == w->type; -} static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) { @@ -33,6 +27,15 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_stack_t* s = d->module_datas[dfa_module_class.index]; scf_type_t* t = NULL; + while (d->current_identities->size > 0) { + + dfa_identity_t* id = scf_stack_pop(d->current_identities); + if (id) { + free(id); + id = NULL; + } + } + if (SCF_LEX_WORD_ID == key->type) { t = scf_block_find_type(ast->current_block, key->text->data); @@ -42,6 +45,9 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; ast->nb_structs++; + + scf_scope_push_type(ast->current_block->scope, t); + scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t); } assert(words->size >= 3); @@ -58,14 +64,15 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) ast->nb_structs++; + scf_scope_push_type(ast->current_block->scope, t); + scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t); + t->node.anon_flag = 1; } if (!t->scope) t->scope = scf_scope_alloc(); - scf_scope_push_type(ast->current_block->scope, t); - switch (key->type) { case SCF_LEX_WORD_KEY_STRUCT: @@ -76,13 +83,13 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) case SCF_LEX_WORD_KEY_UNION: t->node.union_flag = 1; break; + default: + scf_loge("key word '%s' NOT support, file: %s, line: %d\n", key->text->data, key->file->data, key->line); return SCF_DFA_ERROR; break; }; - scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t); - dfa_class_data_t* cd = calloc(1, sizeof(dfa_class_data_t)); if (!cd) return -ENOMEM; @@ -97,6 +104,9 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) cd->current_type = t; cd->nb_lbs++; + cd->typedef_flag = d->typedef_flag; + d ->typedef_flag = 0; + ast->current_block = (scf_block_t*)t; SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END); @@ -367,6 +377,9 @@ static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) dfa->ops->push_word(dfa, w); + d ->typedef_flag = cd->typedef_flag; + cd->typedef_flag = 0; + } else if (SCF_LEX_WORD_SEMICOLON == w->type && s->size > 1 && cd->current_type->node.anon_flag) { @@ -416,8 +429,63 @@ static int _class_action_var(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_NEXT_WORD; } +int __class_add_type(scf_ast_t* ast, scf_lex_word_t* key, scf_lex_word_t* name) +{ + if (SCF_LEX_WORD_ID == name->type + && (SCF_LEX_WORD_KEY_STRUCT == key->type + || SCF_LEX_WORD_KEY_UNION == key->type + || SCF_LEX_WORD_KEY_CLASS == key->type)) { + + scf_type_t* t = scf_block_find_type(ast->current_block, name->text->data); + if (t) + return SCF_DFA_OK; + + t = scf_type_alloc(name, name->text->data, SCF_STRUCT + ast->nb_structs, 0); + if (!t) + return SCF_DFA_ERROR; + + switch (key->type) + { + case SCF_LEX_WORD_KEY_STRUCT: + case SCF_LEX_WORD_KEY_CLASS: + t->node.class_flag = 1; + break; + + case SCF_LEX_WORD_KEY_UNION: + t->node.union_flag = 1; + break; + default: + scf_loge("key word '%s' NOT support, file: %s, line: %d\n", key->text->data, key->file->data, key->line); + + scf_type_free(t); + t = NULL; + return SCF_DFA_ERROR; + break; + }; + + ast->nb_structs++; + + scf_scope_push_type(ast->current_block->scope, t); + scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t); + } + + return SCF_DFA_OK; +} + static int _class_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data) { + scf_parse_t* parse = dfa->priv; + scf_ast_t* ast = parse->ast; + scf_lex_word_t* name; + scf_lex_word_t* key; + + if (words->size >= 3) { + name = words->data[words->size - 2]; + key = words->data[words->size - 3]; + + return __class_add_type(ast, key, name); + } + return SCF_DFA_OK; } @@ -443,9 +511,6 @@ static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _dfa_init_module_class(scf_dfa_t* dfa) { - SCF_DFA_MODULE_NODE(dfa, class, _class, _class_is_class, NULL); - - SCF_DFA_MODULE_NODE(dfa, class, identity, scf_dfa_is_identity, NULL); SCF_DFA_MODULE_NODE(dfa, class, lb, scf_dfa_is_lb, _class_action_lb); SCF_DFA_MODULE_NODE(dfa, class, rb, scf_dfa_is_rb, _class_action_rb); SCF_DFA_MODULE_NODE(dfa, class, semicolon, scf_dfa_is_semicolon, _class_action_semicolon); @@ -486,8 +551,6 @@ static int _dfa_fini_module_class(scf_dfa_t* dfa) static int _dfa_init_syntax_class(scf_dfa_t* dfa) { - SCF_DFA_GET_MODULE_NODE(dfa, class, _class, _class); - SCF_DFA_GET_MODULE_NODE(dfa, class, identity, type_name); SCF_DFA_GET_MODULE_NODE(dfa, class, lb, lb); SCF_DFA_GET_MODULE_NODE(dfa, class, rb, rb); SCF_DFA_GET_MODULE_NODE(dfa, class, end, end); @@ -497,16 +560,7 @@ static int _dfa_init_syntax_class(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, type, entry, member); - scf_vector_add(dfa->syntaxes, _class); - - // class start - scf_dfa_node_add_child(_class, type_name); - - scf_dfa_node_add_child(type_name, semicolon); - scf_dfa_node_add_child(type_name, lb); - - // anonymous class - scf_dfa_node_add_child(_class, lb); + // class start define in scf_dfa_type.c // empty class scf_dfa_node_add_child(lb, rb); diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 78f6d38..3213c09 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -93,7 +93,7 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) return SCF_DFA_ERROR; if (!var) { - scf_logw("var '%s' not found, maybe it's a function\n", w->text->data); + scf_logw("var '%s' not found, it may be a function\n", w->text->data); if (scf_ast_find_type_type(&pt, parse->ast, SCF_FUNCTION_PTR) < 0) return SCF_DFA_ERROR; @@ -103,8 +103,8 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) return SCF_DFA_ERROR; if (!f) { - scf_loge("function '%s' not found\n", w->text->data); - return SCF_DFA_ERROR; + scf_logw("function '%s' not found, it may be a struct\n", w->text->data); + return SCF_DFA_NEXT_SYNTAX; } var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f); @@ -154,14 +154,10 @@ static int _expr_action_expr(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (!d->expr) { d->expr = scf_expr_alloc(); - if (!d->expr) { - scf_loge("expr alloc failed\n"); + if (!d->expr) return SCF_DFA_ERROR; - } } - scf_logd("d->expr: %p\n", d->expr); - return words->size > 0 ? SCF_DFA_CONTINUE : SCF_DFA_NEXT_WORD; } @@ -724,8 +720,11 @@ int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag) dfa_identity_t* id = scf_stack_top(d->current_identities); if (id && id->identity) { - if (_expr_add_var(parse, d) < 0) - return SCF_DFA_ERROR; + + int ret = _expr_add_var(parse, d); + + if (SCF_DFA_OK != ret) + return ret; } if (md->parent_block) { @@ -777,20 +776,23 @@ static int _expr_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_parse_t* parse = dfa->priv; dfa_data_t* d = data; - if (_expr_fini_expr(parse, d, 0) < 0) - return SCF_DFA_ERROR; + int ret = _expr_fini_expr(parse, d, 0); + + if (SCF_DFA_OK != ret) + return ret; return SCF_DFA_NEXT_WORD; } static int _expr_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - scf_parse_t* parse = dfa->priv; - dfa_data_t* d = data; - expr_module_data_t* md = d->module_datas[dfa_module_expr.index]; + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; - if (_expr_fini_expr(parse, d, 1) < 0) - return SCF_DFA_ERROR; + int ret = _expr_fini_expr(parse, d, 1); + + if (SCF_DFA_OK != ret) + return ret; return SCF_DFA_OK; } diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 40b293d..e6b472e 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -5,35 +5,43 @@ extern scf_dfa_module_t dfa_module_function; typedef struct { - scf_block_t* parent_block; - int pf_pointers; + scf_variable_t* v_pf; + int pf_lps; int pf_rps; } dfa_fun_data_t; int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) { - if (d->current_identities->size < 2) { - scf_loge("d->current_identities->size: %d\n", d->current_identities->size); - return SCF_DFA_ERROR; - } - scf_parse_t* parse = dfa->priv; scf_ast_t* ast = parse->ast; - dfa_identity_t* id = scf_stack_pop(d->current_identities); + dfa_identity_t* id = NULL; dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; + scf_lex_word_t* name = NULL; + dfa_identity_t* id0; scf_variable_t* v_pf = NULL; scf_function_t* f; scf_variable_t* v; scf_block_t* b; scf_type_t* t; - if (!id || !id->identity) { - scf_loge("function identity not found\n"); - return SCF_DFA_ERROR; + if (d->current_var) { + name = scf_lex_word_clone(d->current_var->w); + if (!name) + return -ENOMEM; + + } else { + id = scf_stack_pop(d->current_identities); + + if (!id || !id->identity) { + scf_loge("function identity not found\n"); + return SCF_DFA_ERROR; + } + + name = id->identity; } uint32_t local_flag = 0; @@ -65,41 +73,64 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) assert(global_flag || local_flag || member_flag); - if (fd->pf_pointers > 0) { + if (d->pf_pointers > 0) { t = NULL; - int pf_pointers = fd->pf_pointers; + int ret; + int pf_pointers = d->pf_pointers; - fd->pf_pointers = 0; + d->pf_pointers = 0; - int ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR); - if (ret < 0) - return ret; + if (!d->current_var) { + ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR); + if (ret < 0) + return ret; - v_pf = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, 0, pf_pointers, NULL); - if (!v_pf) - return -ENOMEM; + v_pf = SCF_VAR_ALLOC_BY_TYPE(name, t, 0, pf_pointers, NULL); + if (!v_pf) + return -ENOMEM; + + v_pf->local_flag = local_flag; + v_pf->global_flag = global_flag; + v_pf->member_flag = member_flag; + } else + v_pf = d->current_var; + + assert(d->current_identities->size > 0); + id0 = d->current_identities->data[0]; + + if (id0->typedef_flag) { + id0->typedef_flag = 0; - scf_scope_push_var(ast->current_block->scope, v_pf); + v_pf->typedef_flag = 1; + + ret = scf_vector_add(ast->current_block->scope->typedef_vars, v_pf); + } else + ret = scf_scope_push_var(ast->current_block->scope, v_pf); + + if (ret < 0) { + scf_variable_free(v_pf); + return ret; + } - ret = scf_string_cat_cstr(id->identity->text, "_pt"); + ret = scf_string_cat_cstr(name->text, "__"); if (ret < 0) return ret; - v_pf->local_flag = local_flag; - v_pf->global_flag = global_flag; - v_pf->member_flag = member_flag; + fd->v_pf = v_pf; } - f = scf_function_alloc(id->identity); + f = scf_function_alloc(name); if (!f) return SCF_DFA_ERROR; f->member_flag = member_flag; - free(id); - id = NULL; + if (id) { + free(id); + id = NULL; + } - scf_logi("function: %s,line:%d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag); + scf_logi("function: %s(), line: %d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag); int void_flag = 0; @@ -300,7 +331,7 @@ static int _function_action_pf_star(scf_dfa_t* dfa, scf_vector_t* words, void* d dfa_data_t* d = data; dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; - fd->pf_pointers++; + d->pf_pointers++; return SCF_DFA_NEXT_WORD; } @@ -330,7 +361,7 @@ static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* dat fd->pf_lps = 0; if (id && id->identity) - scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, fd->pf_pointers); + scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, d->pf_pointers); } else { SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE); } @@ -346,11 +377,14 @@ static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) assert(!d->current_node); - d->current_var = NULL; + if (d->pf_pointers <= 0) + d->current_var = NULL; if (_function_add_function(dfa, d) < 0) return SCF_DFA_ERROR; + d->current_var = NULL; + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_rp"), SCF_DFA_HOOK_PRE); SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_comma"), SCF_DFA_HOOK_PRE); @@ -568,6 +602,10 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, type, identity, identity); SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block); + SCF_DFA_GET_MODULE_NODE(dfa, var, ls, ls); + SCF_DFA_GET_MODULE_NODE(dfa, var, rs, rs); + SCF_DFA_GET_MODULE_NODE(dfa, var, assign, assign); + // function pointer scf_dfa_node_add_child(base_type, pf_lp); scf_dfa_node_add_child(type_name, pf_lp); @@ -577,6 +615,10 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa) scf_dfa_node_add_child(pf_star, identity); scf_dfa_node_add_child(identity, pf_rp); + scf_dfa_node_add_child(identity, ls); + scf_dfa_node_add_child(identity, assign); + scf_dfa_node_add_child(rs, pf_rp); + scf_dfa_node_add_child(pf_star, pf_star); scf_dfa_node_add_child(pf_lp, pf_lp); scf_dfa_node_add_child(pf_rp, pf_rp); diff --git a/parse/scf_dfa_type.c b/parse/scf_dfa_type.c index d2752f3..fca7f19 100644 --- a/parse/scf_dfa_type.c +++ b/parse/scf_dfa_type.c @@ -4,6 +4,8 @@ extern scf_dfa_module_t dfa_module_type; +int __class_add_type(scf_ast_t* ast, scf_lex_word_t* key, scf_lex_word_t* name); + static int _type_is__struct(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; @@ -13,6 +15,15 @@ static int _type_is__struct(scf_dfa_t* dfa, void* word) || SCF_LEX_WORD_KEY_UNION == w->type; } +static int _type_action_typedef(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_data_t* d = data; + + d->typedef_flag = 1; + + return SCF_DFA_NEXT_WORD; +} + static int _type_action_const(scf_dfa_t* dfa, scf_vector_t* words, void* data) { dfa_data_t* d = data; @@ -73,17 +84,19 @@ static int _type_action_base_type(scf_dfa_t* dfa, scf_vector_t* words, void* dat return SCF_DFA_ERROR; } - id->type_w = w; + id->type_w = w; - id->const_flag = d->const_flag; - id->static_flag = d->static_flag; - id->extern_flag = d->extern_flag; - id->inline_flag = d->inline_flag; + id->const_flag = d->const_flag; + id->static_flag = d->static_flag; + id->extern_flag = d->extern_flag; + id->inline_flag = d->inline_flag; + id->typedef_flag = d->typedef_flag; - d ->const_flag = 0; - d ->static_flag = 0; - d ->extern_flag = 0; - d ->inline_flag = 0; + d->const_flag = 0; + d->static_flag = 0; + d->extern_flag = 0; + d->inline_flag = 0; + d->typedef_flag = 0; return SCF_DFA_NEXT_WORD; } @@ -115,16 +128,28 @@ int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id) if (!id->identity) return 0; - id->type = scf_block_find_type(parse->ast->current_block, id->identity->text->data); - if (!id->type) { + int ret = scf_ast_find_type(&id->type, parse->ast, id->identity->text->data); + if (ret < 0) + return SCF_DFA_ERROR; - int ret = scf_ast_find_global_type(&id->type, parse->ast, id->identity->text->data); - if (ret < 0) { - scf_loge("find global function error\n"); + if (!id->type) { + ret = scf_ast_find_typedef(&id->type_def, parse->ast, id->identity->text->data); + if (ret < 0) return SCF_DFA_ERROR; - } - if (!id->type) { + if (id->type_def) { + scf_logw("find typedef '%s'\n", id->identity->text->data); + + ret = scf_ast_find_type_type(&id->type, parse->ast, id->type_def->type); + if (ret < 0) + return SCF_DFA_ERROR; + + id->func_ptr = id->type_def->func_ptr; + + assert(id->type); + } else { + scf_logw("can't find type '%s', it may be an function ptr\n", id->identity->text->data); + id->type = scf_block_find_type_type(parse->ast->current_block, SCF_FUNCTION_PTR); if (!id->type) { @@ -133,7 +158,7 @@ int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id) } } - if (SCF_FUNCTION_PTR == id->type->node.type) { + if (SCF_FUNCTION_PTR == id->type->node.type && !id->type_def) { id->func_ptr = _type_find_function(parse->ast->current_block, id->identity->text->data); @@ -155,19 +180,47 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data scf_lex_word_t* w = words->data[words->size - 1]; dfa_data_t* d = data; scf_stack_t* s = d->current_identities; + dfa_identity_t* type = NULL; dfa_identity_t* id = NULL; + int ret; if (s->size > 0) { - id = scf_stack_top(s); + type = scf_stack_top(s); - int ret = _type_find_type(dfa, id); + if (d->typedef_flag) { + + if (words->size < 3) { + scf_loge("\n"); + return SCF_DFA_ERROR; + } + + scf_lex_word_t* name = words->data[words->size - 2]; + scf_lex_word_t* key = words->data[words->size - 3]; + + if (SCF_LEX_WORD_KEY_STRUCT == key->type + || SCF_LEX_WORD_KEY_UNION == key->type + || SCF_LEX_WORD_KEY_CLASS == key->type) { + + ret = __class_add_type(parse->ast, key, name); + if (ret < 0) + return ret; + } + } + + ret = _type_find_type(dfa, type); if (ret < 0) { scf_loge("\n"); return ret; } + + if (d->typedef_flag) { + type->typedef_flag = d->typedef_flag; + + d->typedef_flag = 0; + } } - id = calloc(1, sizeof(dfa_identity_t)); + id = calloc(1, sizeof(dfa_identity_t)); if (!id) return SCF_DFA_ERROR; @@ -175,6 +228,7 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data free(id); return SCF_DFA_ERROR; } + id->identity = w; return SCF_DFA_NEXT_WORD; @@ -224,6 +278,7 @@ static int _dfa_init_module_type(scf_dfa_t* dfa) SCF_DFA_MODULE_NODE(dfa, type, _struct, _type_is__struct, NULL); + SCF_DFA_MODULE_NODE(dfa, type, _typedef, scf_dfa_is_typedef, _type_action_typedef); SCF_DFA_MODULE_NODE(dfa, type, _const, scf_dfa_is_const, _type_action_const); SCF_DFA_MODULE_NODE(dfa, type, _static, scf_dfa_is_static, _type_action_static); SCF_DFA_MODULE_NODE(dfa, type, _extern, scf_dfa_is_extern, _type_action_extern); @@ -241,6 +296,7 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa) { SCF_DFA_GET_MODULE_NODE(dfa, type, entry, entry); + SCF_DFA_GET_MODULE_NODE(dfa, type, _typedef, _typedef); SCF_DFA_GET_MODULE_NODE(dfa, type, _const, _const); SCF_DFA_GET_MODULE_NODE(dfa, type, _static, _static); SCF_DFA_GET_MODULE_NODE(dfa, type, _extern, _extern); @@ -254,9 +310,13 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, identity, identity, type_name); + SCF_DFA_GET_MODULE_NODE(dfa, class, lb, class_lb); + SCF_DFA_GET_MODULE_NODE(dfa, class, semicolon, class_semicolon); + scf_vector_add(dfa->syntaxes, entry); + scf_dfa_node_add_child(entry, _typedef); scf_dfa_node_add_child(entry, _static); scf_dfa_node_add_child(entry, _extern); scf_dfa_node_add_child(entry, _const); @@ -266,6 +326,11 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa) scf_dfa_node_add_child(entry, base_type); scf_dfa_node_add_child(entry, type_name); + scf_dfa_node_add_child(_typedef, _const); + scf_dfa_node_add_child(_typedef, _struct); + scf_dfa_node_add_child(_typedef, base_type); + scf_dfa_node_add_child(_typedef, type_name); + scf_dfa_node_add_child(_static, _struct); scf_dfa_node_add_child(_static, base_type); scf_dfa_node_add_child(_static, type_name); @@ -287,7 +352,11 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa) scf_dfa_node_add_child(_extern, _const); scf_dfa_node_add_child(_inline, _const); + // struct / union / class scf_dfa_node_add_child(_struct, type_name); + scf_dfa_node_add_child(type_name, class_semicolon); // only declare + scf_dfa_node_add_child(type_name, class_lb); // define + scf_dfa_node_add_child(_struct, class_lb); // define anonymous // multi-pointer scf_dfa_node_add_child(star, star); diff --git a/parse/scf_dfa_var.c b/parse/scf_dfa_var.c index c626f56..63f5008 100644 --- a/parse/scf_dfa_var.c +++ b/parse/scf_dfa_var.c @@ -43,11 +43,15 @@ int _check_recursive(scf_type_t* parent, scf_type_t* child, scf_lex_word_t* w) static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) { scf_parse_t* parse = dfa->priv; + scf_ast_t* ast = parse->ast; dfa_identity_t* id = scf_stack_top(d->current_identities); + dfa_identity_t* id0 = NULL; + scf_variable_t* v = NULL; + scf_type_t* t = NULL; if (id && id->identity) { - scf_variable_t* v = scf_scope_find_variable(parse->ast->current_block->scope, id->identity->text->data); + v = scf_scope_find_variable(ast->current_block->scope, id->identity->text->data); if (v) { scf_loge("repeated declare var '%s', line: %d\n", id->identity->text->data, id->identity->line); return SCF_DFA_ERROR; @@ -55,10 +59,41 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) assert(d->current_identities->size >= 2); - dfa_identity_t* id0 = d->current_identities->data[0]; + id0 = d->current_identities->data[0]; + assert(id0 && id0->type); - scf_block_t* b = parse->ast->current_block; + t = id0->type; + + int const_flag = id0->const_flag; + int nb_pointers = id0->nb_pointers; + void* func_ptr = id0->func_ptr; + + if (id0->type_def) { + const_flag |= id0->type_def->const_flag; + nb_pointers += id0->type_def->nb_pointers; + + if (!func_ptr) + func_ptr = id0->type_def->func_ptr; + } + + if (d->pf_pointers > 0) { + nb_pointers = d->pf_pointers; + + t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR); + } + + if (SCF_VAR_VOID == t->node.type && 0 == nb_pointers) { + scf_loge("void var must be a pointer, like 'void*'\n"); + return SCF_DFA_ERROR; + } + + if (SCF_FUNCTION_PTR == t->node.type && 0 == nb_pointers) { + scf_loge("invalid func ptr\n"); + return SCF_DFA_ERROR; + } + + scf_block_t* b = ast->current_block; while (b) { if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type) break; @@ -84,10 +119,10 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) global_flag = 0; member_flag = 1; - if (0 == id0->nb_pointers && id0->type->node.type >= SCF_STRUCT) { + if (0 == nb_pointers && t->node.type >= SCF_STRUCT) { // if not pointer var, check if define recursive struct/union/class var - if (_check_recursive((scf_type_t*)b, id0->type, id->identity) < 0) { + if (_check_recursive((scf_type_t*)b, t, id->identity) < 0) { scf_loge("recursive define when define var '%s', line: %d\n", id->identity->text->data, id->identity->line); @@ -96,56 +131,59 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) } } - if (SCF_FUNCTION_PTR == id0->type->node.type - && (!id0->func_ptr || 0 == id0->nb_pointers)) { - scf_loge("invalid func ptr\n"); - return SCF_DFA_ERROR; - } - if (id0->extern_flag) { if (!global_flag) { scf_loge("extern var must be global.\n"); return SCF_DFA_ERROR; } - scf_variable_t* v = scf_block_find_variable(parse->ast->current_block, id->identity->text->data); + v = scf_block_find_variable(ast->current_block, id->identity->text->data); if (v) { scf_loge("extern var already declared, line: %d\n", v->w->line); return SCF_DFA_ERROR; } } - if (SCF_VAR_VOID == id0->type->node.type && 0 == id0->nb_pointers) { - scf_loge("void var must be a pointer, like void*\n"); - return SCF_DFA_ERROR; - } - - v = SCF_VAR_ALLOC_BY_TYPE(id->identity, id0->type, id0->const_flag, id0->nb_pointers, id0->func_ptr); + v = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, const_flag, nb_pointers, func_ptr); if (!v) { scf_loge("alloc var failed\n"); return SCF_DFA_ERROR; } - v->local_flag = local_flag; - v->global_flag = global_flag; - v->member_flag = member_flag; + v->local_flag = local_flag; + v->global_flag = global_flag; + v->member_flag = member_flag; + + v->static_flag = id0->static_flag; + v->extern_flag = id0->extern_flag; + v->typedef_flag = id0->typedef_flag; + + if (id0->type_def) { + int i; + scf_dimention_t* dim; - v->static_flag = id0->static_flag; - v->extern_flag = id0->extern_flag; + for (i = 0; i < id0->type_def->nb_dimentions; i++) { + dim = &id0->type_def->dimentions[i]; - scf_logi("type: %d, nb_pointers: %d,nb_dimentions: %d, var: %s,line:%d,pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n", - v->type, v->nb_pointers, v->nb_dimentions, + scf_variable_add_array_dimention(v, dim->num, NULL); + } + + v->const_literal_flag = id0->type_def->nb_dimentions > 0; + } + + scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d, var: %s, line:%d, pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n", + v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions, v->w->text->data, v->w->line, v->w->pos, v->local_flag, v->global_flag, v->member_flag, v->extern_flag, v->static_flag); - scf_scope_push_var(parse->ast->current_block->scope, v); + scf_scope_push_var(ast->current_block->scope, v); - d->current_var = v; - d->current_var_w = id->identity; - id0->nb_pointers = 0; - id0->const_flag = 0; - id0->static_flag = 0; - id0->extern_flag = 0; + d->current_var = v; + d->current_var_w = id->identity; + id0->nb_pointers = 0; + id0->const_flag = 0; + id0->static_flag = 0; + id0->extern_flag = 0; scf_stack_pop(d->current_identities); free(id); @@ -443,6 +481,49 @@ static int _var_add_vla(scf_ast_t* ast, scf_variable_t* vla) return 0; } +static int _var_add_typedef(scf_ast_t* ast, dfa_data_t* d) +{ + scf_variable_t* v; + + if (d->expr) { + scf_expr_free(d->expr); + d->expr = NULL; + } + + if (d->expr_local_flag > 0) + d->expr_local_flag--; + + if (d->current_var) { + v = scf_block_find_typedef(ast->current_block, d->current_var->w->text->data); + if (v) { + scf_loge("repeated typedef '%s', 1st in file: %s, line: %d, 2nd in file: %s, line: %d\n", + v->w->text->data, v->w->file->data, v->w->line, + d->current_var->w->file->data, + d->current_var->w->line); + return SCF_DFA_REPEATED; + } + + v = d->current_var; + + scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d, var: %s, line:%d, pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n", + v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions, + v->w->text->data, v->w->line, v->w->pos, + v->local_flag, v->global_flag, v->member_flag, + v->extern_flag, v->static_flag); + + int ret = scf_vector_add(ast->current_block->scope->typedef_vars, d->current_var); + if (ret < 0) + return ret; + + assert(0 == scf_vector_del(ast->current_block->scope->vars, d->current_var)); + + d->current_var->vla_flag = 0; + d->current_var = NULL; + } + + return 0; +} + static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -459,6 +540,15 @@ static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (d->current_var) { scf_variable_size(d->current_var); + if (d->current_var->typedef_flag) { + + int ret = _var_add_typedef(parse->ast, d); + if (ret < 0) + return ret; + + return SCF_DFA_SWITCH_TO; + } + if (d->current_var->vla_flag) { if (_var_add_vla(parse->ast, d->current_var) < 0) @@ -496,6 +586,15 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data if (d->current_var) { scf_variable_size(d->current_var); + if (d->current_var->typedef_flag) { + + int ret = _var_add_typedef(parse->ast, d); + if (ret < 0) + return ret; + + return SCF_DFA_OK; + } + if (d->current_var->vla_flag) { if (_var_add_vla(parse->ast, d->current_var) < 0) @@ -523,8 +622,9 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - scf_parse_t* parse = dfa->priv; - dfa_data_t* d = data; + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; if (_var_add_var(dfa, d) < 0) { scf_loge("add var error\n"); @@ -534,16 +634,18 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->nb_lss = 0; d->nb_rss = 0; - scf_lex_word_t* w = words->data[words->size - 1]; - if (!d->current_var) { scf_loge("\n"); return SCF_DFA_ERROR; } + if (d->current_var->typedef_flag) { + scf_loge("typedef can't be assigned by '%s', file: %s, line: %d\n", w->text->data, w->file->data, w->line); + return SCF_DFA_ERROR; + } + if (d->current_var->extern_flag) { - scf_loge("extern var '%s' can't be inited here, line: %d\n", - d->current_var->w->text->data, w->line); + scf_loge("extern var '%s' can't be inited here, line: %d\n", d->current_var->w->text->data, w->line); return SCF_DFA_ERROR; } @@ -554,8 +656,7 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data) } if (d->current_var->nb_dimentions > 0) { - scf_logi("var array '%s' init, nb_dimentions: %d\n", - d->current_var->w->text->data, d->current_var->nb_dimentions); + scf_logi("var array '%s' init, nb_dimentions: %d\n", d->current_var->w->text->data, d->current_var->nb_dimentions); return SCF_DFA_NEXT_WORD; } @@ -641,7 +742,11 @@ static int _var_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } - assert(!d->expr); + if (d->expr) { + scf_expr_free(d->expr); + d->expr = NULL; + } + scf_variable_add_array_dimention(d->current_var, -1, NULL); d->current_var->const_literal_flag = 1; @@ -663,56 +768,61 @@ static int _var_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_logd("d->expr: %p\n", d->expr); - if (d->expr) { - while(d->expr->parent) - d->expr = d->expr->parent; + if (!d->expr) + return SCF_DFA_SWITCH_TO; - if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) { - scf_loge("scf_expr_calculate\n"); + while(d->expr->parent) + d->expr = d->expr->parent; - scf_expr_free(d->expr); - d->expr = NULL; - return SCF_DFA_ERROR; - } + if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) + goto error; - assert(d->current_var->dim_index < d->current_var->nb_dimentions); + assert(d->current_var->dim_index < d->current_var->nb_dimentions); - if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) { + if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) { - if (!d->current_var->local_flag) { - scf_loge("variable length array '%s' must in local scope, file: %s, line: %d\n", - d->current_var->w->text->data, w->file->data, w->line); + if (d->current_var->typedef_flag) { + scf_loge("variable length array '%s' can't be type defined, file: %s, line: %d\n", + d->current_var->w->text->data, w->file->data, w->line); + goto error; + } - scf_variable_free(r); - r = NULL; + if (!d->current_var->local_flag) { + scf_loge("variable length array '%s' must in local scope, file: %s, line: %d\n", + d->current_var->w->text->data, w->file->data, w->line); + goto error; + } - scf_expr_free(d->expr); - d->expr = NULL; - return SCF_DFA_ERROR; - } + scf_logw("define variable length array, file: %s, line: %d\n", w->file->data, w->line); - scf_logw("define variable length array, file: %s, line: %d\n", w->file->data, w->line); + d->current_var->dimentions[d->current_var->dim_index].vla = d->expr; + d->current_var->vla_flag = 1; + d->expr = NULL; + } else { + d->current_var->dimentions[d->current_var->dim_index].num = r->data.i; - d->current_var->dimentions[d->current_var->dim_index].vla = d->expr; - d->current_var->vla_flag = 1; - d->expr = NULL; - } else { - d->current_var->dimentions[d->current_var->dim_index].num = r->data.i; + scf_logi("dimentions: %d, size: %d\n", + d->current_var->dim_index, d->current_var->dimentions[d->current_var->dim_index].num); - scf_logi("dimentions: %d, size: %d\n", - d->current_var->dim_index, d->current_var->dimentions[d->current_var->dim_index].num); + scf_expr_free(d->expr); + d->expr = NULL; + } - scf_expr_free(d->expr); - d->expr = NULL; - } + d->current_var->dim_index++; - d->current_var->dim_index++; + scf_variable_free(r); + r = NULL; + return SCF_DFA_SWITCH_TO; +error: + if (r) { scf_variable_free(r); r = NULL; } - return SCF_DFA_SWITCH_TO; + scf_expr_free(d->expr); + d->expr = NULL; + return SCF_DFA_ERROR; } static int _dfa_init_module_var(scf_dfa_t* dfa) diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 00b910f..69cc4ef 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -296,7 +296,8 @@ static int __debug_add_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_decla } d = parse->debug->abbrevs->data[parse->debug->abbrevs->size - 1]; - d->has_children = t->scope->vars->size > 0; + + d->has_children = t->scope && t->scope->vars->size > 0; } types = parse->debug->struct_types; @@ -524,10 +525,12 @@ static int _debug_add_type(scf_dwarf_info_entry_t** pie, scf_parse_t* parse, scf static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_declaration_t** pad, scf_parse_t* parse, scf_type_t* t) { -// scf_dwarf_abbrev_declaration_t* d; - scf_dwarf_abbrev_attribute_t* attr; - scf_dwarf_info_entry_t* ie; - scf_dwarf_info_attr_t* iattr; + scf_dwarf_abbrev_attribute_t* attr; + scf_dwarf_info_entry_t* ie; + scf_dwarf_info_attr_t* iattr; + scf_dwarf_info_entry_t* ie_member; + scf_variable_t* v_member; + scf_type_t* t_member; int ret; int i; @@ -538,40 +541,40 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev int nb_pointers = 0; - for (i = 0; i < t->scope->vars->size; i++) { + if (t->scope) { + for (i = 0; i < t->scope->vars->size; i++) { + v_member = t->scope->vars->data[i]; + t_member = NULL; - scf_dwarf_info_entry_t* ie_member; - scf_variable_t* v_member; - scf_type_t* t_member; + ret = scf_ast_find_type_type(&t_member, parse->ast, v_member->type); + if (ret < 0) + return ret; - v_member = t->scope->vars->data[i]; - ret = scf_ast_find_type_type(&t_member, parse->ast, v_member->type); - if (ret < 0) - return ret; + ie_member = _debug_find_type(parse, t_member, v_member->nb_pointers); + if (!ie_member) { - ie_member = _debug_find_type(parse, t_member, v_member->nb_pointers); - if (!ie_member) { + if (t_member != t) { + ret = _debug_add_type(&ie_member, parse, t_member, v_member->nb_pointers); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + } else { + assert(v_member->nb_pointers > 0); - if (t_member != t) { - ret = _debug_add_type(&ie_member, parse, t_member, v_member->nb_pointers); - if (ret < 0) { - scf_loge("\n"); - return ret; + if (nb_pointers < v_member->nb_pointers) + nb_pointers = v_member->nb_pointers; } - } else { - assert(v_member->nb_pointers > 0); - - if (nb_pointers < v_member->nb_pointers) - nb_pointers = v_member->nb_pointers; } + + if (scf_vector_add(ie_member_types, ie_member) < 0) + return -ENOMEM; } - if (scf_vector_add(ie_member_types, ie_member) < 0) - return -ENOMEM; + assert(ie_member_types->size == t->scope->vars->size); } - assert(ie_member_types->size == t->scope->vars->size); - + ie = NULL; ret = __debug_add_type(&ie, pad, parse, t, 0, NULL); if (ret < 0) { scf_loge("\n"); @@ -586,22 +589,20 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev return -ENOMEM; } - for (i = 0; i < t->scope->vars->size; i++) { - - scf_dwarf_info_entry_t* ie_member; - scf_variable_t* v_member; - - v_member = t->scope->vars->data[i]; + if (t->scope) { + for (i = 0; i < t->scope->vars->size; i++) { + v_member = t->scope->vars->data[i]; + ie_member = NULL; - ret = __debug_add_member_var(&ie_member, parse, v_member, ie_member_types->data[i]); - if (ret < 0) { - scf_loge("\n"); - return ret; - } + ret = __debug_add_member_var(&ie_member, parse, v_member, ie_member_types->data[i]); + if (ret < 0) { + scf_loge("\n"); + return ret; + } - if (nb_pointers > 0) { - if (scf_vector_add(refills, ie_member) < 0) { - return -ENOMEM; + if (nb_pointers > 0) { + if (scf_vector_add(refills, ie_member) < 0) + return -ENOMEM; } } } @@ -626,17 +627,18 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev int j; for (j = 1; j <= nb_pointers; j++) { + ie_pointer = NULL; + ret = _debug_add_type(&ie_pointer, parse, t, j); if (ret < 0) { scf_loge("\n"); return ret; } - for (i = 0; i < t->scope->vars->size; i++) { - - scf_dwarf_info_entry_t* ie_member; - scf_variable_t* v_member; + if (!t->scope) + continue; + for (i = 0; i < t->scope->vars->size; i++) { v_member = t->scope->vars->data[i]; if (v_member->type != t->node.type) diff --git a/parse/scf_parse.h b/parse/scf_parse.h index 051ff1c..719e89c 100644 --- a/parse/scf_parse.h +++ b/parse/scf_parse.h @@ -50,15 +50,17 @@ typedef struct { scf_lex_word_t* identity; scf_lex_word_t* type_w; scf_type_t* type; + scf_variable_t* type_def; int number; int nb_pointers; scf_function_t* func_ptr; - uint32_t const_flag :1; - uint32_t extern_flag:1; - uint32_t static_flag:1; - uint32_t inline_flag:1; + uint32_t const_flag :1; + uint32_t extern_flag :1; + uint32_t static_flag :1; + uint32_t inline_flag :1; + uint32_t typedef_flag:1; } dfa_identity_t; @@ -77,6 +79,7 @@ struct dfa_data_s { scf_function_t* current_function; int argc; + int pf_pointers; scf_lex_word_t* current_async_w;