From: yu.dongliang <18588496441@163.com> Date: Sun, 16 Aug 2026 13:13:30 +0000 (+0800) Subject: 1, support 'va_copy()', 'offsetof()', X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=f0c594503949cd531a3eeca2fa606a6022296805;p=scf.git 1, support 'va_copy()', 'offsetof()', 2, support , , , of musl libc. --- diff --git a/core/scf_3ac.c b/core/scf_3ac.c index 5560a19..2b6d7dc 100644 --- a/core/scf_3ac.c +++ b/core/scf_3ac.c @@ -57,6 +57,7 @@ static scf_3ac_operator_t _3ac_operators[] = { {SCF_OP_OR_ASSIGN, "|="}, {SCF_OP_VA_START, "va_start"}, + {SCF_OP_VA_COPY, "va_copy"}, {SCF_OP_VA_ARG, "va_arg"}, {SCF_OP_VA_END, "va_end"}, diff --git a/core/scf_ast.c b/core/scf_ast.c index bad662e..2bf5a93 100644 --- a/core/scf_ast.c +++ b/core/scf_ast.c @@ -572,11 +572,9 @@ int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const ui return 0; } -int scf_function_signature(scf_ast_t* ast, scf_function_t* f) +int scf_function_signature2(scf_string_t** ps, scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv) { scf_string_t* s; - scf_type_t* t = (scf_type_t*)f->node.parent; - int ret; int i; @@ -596,32 +594,22 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f) goto error; } - if (f->op_type >= 0) { - scf_operator_t* op = scf_find_base_operator_by_type(f->op_type); - - if (!op->signature) - goto error; - - ret = scf_string_cat_cstr(s, op->signature); - } else - ret = scf_string_cat(s, f->node.w->text); - + ret = scf_string_cat_cstr(s, fname); if (ret < 0) goto error; scf_logd("f signature: %s\n", s->data); if (t->node.type < SCF_STRUCT) { - if (f->signature) - scf_string_free(f->signature); - - f->signature = s; + *ps = s; return 0; } - if (f->argv) { - for (i = 0; i < f->argv->size; i++) { - scf_variable_t* v = f->argv->data[i]; - scf_type_t* t_v = NULL; + if (argv) { + scf_variable_t* v; + scf_type_t* t_v; + + for (i = 0; i < argv->size; i++) { + v = argv->data[i]; t_v = scf_block_find_type_type((scf_block_t*)t, v->type); if (!t_v) { @@ -657,14 +645,36 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f) scf_logd("f signature: %s\n", s->data); - if (f->signature) - scf_string_free(f->signature); - f->signature = s; + *ps = s; return 0; error: scf_string_free(s); - return -1; + return ret; +} + +int scf_function_signature(scf_ast_t* ast, scf_function_t* f, scf_vector_t* argv) +{ + char* fname = f->node.w->text->data; + + if (f->op_type >= 0) { + scf_operator_t* op = scf_find_base_operator_by_type(f->op_type); + + if (!op->signature) + return -EINVAL; + + fname = op->signature; + } + + if (!argv) + argv = f->argv; + + if (f->signature) { + scf_string_free(f->signature); + f->signature = NULL; + } + + return scf_function_signature2(&f->signature, ast, (scf_type_t*)f->node.parent, fname, argv); } int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv) diff --git a/core/scf_ast.h b/core/scf_ast.h index 8657eb9..c749ace 100644 --- a/core/scf_ast.h +++ b/core/scf_ast.h @@ -78,7 +78,9 @@ int scf_ast_add_base_type(scf_ast_t* ast, scf_base_type_t* base_type); int scf_ast_add_file_block(scf_ast_t* ast, const char* path); -int scf_function_signature(scf_ast_t* ast, scf_function_t* f); +int scf_function_signature(scf_ast_t* ast, scf_function_t* f, scf_vector_t* argv); + +int scf_function_signature2(scf_string_t** ps, scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv); int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w); int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64); diff --git a/core/scf_operator.c b/core/scf_operator.c index 7b9160f..5327198 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -11,6 +11,7 @@ static scf_operator_t base_operators[] = {".", "p", SCF_OP_POINTER, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, {"va_start", NULL, SCF_OP_VA_START, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"va_copy", NULL, SCF_OP_VA_COPY, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, {"va_arg", NULL, SCF_OP_VA_ARG, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, {"va_end", NULL, SCF_OP_VA_END, 1, 1, SCF_OP_ASSOCIATIVITY_LEFT}, {"container", NULL, SCF_OP_CONTAINER, 1, 3, SCF_OP_ASSOCIATIVITY_LEFT}, diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index 7290950..35784b6 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -202,11 +202,16 @@ static int _scf_op_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo vptr->tmp_flag = 1; nptr = scf_node_alloc(NULL, vptr->type, vptr); + + scf_variable_free(vptr); + vptr = NULL; if (!nptr) return -ENOMEM; - if (scf_node_add_child(parent, nptr) < 0) + if (scf_node_add_child(parent, nptr) < 0) { + scf_node_free(nptr); return -ENOMEM; + } srcs[0] = parent->nodes[0]; srcs[1] = parent->nodes[1]; @@ -215,6 +220,15 @@ static int _scf_op_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo return _scf_3ac_code_srcN(d->_3ac_list_head, SCF_OP_VA_START, srcs, 3); } +static int _scf_op_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_handler_data_t* d = data; + + return _scf_3ac_code_srcN(d->_3ac_list_head, SCF_OP_VA_COPY, nodes, nb_nodes); +} + static int _scf_op_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(1 == nb_nodes); @@ -2431,6 +2445,7 @@ scf_operator_handler_pt __operator_handlers[SCF_N_3AC_OPS] = [SCF_OP_POINTER ] = _scf_op_pointer, [SCF_OP_VA_START] = _scf_op_va_start, + [SCF_OP_VA_COPY ] = _scf_op_va_copy, [SCF_OP_VA_ARG ] = _scf_op_va_arg, [SCF_OP_VA_END ] = _scf_op_va_end, diff --git a/examples/hello.c b/examples/hello.c index 4cc8c43..741e156 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -1,4 +1,8 @@ #include +#include +#include +#include +#include int main() { diff --git a/examples/offsetof.c b/examples/offsetof.c new file mode 100644 index 0000000..911557d --- /dev/null +++ b/examples/offsetof.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +struct A +{ + long x; + int y; + short z; +}; + +int main() +{ + printf("offsetof(A, z): %ld\n", offsetof(A, z)); + return 0; +} diff --git a/examples/scf_printf.c b/examples/scf_printf.c index e38964b..9d81227 100644 --- a/examples/scf_printf.c +++ b/examples/scf_printf.c @@ -206,11 +206,16 @@ int write(int fd, uint8_t* buf, intptr_t size); int scf_printf(const char* fmt, ...) { va_list ap; + va_list ap2; char buf[1024]; va_start(ap, fmt); - int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap); + va_copy(ap2, ap); + + int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap2); + + va_end(ap2); va_end(ap); if (ret > 0) { diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 2abb52c..81f8e19 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -1963,7 +1963,6 @@ static int _x64_inst_pop_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) } /* - struct va_list { uint8_t* iptr; @@ -2040,6 +2039,80 @@ static int _x64_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c) return 0; } +static int _x64_inst_va_copy_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + scf_x64_context_t* x64 = ctx->priv; + scf_function_t* f = x64->f; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + assert(2 == c->srcs->size); + + scf_instruction_t* inst = NULL; + scf_register_t* r0 = NULL; + scf_register_t* r1 = NULL; + scf_register_t* r = NULL; + + scf_3ac_operand_t* ap0 = c->srcs->data[0]; + scf_3ac_operand_t* ap1 = c->srcs->data[1]; + scf_x64_OpCode_t* P2G = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_E2G); + scf_x64_OpCode_t* G2P = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E); + scf_variable_t* v0 = ap0->dag_node->var; + scf_variable_t* v1 = ap1->dag_node->var; + + if (v0->bp_offset >= 0 || v1->bp_offset >= 0) { + scf_loge("\n"); + return -1; + } + + X64_SELECT_REG_CHECK(&r0, ap0->dag_node, c, f, 1); + X64_SELECT_REG_CHECK(&r1, ap1->dag_node, c, f, 1); + + int ret = x64_select_free_reg(&r, c, f, 0); + if (ret < 0) + return ret; + + // iptr: offset 0 + inst = x64_make_inst_P2G(P2G, r, r1, 0); + X64_INST_ADD_CHECK(c, inst, NULL); + + inst = x64_make_inst_G2P(G2P, r0, 0, r); + X64_INST_ADD_CHECK(c, inst, NULL); + + // fptr: offset 8 + inst = x64_make_inst_P2G(P2G, r, r1, 8); + X64_INST_ADD_CHECK(c, inst, NULL); + + inst = x64_make_inst_G2P(G2P, r0, 8, r); + X64_INST_ADD_CHECK(c, inst, NULL); + + // optr: offset 16 + inst = x64_make_inst_P2G(P2G, r, r1, 16); + X64_INST_ADD_CHECK(c, inst, NULL); + + inst = x64_make_inst_G2P(G2P, r0, 16, r); + X64_INST_ADD_CHECK(c, inst, NULL); + + // ireg: offset 24 + inst = x64_make_inst_P2G(P2G, r, r1, 24); + X64_INST_ADD_CHECK(c, inst, NULL); + + inst = x64_make_inst_G2P(G2P, r0, 24, r); + X64_INST_ADD_CHECK(c, inst, NULL); + + // freg: offset 32 + inst = x64_make_inst_P2G(P2G, r, r1, 32); + X64_INST_ADD_CHECK(c, inst, NULL); + + inst = x64_make_inst_G2P(G2P, r0, 32, r); + X64_INST_ADD_CHECK(c, inst, NULL); + return 0; +} + static int _x64_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) { scf_x64_context_t* x64 = ctx->priv; @@ -2223,6 +2296,7 @@ static x64_inst_handler_pt x64_inst_handlers[] = [SCF_OP_NEG ] = _x64_inst_neg_handler, [SCF_OP_VA_START ] = _x64_inst_va_start_handler, + [SCF_OP_VA_COPY ] = _x64_inst_va_copy_handler, [SCF_OP_VA_ARG ] = _x64_inst_va_arg_handler, [SCF_OP_VA_END ] = _x64_inst_va_end_handler, diff --git a/native/x64/scf_x64_rcg.c b/native/x64/scf_x64_rcg.c index baf144b..28a68cc 100644 --- a/native/x64/scf_x64_rcg.c +++ b/native/x64/scf_x64_rcg.c @@ -1191,6 +1191,14 @@ static int _x64_rcg_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_g return x64_rcg_make(c, g, NULL, NULL); } +static int _x64_rcg_va_copy_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) +{ + int ret = x64_rcg_make2(c, NULL, NULL); + if (ret < 0) + return ret; + return x64_rcg_make(c, g, NULL, NULL); +} + static int _x64_rcg_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { int ret = x64_rcg_make2(c, NULL, NULL); @@ -1220,6 +1228,7 @@ static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] = [SCF_OP_NEG ] = _x64_rcg_neg_handler, [SCF_OP_VA_START ] = _x64_rcg_va_start_handler, + [SCF_OP_VA_COPY ] = _x64_rcg_va_copy_handler, [SCF_OP_VA_ARG ] = _x64_rcg_va_arg_handler, [SCF_OP_VA_END ] = _x64_rcg_va_end_handler, diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 49a2187..b8a6681 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -9,7 +9,7 @@ typedef struct { scf_stack_t* ls_exprs; scf_stack_t* lp_exprs; scf_block_t* parent_block; - scf_variable_t* current_var; + scf_type_t* current_struct; } expr_module_data_t; @@ -117,6 +117,9 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) scf_logd("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line); node = scf_node_alloc(w, var->type, var); + + scf_variable_free(var); + var = NULL; if (!node) return -ENOMEM; @@ -133,14 +136,14 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) return SCF_DFA_ERROR; } - if (var->type >= SCF_STRUCT) { + if (node->var->type >= SCF_STRUCT) { - int ret = scf_ast_find_type_type(&md->current_struct, parse->ast, var->type); + int ret = scf_ast_find_type_type(&md->current_struct, parse->ast, node->var->type); if (ret < 0) return SCF_DFA_ERROR; + assert(md->current_struct); } - md->current_var = var; free(id); id = NULL; @@ -193,7 +196,7 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } - if (scf_function_signature(parse->ast, f) < 0) + if (scf_function_signature(parse->ast, f, NULL) < 0) return SCF_DFA_ERROR; w->text->data[2] = '\0'; @@ -248,19 +251,18 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) } scf_variable_t* var = SCF_VAR_ALLOC_BY_TYPE(w, t, 1, nb_pointers, NULL); - if (!var) { - scf_loge("var '%s' alloc failed\n", w->text->data); - return SCF_DFA_ERROR; - } + if (!var) + return -ENOMEM; - scf_node_t* n = scf_node_alloc(w, var->type, var); - if (!n) { - scf_loge("var node '%s' alloc failed\n", w->text->data); - return SCF_DFA_ERROR; - } + scf_node_t* node = scf_node_alloc(w, var->type, var); - if (scf_expr_add_node(d->expr, n) < 0) { - scf_loge("add var node '%s' to expr failed\n", w->text->data); + scf_variable_free(var); + var = NULL; + if (!node) + return -ENOMEM; + + if (scf_expr_add_node(d->expr, node) < 0) { + scf_node_free(node); return SCF_DFA_ERROR; } @@ -416,38 +418,57 @@ static int _expr_action_rp_cast(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (d->current_va_arg || d->current_va_copy) return SCF_DFA_NEXT_SYNTAX; - scf_variable_t* var = NULL; - scf_node_t* node_var = NULL; - scf_node_t* node_cast = NULL; + scf_variable_t* var = NULL; + scf_node_t* node = NULL; + scf_node_t* cast = NULL; + scf_expr_t* e = NULL; var = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, id->func_ptr); - if (!var) { - scf_loge("var alloc failed\n"); + if (!var) return SCF_DFA_ERROR; - } - node_var = scf_node_alloc(NULL, var->type, var); - if (!node_var) { - scf_loge("var node alloc failed\n"); + node = scf_node_alloc(NULL, var->type, var); + + scf_variable_free(var); + var = NULL; + if (!node) return SCF_DFA_ERROR; - } - node_cast = scf_node_alloc(id->type_w, SCF_OP_TYPE_CAST, NULL); - if (!node_cast) { - scf_loge("cast node alloc failed\n"); + cast = scf_node_alloc(id->type_w, SCF_OP_TYPE_CAST, NULL); + if (!cast) { + scf_node_free(node); return SCF_DFA_ERROR; } - scf_node_add_child(node_cast, node_var); - // '(' lp action pushed a expr before - scf_expr_t* e = scf_stack_pop(md->lp_exprs); - - scf_logd("type cast: d->expr: %p, d->expr->parent: %p, e: %p\n", d->expr, d->expr->parent, e); + int ret = scf_node_add_child(cast, node); + if (ret < 0) { + scf_node_free(cast); + scf_node_free(node); + return ret; + } + // '(' lp action pushed a expr before + e = scf_stack_pop(md->lp_exprs); assert(e); - scf_expr_add_node(e, node_cast); + ret = scf_expr_add_node(e, cast); + if (ret < 0) { + scf_node_free(cast); + scf_expr_free(e); + return ret; + } + d->expr = e; + e = NULL; + + if (node->var->type >= SCF_STRUCT) { + + ret = scf_ast_find_type_type(&md->current_struct, parse->ast, node->var->type); + if (ret < 0) + return SCF_DFA_ERROR; + + assert(md->current_struct); + } scf_stack_pop(d->current_identities); free(id); @@ -997,6 +1018,7 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa) scf_dfa_node_add_child(rs, binary_op); scf_dfa_node_add_child(rs, unary_post); scf_dfa_node_add_child(rs, rp); + scf_dfa_node_add_child(rp, ls); scf_dfa_node_add_child(identity, unary_post); scf_dfa_node_add_child(identity, rs); diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 2ac87de..a26b15d 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -18,7 +18,80 @@ typedef struct { int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id); -int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) + +int _function_add_rets(scf_function_t* f, dfa_data_t* d) +{ + dfa_identity_t* id; + scf_variable_t* v; + + int void_flag = 0; + + while (d->current_identities->size > 0) { + + id = scf_stack_pop(d->current_identities); + if (!id) + return SCF_DFA_ERROR; + + if (!id->type) { + assert(id->identity); + + scf_loge("%s:%d:%d, function return value type '%s' NOT found\n", + id->identity->file->data, id->identity->line, id->identity->pos, + id->identity->text->data); + return SCF_DFA_ERROR; + } + + if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers) + void_flag = 1; + + f->extern_flag |= id->extern_flag; + f->static_flag |= id->static_flag; + f->inline_flag |= id->inline_flag; + + if (f->extern_flag && (f->static_flag || f->inline_flag)) { + scf_loge("'extern' function can't be 'static' or 'inline'\n"); + return SCF_DFA_ERROR; + } + + v = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL); + free(id); + id = NULL; + + if (!v) + return SCF_DFA_ERROR; + + if (scf_vector_add(f->rets, v) < 0) { + scf_variable_free(v); + return SCF_DFA_ERROR; + } + } + + assert(f->rets->size > 0); + + if (void_flag && 1 != f->rets->size) { + scf_loge("void function must have no other return value\n"); + return SCF_DFA_ERROR; + } + + f->void_flag = void_flag; + + if (f->rets->size > 4) { + scf_loge("function return values must NOT more than 4!\n"); + return SCF_DFA_ERROR; + } + + int i; + int j; + for (i = 0; i < f->rets->size / 2; i++) { + j = f->rets->size - 1 - i; + + SCF_XCHG(f->rets->data[i], f->rets->data[j]); + } + + return 0; +} + +int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d, scf_lex_word_t* lp) { scf_parse_t* parse = dfa->priv; scf_ast_t* ast = parse->ast; @@ -40,14 +113,16 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) return -ENOMEM; } else { - id = scf_stack_pop(d->current_identities); - - if (!id || !id->identity) { - scf_loge("function identity not found\n"); + id = scf_stack_top(d->current_identities); + if (!id) { + scf_loge("%s:%d:%d, lost 'void' when declare function pointer\n", lp->file->data, lp->line, lp->pos); return SCF_DFA_ERROR; } - name = id->identity; + if (id->identity) + name = id->identity; + else + name = id->type_w; } uint32_t local_flag = 0; @@ -103,7 +178,7 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) v_pf = d->current_var; assert(d->current_identities->size > 0); - id0 = d->current_identities->data[0]; + id0 = d->current_identities->data[0]; if (id0->typedef_flag) { id0->typedef_flag = 0; @@ -131,72 +206,18 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) return SCF_DFA_ERROR; f->member_flag = member_flag; - if (id) { + if (id && d->current_identities->size > 1) { + scf_stack_pop(d->current_identities); free(id); - id = NULL; } + id = NULL; scf_logi("s->size: %d, function: %s(), line: %d, member_flag: %d\n", s->size, f->node.w->text->data, f->node.w->line, f->member_flag); - int void_flag = 0; - - while (d->current_identities->size > 0) { - - id = scf_stack_pop(d->current_identities); - - if (!id || !id->type || !id->type_w) { - scf_loge("function return value type NOT found\n"); - return SCF_DFA_ERROR; - } - - if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers) - void_flag = 1; - - f->extern_flag |= id->extern_flag; - f->static_flag |= id->static_flag; - f->inline_flag |= id->inline_flag; - - if (f->extern_flag && (f->static_flag || f->inline_flag)) { - scf_loge("'extern' function can't be 'static' or 'inline'\n"); - return SCF_DFA_ERROR; - } - - v = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL); - free(id); - id = NULL; - - if (!v) { - scf_function_free(f); - return SCF_DFA_ERROR; - } - - if (scf_vector_add(f->rets, v) < 0) { - scf_variable_free(v); - scf_function_free(f); - return SCF_DFA_ERROR; - } - } - - assert(f->rets->size > 0); - - if (void_flag && 1 != f->rets->size) { - scf_loge("void function must have no other return value\n"); - return SCF_DFA_ERROR; - } - - f->void_flag = void_flag; - - if (f->rets->size > 4) { - scf_loge("function return values must NOT more than 4!\n"); - return SCF_DFA_ERROR; - } - - int i; - int j; - for (i = 0; i < f->rets->size / 2; i++) { - j = f->rets->size - 1 - i; - - SCF_XCHG(f->rets->data[i], f->rets->data[j]); + int ret = _function_add_rets(f, d); + if (ret < 0) { + scf_function_free(f); + return ret; } if (v_pf) { @@ -325,11 +346,11 @@ int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d) arg->dimentions = NULL; } - arg->const_literal_flag = 0; - scf_logi("s->size: %d, fd->f: %s(), fd->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n", s->size, fd->f->node.w->text->data, fd->argc, arg->nb_pointers, arg->nb_dimentions); + arg->const_literal_flag = 0; + assert(scf_vector_find(fd->f->scope->vars, arg)); scf_vector_add(fd->f->argv, arg); @@ -411,6 +432,7 @@ static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* dat static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; + scf_lex_word_t* w = words->data[words->size - 1]; dfa_data_t* d = data; scf_stack_t* s = d->module_datas[dfa_module_function.index]; dfa_fun_data_t* fd = calloc(1, sizeof(dfa_fun_data_t)); @@ -427,11 +449,12 @@ static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (d->pf_pointers <= 0) d->current_var = NULL; - ret = _function_add_function(dfa, d); + ret = _function_add_function(dfa, d, w); if (ret < 0) return ret; d->current_var = NULL; + d->arg_flag = 1; 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); @@ -468,6 +491,8 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_logi("f: %s(), fd->nb_lps: %d, fd->nb_rps: %d\n", f->node.w->text->data, fd->nb_lps, fd->nb_rps); + d->arg_flag = 0; + if (_function_add_arg(dfa, d) < 0) return SCF_DFA_ERROR; @@ -695,6 +720,7 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa) scf_dfa_node_add_child(identity, assign); scf_dfa_node_add_child(rs, pf_rp); + scf_dfa_node_add_child(pf_star, 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_identity.c b/parse/scf_dfa_identity.c index 48d9ae9..371f523 100644 --- a/parse/scf_dfa_identity.c +++ b/parse/scf_dfa_identity.c @@ -4,6 +4,27 @@ extern scf_dfa_module_t dfa_module_identity; +static scf_key_word_t future_key_words[] = +{ + {SCF_CSTR("_Noreturn"), -1}, +}; + +void warning_future_key_word(scf_lex_word_t* w) +{ + scf_key_word_t* key; + int i; + + for (i = 0; i < sizeof(future_key_words) / sizeof(future_key_words[0]); i++) { + key = &future_key_words[i]; + + if (w->text->len == key->len && !memcmp(w->text->data, key->text, key->len)) { + scf_logw("%s:%d:%d, '%s' is a key word of future std C\n", + w->file->data, w->line, w->pos, w->text->data); + break; + } + } +} + static int _identity_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_lex_word_t* w = words->data[words->size - 1]; @@ -12,6 +33,8 @@ static int _identity_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* scf_logd("w: '%s'\n", w->text->data); + warning_future_key_word(w); + dfa_identity_t* id = calloc(1, sizeof(dfa_identity_t)); if (!id) return SCF_DFA_ERROR; diff --git a/parse/scf_dfa_type.c b/parse/scf_dfa_type.c index 74b9429..8523c58 100644 --- a/parse/scf_dfa_type.c +++ b/parse/scf_dfa_type.c @@ -6,6 +6,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); +void warning_future_key_word(scf_lex_word_t* w); + typedef struct { int type; int n; @@ -38,8 +40,10 @@ static type_filter_t base_type_filters[] = static int _base_type_filter(scf_dfa_t* dfa, scf_vector_t* words, scf_stack_t* s) { - if (s->size <= 1) + if (s->size <= 1) { + scf_logw("s->size: %d\n", s->size); return 0; + } scf_parse_t* parse = dfa->priv; scf_ast_t* ast = parse->ast; @@ -305,6 +309,10 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data dfa_identity_t* id = NULL; int ret; + warning_future_key_word(w); + + scf_logi("w: %s\n", w->text->data); + if (s->size > 0) { type = scf_stack_top(s); @@ -359,13 +367,30 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data static int _type_action_star(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - dfa_data_t* d = data; - dfa_identity_t* id = scf_stack_top(d->current_identities); + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + dfa_identity_t* id = scf_stack_top(d->current_identities); + int ret; assert(id); if (!id->type) { - int ret = _type_find_type(dfa, id); + + if (words->size >= 3) { + 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, id); if (ret < 0) { scf_loge("\n"); return ret; @@ -525,6 +550,7 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa) // const pointer, like 'uint8_t* const p' scf_dfa_node_add_child(star, vconst); scf_dfa_node_add_child(vconst, var_name); + scf_dfa_node_add_child(vconst, star); // multi-return-value function scf_dfa_node_add_child(base_type, comma); diff --git a/parse/scf_dfa_va_arg.c b/parse/scf_dfa_va_arg.c index 06e718a..6e8011a 100644 --- a/parse/scf_dfa_va_arg.c +++ b/parse/scf_dfa_va_arg.c @@ -14,6 +14,7 @@ static int _va_arg_action_start(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_lex_word_t* w = words->data[words->size - 1]; if (d->current_va_start + || d->current_va_copy || d->current_va_arg || d->current_va_end) { scf_loge("recursive 'va_start' in file: %s, line %d\n", w->file->data, w->line); @@ -33,10 +34,27 @@ static int _va_arg_action_start(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _va_arg_action_copy(scf_dfa_t* dfa, scf_vector_t* words, void* data) { + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; scf_lex_word_t* w = words->data[words->size - 1]; - scf_loge("%s:%d:%d, NOT support 'va_copy'\n", w->file->data, w->line, w->pos); - return SCF_DFA_ERROR; + if (d->current_va_start + || d->current_va_copy + || d->current_va_arg + || d->current_va_end) { + scf_loge("recursive 'va_copy' in file: %s, line %d\n", w->file->data, w->line); + return SCF_DFA_ERROR; + } + + scf_node_t* node = scf_node_alloc(w, SCF_OP_VA_COPY, NULL); + if (!node) + return SCF_DFA_ERROR; + + scf_node_add_child((scf_node_t*)parse->ast->current_block, node); + + d->current_va_copy = node; + + return SCF_DFA_NEXT_WORD; } static int _va_arg_action_arg(scf_dfa_t* dfa, scf_vector_t* words, void* data) @@ -46,6 +64,7 @@ static int _va_arg_action_arg(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_lex_word_t* w = words->data[words->size - 1]; if (d->current_va_start + || d->current_va_copy || d->current_va_arg || d->current_va_end) { scf_loge("recursive 'va_arg' in file: %s, line %d\n", w->file->data, w->line); @@ -73,6 +92,7 @@ static int _va_arg_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_lex_word_t* w = words->data[words->size - 1]; if (d->current_va_start + || d->current_va_copy || d->current_va_arg || d->current_va_end) { scf_loge("recursive 'va_end' in file: %s, line %d\n", w->file->data, w->line); @@ -97,6 +117,7 @@ static int _va_arg_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_lex_word_t* w = words->data[words->size - 1]; assert(d->current_va_start + || d->current_va_copy || d->current_va_arg || d->current_va_end); @@ -184,8 +205,8 @@ static int _va_arg_action_fmt(scf_dfa_t* dfa, scf_vector_t* words, void* data) && SCF_VAR_I8 != fmt->type && SCF_VAR_U8 != fmt->type) { - scf_loge("format string %s is not 'char*' or 'int8*' or 'uint8*' type\n", w->text->data); - return SCF_DFA_ERROR; + scf_logw("format string %s is not 'char*' or 'int8*' or 'uint8*' type\n", w->text->data); + return SCF_DFA_NEXT_SYNTAX; } if (scf_variable_nb_pointers(fmt) != 1) { diff --git a/parse/scf_dfa_var.c b/parse/scf_dfa_var.c index 7f90287..a2af0c7 100644 --- a/parse/scf_dfa_var.c +++ b/parse/scf_dfa_var.c @@ -46,146 +46,169 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) scf_ast_t* ast = parse->ast; dfa_identity_t* id = scf_stack_top(d->current_identities); dfa_identity_t* id0 = NULL; + scf_lex_word_t* w = NULL; scf_variable_t* v = NULL; scf_type_t* t = NULL; - if (id && id->identity) { + if (id) { + if (id->identity) { + w = id->identity; - 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; + v = scf_scope_find_variable(ast->current_block->scope, w->text->data); + if (v) { + scf_loge("repeated declare var '%s', line: %d\n", w->text->data, w->line); + return SCF_DFA_ERROR; + } } + } - assert(d->current_identities->size >= 2); + // anonymous var only used in function args!! + if (!w && !d->arg_flag) + return 0; - id0 = d->current_identities->data[0]; + assert(d->current_identities->size >= 1); + id0 = d->current_identities->data[0]; - assert(id0 && id0->type); + assert(id0 && id0->type); - t = id0->type; + t = id0->type; - int const_flag = id0->const_flag; - int nb_pointers = id0->nb_pointers; - void* func_ptr = id0->func_ptr; + 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 (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 (!func_ptr) + func_ptr = id0->type_def->func_ptr; + } - if (d->pf_pointers > 0) { - nb_pointers = d->pf_pointers; + if (d->pf_pointers > 0) { + nb_pointers = d->pf_pointers; - t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR); - } + 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_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; - } + 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; - b = (scf_block_t*)b->node.parent; - } + scf_block_t* b = ast->current_block; + while (b) { + if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type) + break; - uint32_t global_flag; - uint32_t local_flag; - uint32_t member_flag; + b = (scf_block_t*)b->node.parent; + } - if (!b) { - local_flag = 0; - global_flag = 1; - member_flag = 0; + uint32_t global_flag; + uint32_t local_flag; + uint32_t member_flag; - } else if (SCF_FUNCTION == b->node.type) { - local_flag = 1; - global_flag = 0; - member_flag = 0; + if (!b) { + local_flag = 0; + global_flag = 1; + member_flag = 0; - } else if (b->node.type >= SCF_STRUCT) { - local_flag = 0; - global_flag = 0; - member_flag = 1; + } else if (SCF_FUNCTION == b->node.type) { + local_flag = 1; + global_flag = 0; + member_flag = 0; - if (0 == nb_pointers && t->node.type >= SCF_STRUCT) { - // if not pointer var, check if define recursive struct/union/class var + } else if (b->node.type >= SCF_STRUCT) { + local_flag = 0; + global_flag = 0; + member_flag = 1; - if (_check_recursive((scf_type_t*)b, t, id->identity) < 0) { + if (0 == nb_pointers && t->node.type >= SCF_STRUCT) { + // if not pointer var, check if define recursive struct/union/class var - scf_loge("recursive define when define var '%s', line: %d\n", - id->identity->text->data, id->identity->line); - return SCF_DFA_ERROR; - } - } - } + if (_check_recursive((scf_type_t*)b, t, w) < 0) { - if (id0->extern_flag) { - if (!global_flag) { - scf_loge("extern var must be global.\n"); + scf_loge("%s:%d:%d, recursive define when define var '%s'\n", + w->file->data, w->line, w->pos, w->text->data); return SCF_DFA_ERROR; } + } + } - 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 (id0->extern_flag) { + if (!global_flag) { + scf_loge("%s:%d:%d, extern var '%s' MUST be global.\n", w->file->data, w->line, w->pos, w->text->data); + return SCF_DFA_ERROR; } - v = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, const_flag, nb_pointers, func_ptr); - if (!v) { - scf_loge("alloc var failed\n"); + v = scf_block_find_variable(ast->current_block, w->text->data); + if (v) { + scf_loge("%s:%d:%d, extern var '%s' already declared, first here: %s:%d:%d\n", + w->file->data, w->line, w->pos, w->text->data, + v->w->file->data, + v->w->line, + v->w->pos); return SCF_DFA_ERROR; } - 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; + v = SCF_VAR_ALLOC_BY_TYPE(w, t, const_flag, nb_pointers, func_ptr); + if (!v) + return SCF_DFA_ERROR; - if (id0->type_def) { - int i; - scf_dimention_t* dim; + v->local_flag = local_flag; + v->global_flag = global_flag; + v->member_flag = member_flag; - for (i = 0; i < id0->type_def->nb_dimentions; i++) { - dim = &id0->type_def->dimentions[i]; + v->static_flag = id0->static_flag; + v->extern_flag = id0->extern_flag; + v->typedef_flag = id0->typedef_flag; - scf_variable_add_array_dimention(v, dim->num); - } + if (id0->type_def) { + int i; + scf_dimention_t* dim; + + for (i = 0; i < id0->type_def->nb_dimentions; i++) { + dim = &id0->type_def->dimentions[i]; - v->const_literal_flag = id0->type_def->nb_dimentions > 0; + scf_variable_add_array_dimention(v, dim->num); } - 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); + v->const_literal_flag = id0->type_def->nb_dimentions > 0; + } + +#if 1 + scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d", + v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions); - scf_scope_push_var(ast->current_block->scope, v); + if (v->w) + printf(", var: '%s', line:%d, pos:%d", v->w->text->data, v->w->line, v->w->pos); + else + printf(", var: 'anonymous', line:%d, pos:%d", id0->type_w->line, id0->type_w->pos); - 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; + printf(", local: %d, global: %d, member: %d, extern: %d, static: %d\n\n", + v->local_flag, v->global_flag, v->member_flag, + v->extern_flag, v->static_flag); +#endif + + scf_scope_push_var(ast->current_block->scope, v); + + d->current_var = v; + d->current_var_w = w; + id0->nb_pointers = 0; + id0->const_flag = 0; + id0->static_flag = 0; + id0->extern_flag = 0; + + if (d->current_identities->size >= 2) { scf_stack_pop(d->current_identities); + free(id); id = NULL; } @@ -585,23 +608,25 @@ static int _dfa_init_module_var(scf_dfa_t* dfa) static int _dfa_init_syntax_var(scf_dfa_t* dfa) { - SCF_DFA_GET_MODULE_NODE(dfa, var, comma, comma); - SCF_DFA_GET_MODULE_NODE(dfa, var, semicolon, semicolon); + SCF_DFA_GET_MODULE_NODE(dfa, var, comma, comma); + SCF_DFA_GET_MODULE_NODE(dfa, var, semicolon, semicolon); - 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); + 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); - SCF_DFA_GET_MODULE_NODE(dfa, var, colon, colon); - SCF_DFA_GET_MODULE_NODE(dfa, var, bits, bits); + SCF_DFA_GET_MODULE_NODE(dfa, var, colon, colon); + SCF_DFA_GET_MODULE_NODE(dfa, var, bits, bits); - SCF_DFA_GET_MODULE_NODE(dfa, type, star, star); - SCF_DFA_GET_MODULE_NODE(dfa, type, identity, identity); + SCF_DFA_GET_MODULE_NODE(dfa, type, star, star); + SCF_DFA_GET_MODULE_NODE(dfa, type, identity, identity); + SCF_DFA_GET_MODULE_NODE(dfa, type, base_type, base_type); + SCF_DFA_GET_MODULE_NODE(dfa, identity, identity, type_name); - SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); + SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); - SCF_DFA_GET_MODULE_NODE(dfa, init_data, entry, init_data); - SCF_DFA_GET_MODULE_NODE(dfa, init_data, rb, init_rb); + SCF_DFA_GET_MODULE_NODE(dfa, init_data, entry, init_data); + SCF_DFA_GET_MODULE_NODE(dfa, init_data, rb, init_rb); scf_dfa_node_add_child(identity, comma); @@ -617,6 +642,11 @@ static int _dfa_init_syntax_var(scf_dfa_t* dfa) scf_dfa_node_add_child(rs, comma); scf_dfa_node_add_child(rs, semicolon); + // anonymous array var, used for function args. + scf_dfa_node_add_child(base_type, ls); + scf_dfa_node_add_child(type_name, ls); + scf_dfa_node_add_child(star, ls); + // bits scf_dfa_node_add_child(identity, colon); scf_dfa_node_add_child(colon, bits); diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index cfa654c..0ae1c0a 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -164,8 +164,8 @@ static int _scf_op_const_array_index(scf_ast_t* ast, scf_node_t** nodes, int nb_ assert(v0); if (scf_variable_nb_pointers(v0) <= 0) { - scf_loge("index out\n"); - return -1; +// scf_loge("index out\n"); +// return -1; } scf_handler_data_t* d = data; @@ -509,6 +509,66 @@ static int _scf_op_const_dereference(scf_ast_t* ast, scf_node_t** nodes, int nb_ static int _scf_op_const_address_of(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { + assert(1 == nb_nodes); + + scf_node_t* child = nodes[0]; + scf_node_t* parent = nodes[0]->parent; + scf_variable_t* result = _scf_operand_get(parent); + scf_variable_t* type; + scf_variable_t* member; + scf_variable_t* r = NULL; + + while (SCF_OP_EXPR == child->type) + child = child->nodes[0]; + + if (SCF_OP_POINTER == child->type) { + assert(2 == child->nb_nodes); + + type = _scf_operand_get(child->nodes[0]); + member = _scf_operand_get(child->nodes[1]); + + if (scf_variable_const(type)) { + + r = scf_variable_ref(result); + + r->data.u64 = type->data.u64 + member->offset; + r->const_flag = 1; + r->const_literal_flag = 1; + + scf_node_free_data(parent); + + parent->type = r->type; + parent->var = r; + } + + } else if (SCF_OP_ARRAY_INDEX == child->type) { + assert(2 == child->nb_nodes); + + type = _scf_operand_get(child->nodes[0]); + member = _scf_operand_get(child->nodes[1]); + + if (scf_variable_const(type) + && !type->global_flag + && !type->member_flag + && !type->local_flag + && scf_variable_const_integer(member)) { + + r = scf_variable_ref(result); + + r->data.u64 = type->data.u64 + member->data.u64 * type->data_size; + r->const_flag = 1; + r->const_literal_flag = 1; + + scf_node_free_data(parent); + + parent->type = r->type; + parent->var = r; + + scf_logd("type->data.p: %p, type->data_size: %d, member->data.u64: %ld, r->data.p: %p\n", + type->data.p, type->data_size, member->data.u64, r->data.p); + } + } + return 0; } @@ -549,12 +609,15 @@ static int _scf_op_const_type_cast(scf_ast_t* ast, scf_node_t** nodes, int nb_no scf_loge("\n"); return ret; } + + r->data_size = result->data_size; r->const_flag = 1; if (parent->w) SCF_XCHG(r->w, parent->w); scf_node_free_data(parent); + parent->type = r->type; parent->var = r; } @@ -919,6 +982,11 @@ static int _scf_op_const_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nod return 0; } +static int _scf_op_const_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + static int _scf_op_const_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { return 0; @@ -939,6 +1007,7 @@ scf_operator_handler_pt const_operator_handlers[SCF_N_OPS] = [SCF_OP_NEW ] = _scf_op_const_new, [SCF_OP_VA_START ] = _scf_op_const_va_start, + [SCF_OP_VA_COPY ] = _scf_op_const_va_copy, [SCF_OP_VA_ARG ] = _scf_op_const_va_arg, [SCF_OP_VA_END ] = _scf_op_const_va_end, diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 9918ff6..a049e13 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -762,15 +762,27 @@ static int _scf_op_semantic_new(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes } ret = _semantic_find_proper_function(ast, class, "__init", argv, &finit); - scf_vector_free(argv); - if (ret < 0) { - scf_loge("init function of class '%s' not found\n", v0->w->text->data); + scf_string_t* signature = NULL; + + ret = scf_function_signature2(&signature, ast, class, "__init", argv); + + if (signature) { + scf_loge("init function '%s' of class '%s' not found\n", signature->data, v0->w->text->data); + + scf_string_free(signature); + } else + scf_loge("init function '__init' of class '%s' not found\n", v0->w->text->data); + + scf_vector_free(argv); scf_node_free(nthis); return -1; } v0->func_ptr = finit; + scf_vector_free(argv); + argv = NULL; + ret = _semantic_add_var(&nsize, ast, parent, v0->w, SCF_VAR_INT, 1, 0, NULL); if (ret < 0) { scf_node_free(nthis); @@ -3075,6 +3087,16 @@ static int _scf_op_semantic_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_ return 0; } +static int _scf_op_semantic_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + if (2 != nb_nodes) { + scf_loge("\n"); + return -1; + } + + return 0; +} + static int _scf_op_semantic_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { if (2 != nb_nodes) { @@ -3094,7 +3116,6 @@ static int _scf_op_semantic_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_no assert(t); scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(nodes[0]->parent->w, t, 0, v->nb_pointers, v->func_ptr); - if (!r) return -ENOMEM; @@ -3122,6 +3143,7 @@ scf_operator_handler_pt semantic_operator_handlers[SCF_N_OPS] = [SCF_OP_NEW ] = _scf_op_semantic_new, [SCF_OP_VA_START ] = _scf_op_semantic_va_start, + [SCF_OP_VA_COPY ] = _scf_op_semantic_va_copy, [SCF_OP_VA_ARG ] = _scf_op_semantic_va_arg, [SCF_OP_VA_END ] = _scf_op_semantic_va_end, diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 20e6636..bc3a458 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -1856,7 +1856,7 @@ static int _scf_parse_add_text_relas(scf_parse_t* parse, scf_elf_context_t* elf, for (j = 0; j < f->text_relas->size; j++) { r = f->text_relas->data[j]; - if (scf_function_signature(parse->ast, r->func) < 0) { + if (scf_function_signature(parse->ast, r->func, NULL) < 0) { scf_loge("\n"); goto error; } @@ -2144,7 +2144,7 @@ int64_t scf_parse_fill_code2(scf_parse_t* parse, scf_vector_t* functions, scf_ve return ret; } - if (scf_function_signature(parse->ast, f) < 0) + if (scf_function_signature(parse->ast, f, NULL) < 0) return -ENOMEM; int ret = _fill_function_inst(code, f, offset, parse); diff --git a/parse/scf_parse.h b/parse/scf_parse.h index cff60ce..1e403fe 100644 --- a/parse/scf_parse.h +++ b/parse/scf_parse.h @@ -108,6 +108,7 @@ struct dfa_data_s { uint32_t extern_flag:1; uint32_t static_flag:1; uint32_t inline_flag:1; + uint32_t arg_flag:1; uint32_t var_semicolon_flag:1; diff --git a/sysroot/include/stddef.h b/sysroot/include/stddef.h new file mode 100644 index 0000000..526df4e --- /dev/null +++ b/sysroot/include/stddef.h @@ -0,0 +1,27 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#if __cplusplus >= 201103L +#define NULL nullptr +#elif defined(__cplusplus) +#define NULL 0L +#else +//#define NULL ((void*)0) +#endif + +#define __NEED_ptrdiff_t +#define __NEED_size_t +#define __NEED_wchar_t +#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L +#define __NEED_max_align_t +#endif + +#include + +#if __GNUC__ > 3 +#define offsetof(type, member) __builtin_offsetof(type, member) +#else +#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 )) +#endif + +#endif diff --git a/sysroot/include/stdlib.h b/sysroot/include/stdlib.h new file mode 100644 index 0000000..e67b588 --- /dev/null +++ b/sysroot/include/stdlib.h @@ -0,0 +1,179 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if __cplusplus >= 201103L +#define NULL nullptr +#elif defined(__cplusplus) +#define NULL 0L +#else +//#define NULL ((void*)0) +#endif + +#define __NEED_size_t +#define __NEED_wchar_t + +#include + +int atoi (const char *); +long atol (const char *); +long long atoll (const char *); +double atof (const char *); + +float strtof (const char *__restrict, char **__restrict); +double strtod (const char *__restrict, char **__restrict); +long double strtold (const char *__restrict, char **__restrict); + +long strtol (const char *__restrict, char **__restrict, int); +unsigned long strtoul (const char *__restrict, char **__restrict, int); +long long strtoll (const char *__restrict, char **__restrict, int); +unsigned long long strtoull (const char *__restrict, char **__restrict, int); + +int rand (void); +void srand (unsigned); + +void *malloc (size_t); +void *calloc (size_t, size_t); +void *realloc (void *, size_t); +void free (void *); +void *aligned_alloc(size_t, size_t); + +_Noreturn void abort (void); +int atexit (void (*) (void)); +_Noreturn void exit (int); +_Noreturn void _Exit (int); +int at_quick_exit (void (*) (void)); +_Noreturn void quick_exit (int); + +char *getenv (const char *); + +int system (const char *); + +void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); +void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); + +int abs (int); +long labs (long); +long long llabs (long long); + +typedef struct { int quot, rem; } div_t; +typedef struct { long quot, rem; } ldiv_t; +typedef struct { long long quot, rem; } lldiv_t; + +div_t div (int, int); +ldiv_t ldiv (long, long); +lldiv_t lldiv (long long, long long); + +int mblen (const char *, size_t); +int mbtowc (wchar_t *__restrict, const char *__restrict, size_t); +int wctomb (char *, wchar_t); +size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t); +size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t); + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +size_t __ctype_get_mb_cur_max(void); +#define MB_CUR_MAX (__ctype_get_mb_cur_max()) + +#define RAND_MAX (0x7fffffff) + + +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ + || defined(_BSD_SOURCE) + +#define WNOHANG 1 +#define WUNTRACED 2 + +#define WEXITSTATUS(s) (((s) & 0xff00) >> 8) +#define WTERMSIG(s) ((s) & 0x7f) +#define WSTOPSIG(s) WEXITSTATUS(s) +#define WIFEXITED(s) (!WTERMSIG(s)) +#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001U)>>8) > 0x7f00) +#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu) + +int posix_memalign (void **, size_t, size_t); +int setenv (const char *, const char *, int); +int unsetenv (const char *); +int mkstemp (char *); +int mkostemp (char *, int); +char *mkdtemp (char *); +int getsubopt (char **, char *const *, char **); +int rand_r (unsigned *); + +#endif + + +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ + || defined(_BSD_SOURCE) +char *realpath (const char *__restrict, char *__restrict); +long int random (void); +void srandom (unsigned int); +char *initstate (unsigned int, char *, size_t); +char *setstate (char *); +int putenv (char *); +int posix_openpt (int); +int grantpt (int); +int unlockpt (int); +char *ptsname (int); +char *l64a (long); +long a64l (const char *); +void setkey (const char *); +double drand48 (void); +double erand48 (unsigned short [3]); +long int lrand48 (void); +long int nrand48 (unsigned short [3]); +long mrand48 (void); +long jrand48 (unsigned short [3]); +void srand48 (long); +unsigned short *seed48 (unsigned short [3]); +void lcong48 (unsigned short [7]); +#endif + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#include +char *mktemp (char *); +int mkstemps (char *, int); +int mkostemps (char *, int, int); +void *valloc (size_t); +void *memalign(size_t, size_t); +int getloadavg(double *, int); +int clearenv(void); +#define WCOREDUMP(s) ((s) & 0x80) +#define WIFCONTINUED(s) ((s) == 0xffff) +void *reallocarray (void *, size_t, size_t); +void qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); +#endif + +#ifdef _GNU_SOURCE +int ptsname_r(int, char *, size_t); +char *ecvt(double, int, int *, int *); +char *fcvt(double, int, int *, int *); +char *gcvt(double, int, char *); +char *secure_getenv(const char *); +struct __locale_struct; +float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *); +double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *); +long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *); +#endif + +#if defined(_LARGEFILE64_SOURCE) +#define mkstemp64 mkstemp +#define mkostemp64 mkostemp +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#define mkstemps64 mkstemps +#define mkostemps64 mkostemps +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sysroot/include/string.h b/sysroot/include/string.h new file mode 100644 index 0000000..da38e56 --- /dev/null +++ b/sysroot/include/string.h @@ -0,0 +1,104 @@ +#ifndef _STRING_H +#define _STRING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if __cplusplus >= 201103L +#define NULL nullptr +#elif defined(__cplusplus) +#define NULL 0L +#else +//#define NULL ((void*)0) +#endif + +#define __NEED_size_t +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ + || defined(_BSD_SOURCE) +#define __NEED_locale_t +#endif + +#include + +void *memcpy (void *__restrict, const void *__restrict, size_t); +void *memmove (void *, const void *, size_t); +void *memset (void *, int, size_t); +int memcmp (const void *, const void *, size_t); +void *memchr (const void *, int, size_t); + +char *strcpy (char *__restrict, const char *__restrict); +char *strncpy (char *__restrict, const char *__restrict, size_t); + +char *strcat (char *__restrict, const char *__restrict); +char *strncat (char *__restrict, const char *__restrict, size_t); + +int strcmp (const char *, const char *); +int strncmp (const char *, const char *, size_t); + +int strcoll (const char *, const char *); +size_t strxfrm (char *__restrict, const char *__restrict, size_t); + +char *strchr (const char *, int); +char *strrchr (const char *, int); + +size_t strcspn (const char *, const char *); +size_t strspn (const char *, const char *); +char *strpbrk (const char *, const char *); +char *strstr (const char *, const char *); +char *strtok (char *__restrict, const char *__restrict); + +size_t strlen (const char *); + +char *strerror (int); + +#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#include +#endif + +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ + || defined(_BSD_SOURCE) +char *strtok_r (char *__restrict, const char *__restrict, char **__restrict); +int strerror_r (int, char *, size_t); +char *stpcpy(char *__restrict, const char *__restrict); +char *stpncpy(char *__restrict, const char *__restrict, size_t); +size_t strnlen (const char *, size_t); +char *strdup (const char *); +char *strndup (const char *, size_t); +char *strsignal(int); +char *strerror_l (int, locale_t); +int strcoll_l (const char *, const char *, locale_t); +size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t); +void *memmem(const void *, size_t, const void *, size_t); +#endif + +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ + || defined(_BSD_SOURCE) +void *memccpy (void *__restrict, const void *__restrict, int, size_t); +#endif + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +char *strsep(char **, const char *); +size_t strlcat (char *, const char *, size_t); +size_t strlcpy (char *, const char *, size_t); +void explicit_bzero (void *, size_t); +#endif + +#ifdef _GNU_SOURCE +#define strdupa(x) strcpy(alloca(strlen(x)+1),x) +int strverscmp (const char *, const char *); +char *strchrnul(const char *, int); +char *strcasestr(const char *, const char *); +void *memrchr(const void *, int, size_t); +void *mempcpy(void *, const void *, size_t); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sysroot/lib/__builtin__.h b/sysroot/lib/__builtin__.h index 349657f..abf945e 100644 --- a/sysroot/lib/__builtin__.h +++ b/sysroot/lib/__builtin__.h @@ -6,5 +6,4 @@ struct __builtin_va_list intptr_t ireg; intptr_t freg; - intptr_t others; };