/* ================ PR_ParseFunctionBody ================ */ void PR_ParseFunctionBody (type_t *type, char *name, def_t *def) { function_t *f; dfunction_t *df; int locals_start; if (pr_scope) PR_ParseError ("'%s': local function definitions are illegal", name); if (def->initialized) PR_ParseError ("function '%s' already has a body", name); locals_start = locals_end = numpr_globals; pr_scope = def; f = PR_ParseImmediateStatements (type); pr_scope = NULL; def->initialized = 1; G_FUNCTION(def->ofs) = numfunctions; f->def = def; // if (opt_dumpasm) // PR_PrintFunction (def); // fill in the dfunction df = &functions[numfunctions]; numfunctions++; if (f->builtin) df->first_statement = -f->builtin; else df->first_statement = f->code; df->s_name = CopyString (f->def->name); df->s_file = s_file; // id's qcc would set numparms to -1 for varargs functions // but non-builtin varargs functions don't make sense anyway so don't bother checking df->numparms = f->def->type->num_parms & VA_MASK; df->locals = locals_end - locals_start; df->parm_start = locals_start; for (int i=0 ; i<df->numparms ; i++) df->parm_size[i] = type_size[f->def->type->parm_types[i]->type]; }
static void ParseFunctionDef (def_t *def, type_t *type) { int i; function_t *f; dfunction_t *df; int locals_start; locals_start = locals_end = numpr_globals; pr_scope = def; f = ParseImmediateStatements(type); pr_scope = NULL; def->initialized = 1; G_FUNCTION(def->ofs) = numfunctions; f->def = def; // Fill in the dfunction df = &functions[numfunctions]; numfunctions++; if (f->builtin) { df->first_statement = -f->builtin; def->referenceCount++; } else { df->first_statement = f->code; } df->s_name = CopyString(f->def->name); df->s_file = s_file; df->numparms = f->def->type->num_parms; df->locals = locals_end-locals_start; df->parm_start = locals_start; for (i = 0; i < df->numparms; i++) { df->parm_size[i] = type_size[f->def->type->parm_types[i]->type]; } }
static void ParseCStyleFunctionDef (const char *funcName, type_t *type) { int i; const char *name = NULL; // FIXME: init to NULL, avoid compiler warning type_t newType; type_t *funcType; def_t *def; function_t *f; dfunction_t *df; int locals_start; char funcIdent[MAX_NAME]; int initClass; strcpy(funcIdent, funcName); memset(&newType, 0, sizeof(newType)); newType.type = ev_function; newType.aux_type = type; // Return type newType.num_parms = 0; if (!TK_CHECK(TK_RPAREN)) { if (TK_CHECK(TK_ELLIPSIS)) { // Variable args newType.num_parms = -1; } else if (!LX_CheckFetch("void")) { do { type = PR_ParseType(); name = PR_ParseName(); strcpy(pr_parm_names[newType.num_parms], name); newType.parm_types[newType.num_parms] = type; newType.num_parms++; } while (TK_CHECK(TK_COMMA)); } LX_Require(")"); } funcType = PR_FindType(&newType); def = PR_GetDef(funcType, funcIdent, pr_scope, true); if (def->initialized) { PR_ParseError("%s redeclared", funcName); } if (TK_TEST(TK_LBRACE) || TK_TEST(TK_LBRACKET) || TK_TEST(TK_COLON)) { initClass = pr_tokenclass; if (def->initialized) { PR_ParseError("%s redeclared", name); } locals_start = locals_end = numpr_globals; pr_scope = def; f = ParseImmediateStatements(funcType); pr_scope = NULL; def->initialized = 1; G_FUNCTION(def->ofs) = numfunctions; f->def = def; df = &functions[numfunctions]; numfunctions++; if (f->builtin) { df->first_statement = -f->builtin; def->referenceCount++; } else { df->first_statement = f->code; } df->s_name = CopyString(f->def->name); df->s_file = s_file; df->numparms = f->def->type->num_parms; df->locals = locals_end - locals_start; df->parm_start = locals_start; for (i = 0; i < df->numparms; i++) { df->parm_size[i] = type_size[f->def->type->parm_types[i]->type]; } if (initClass == TK_COLON) { LX_Require(";"); } } else { LX_Require(";"); } }
/* ================ PR_ParseDefs Called at the outer layer and when a local statement is hit ================ */ void PR_ParseDefs (void) { char *name; type_t *type; def_t *def; function_t *f; dfunction_t *df; int i; int locals_start; type = PR_ParseType (); if (pr_scope && (type->type == ev_field || type->type == ev_function) ) PR_ParseError ("Fields and functions must be global"); do { name = PR_ParseName (); def = PR_GetDef (type, name, pr_scope, true); // check for an initialization if ( PR_Check ("=") ) { if (def->initialized) PR_ParseError ("%s redeclared", name); if (type->type == ev_function) { locals_start = locals_end = numpr_globals; pr_scope = def; f = PR_ParseImmediateStatements (type); pr_scope = NULL; def->initialized = 1; G_FUNCTION(def->ofs) = numfunctions; f->def = def; // if (pr_dumpasm) // PR_PrintFunction (def); // fill in the dfunction df = &functions[numfunctions]; numfunctions++; if (f->builtin) df->first_statement = -f->builtin; else df->first_statement = f->code; df->s_name = CopyString (f->def->name); df->s_file = s_file; df->numparms = f->def->type->num_parms; df->locals = locals_end - locals_start; df->parm_start = locals_start; for (i=0 ; i<df->numparms ; i++) df->parm_size[i] = type_size[f->def->type->parm_types[i]->type]; continue; } else if (pr_immediate_type != type) PR_ParseError ("wrong immediate type for %s", name); def->initialized = 1; memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]); PR_Lex (); } } while (PR_Check (",")); PR_Expect (";"); }