mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 20:11:44 +00:00
rework class fields a little - fields now map onto a single underlaying array symbol, which avoids the need for differently sized underlaying arrays per member that were then conflicting between classes.
tweak the decompiler to deal with fte-optimised progs a little better. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5272 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a450035e80
commit
d474f48fd1
5 changed files with 226 additions and 163 deletions
|
@ -91,12 +91,12 @@ char *type_names[] =
|
|||
"ev_quat",
|
||||
"ev_uinteger"
|
||||
};
|
||||
char *typetoname(QCC_type_t *type)
|
||||
const char *typetoname(QCC_type_t *type)
|
||||
{
|
||||
return type->name;
|
||||
}
|
||||
|
||||
char *temp_type (int temp, dstatement_t *start, dfunction_t *df)
|
||||
const char *temp_type (int temp, dstatement_t *start, dfunction_t *df)
|
||||
{
|
||||
int i;
|
||||
dstatement_t *stat;
|
||||
|
@ -452,7 +452,7 @@ static struct {
|
|||
{80, "infokey", &type_string, {&type_entity, &type_string}, "string(entity e, string key)"},
|
||||
{81, "stof", &type_float, {&type_string}, "float(string s)"},
|
||||
{82, "multicast", NULL, {&type_vector, &type_float}, "void(vector where, float set)"},
|
||||
|
||||
/*
|
||||
//these are mvdsv specific
|
||||
{83, "executecmd", NULL, {NULL}, NULL},
|
||||
{84, "tokenize", NULL, {&type_string}, NULL},
|
||||
|
@ -475,6 +475,50 @@ static struct {
|
|||
{101, "redirectcmd", NULL, {NULL}, NULL},
|
||||
{102, "calltimeofday", NULL, {NULL}, NULL},
|
||||
{103, "forcedemoframe", NULL, {NULL}, NULL},
|
||||
*/
|
||||
|
||||
//some QSG extensions
|
||||
|
||||
{83, NULL, NULL, {NULL}, NULL},
|
||||
{84, NULL, NULL, {NULL}, NULL},
|
||||
{85, NULL, NULL, {NULL}, NULL},
|
||||
{86, NULL, NULL, {NULL}, NULL},
|
||||
{87, NULL, NULL, {NULL}, NULL},
|
||||
{88, NULL, NULL, {NULL}, NULL},
|
||||
{89, NULL, NULL, {NULL}, NULL},
|
||||
{90, "tracebox", NULL, {&type_vector, &type_vector, &type_vector, &type_vector, &type_float, &type_entity}, "void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent)"},
|
||||
{91, "randomvec", &type_vector, {NULL}, "vector()"},
|
||||
{92, "getlight", &type_vector, {&type_vector}, "vector(vector org)"},
|
||||
{93, "registercvar", &type_float, {&type_string, &type_string}, "float(string cvarname, string defaultvalue)"},
|
||||
{94, "min", &type_float, {&type_float,&type_float,&type_float,&type_float,&type_float,&type_float,&type_float,&type_float},"float(float a, float b, ...)"},
|
||||
{95, "max", &type_float, {&type_float,&type_float,&type_float,&type_float,&type_float,&type_float,&type_float,&type_float},"float(float a, float b, ...)"},
|
||||
{96, "bound", &type_float, {&type_float,&type_float,&type_float}, "float(float minimum, float val, float maximum)"},
|
||||
{97, "pow", &type_float, {&type_float,&type_float}, "float(float value, float exp)"},
|
||||
{98, "findfloat", &type_entity, {&type_entity,&type_field,&type_float}, "entity(entity start, .__variant fld, __variant match)"},
|
||||
|
||||
{99, "checkextension",&type_float, {&type_string}, "float(string extname)"},
|
||||
{100, "builtin_find", &type_float, {&type_string}, "float(string builtinname)"},
|
||||
{101, "redirectcmd", NULL, {&type_entity,&type_string}, "void(entity to, string str)"},
|
||||
{102, "anglemod", &type_float, {&type_float}, "float(float value)"},
|
||||
{103, "cvar_string", &type_string, {&type_string}, "string(string cvarname)"},
|
||||
|
||||
{104, "showpic", NULL, {NULL}, "void(string slot, string picname, float x, float y, float zone, optional entity player)"},
|
||||
{105, "hidepic", NULL, {NULL}, "void(string slot, optional entity player)"},
|
||||
{106, "movepic", NULL, {NULL}, "void(string slot, float x, float y, float zone, optional entity player)"},
|
||||
{107, "changepic", NULL, {NULL}, "void(string slot, string picname, optional entity player)"},
|
||||
{108, "showpicent", NULL, {NULL}, "void(string slot, entity player)"},
|
||||
{109, "hidepicent", NULL, {NULL}, "void(string slot, entity player)"},
|
||||
|
||||
{110, "fopen", &type_float, {&type_string,&type_float}, "filestream(string filename, float mode, optional float mmapminsize)"},
|
||||
{111, "fclose", NULL, {&type_float}, "void(filestream fhandle)"},
|
||||
{112, "fgets", &type_string, {&type_float,&type_string}, "string(filestream fhandle)"},
|
||||
{113, "fputs", NULL, {&type_float,&type_string}, "void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)"},
|
||||
{114, "strlen", &type_float, {&type_string}, "float(string s)"},
|
||||
{115, "strcat", &type_string, {&type_string,&type_string}, "string(string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)"},
|
||||
{116, "substring", &type_string, {&type_string,&type_float,&type_float}, "string(string s, float start, float length)"},
|
||||
{117, "stov", &type_vector, {&type_string}, "vector(string s)"},
|
||||
{118, "strzone", &type_string, {&type_string}, "string(string s, ...)"},
|
||||
{119, "strunzone", NULL, {&type_string}, "void(string s)"},
|
||||
};
|
||||
|
||||
char *DecompileValueString(etype_t type, void *val);
|
||||
|
@ -1044,11 +1088,12 @@ void DecompileCalcProfiles(void)
|
|||
*/
|
||||
|
||||
for (j = 0, ps = 0; j < df->numparms; j++)
|
||||
ps += df->parm_size[j];
|
||||
ps += df->parm_size[j];
|
||||
|
||||
if (ps > 0)
|
||||
{
|
||||
for (j = df->parm_start; j < (df->parm_start) + ps; j++)
|
||||
int p;
|
||||
for (p = 0, j = df->parm_start; j < (df->parm_start) + ps; p++)
|
||||
{
|
||||
line[0] = '\0';
|
||||
par = DecompileGetParameter(j);
|
||||
|
@ -1059,16 +1104,31 @@ void DecompileCalcProfiles(void)
|
|||
{
|
||||
//Error("Error - No parameter names with offset %i.", j);
|
||||
// printf("No parameter names with offset %i\n", j);
|
||||
if (j < (df->parm_start) + ps - 1)
|
||||
QC_snprintfz(line, sizeof(line), "float par%i, ", j - df->parm_start);
|
||||
if (p<8)
|
||||
j += df->parm_size[p];
|
||||
else
|
||||
QC_snprintfz(line, sizeof(line), "float par%i", j - df->parm_start);
|
||||
j += 1;
|
||||
if (p<8&&df->parm_size[p] == 3)
|
||||
{
|
||||
if (j < (df->parm_start) + ps)
|
||||
QC_snprintfz(line, sizeof(line), "vector par%i, ", p);
|
||||
else
|
||||
QC_snprintfz(line, sizeof(line), "vector par%i", p);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (j < (df->parm_start) + ps)
|
||||
QC_snprintfz(line, sizeof(line), "__variant par%i, ", p);
|
||||
else
|
||||
QC_snprintfz(line, sizeof(line), "__variant par%i", p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (par->type == ev_vector)
|
||||
j += 2;
|
||||
if (j < (df->parm_start) + ps - 1)
|
||||
j++;
|
||||
if (j < (df->parm_start) + ps)
|
||||
{
|
||||
QC_snprintfz(line, sizeof(line), "%s, ", DecompilePrintParameter(par));
|
||||
}
|
||||
|
@ -1195,7 +1255,7 @@ char *DecompileGlobal(dfunction_t *df, gofs_t ofs, QCC_type_t * req_t)
|
|||
if (def)
|
||||
{
|
||||
|
||||
if (!strcmp(strings + def->s_name, "IMMEDIATE") || !strcmp(strings + def->s_name, ".imm"))
|
||||
if (!strcmp(strings + def->s_name, "IMMEDIATE") || !strcmp(strings + def->s_name, ".imm") || !def->s_name)
|
||||
{
|
||||
etype_t ty;
|
||||
if (!req_t)
|
||||
|
@ -1363,6 +1423,24 @@ void DecompileImmediate_Insert(dfunction_t *df, gofs_t ofs, char *knew, QCC_type
|
|||
}
|
||||
}
|
||||
|
||||
void FloatToString(char *out, size_t outsize, float f)
|
||||
{
|
||||
char *e;
|
||||
QC_snprintfz(out, outsize, "%f", f);
|
||||
|
||||
//trim any trailing decimals
|
||||
e = strchr(out, '.');
|
||||
if (e)
|
||||
{
|
||||
e = e+strlen(e);
|
||||
while (e > out && e[-1] == '0')
|
||||
e--;
|
||||
if (e > out && e[-1] == '.')
|
||||
e--;
|
||||
*e = 0;
|
||||
}
|
||||
}
|
||||
|
||||
char *DecompileImmediate_Get(dfunction_t *df, gofs_t ofs, QCC_type_t *req_t)
|
||||
{
|
||||
char *res;
|
||||
|
@ -1402,16 +1480,21 @@ char *DecompileImmediate_Get(dfunction_t *df, gofs_t ofs, QCC_type_t *req_t)
|
|||
{
|
||||
case ev_void: //for lack of any better ideas.
|
||||
case ev_float:
|
||||
if ((float)(int)pr_globals[ofs] == pr_globals[ofs])
|
||||
QC_snprintfz(temp, sizeof(temp), "%i", (int)(pr_globals[ofs]));
|
||||
else if ((*(int*)&pr_globals[ofs] & 0x7f800000) || !(*(int*)&pr_globals[ofs] & 0x7fffffff))
|
||||
QC_snprintfz(temp, sizeof(temp), "%f", pr_globals[ofs]);
|
||||
//denormalised floats need special handling.
|
||||
if ((0x7fffffff&*(int*)&pr_globals[ofs]) >= 1 && (0x7fffffff&*(int*)&pr_globals[ofs]) < 0x00800000)
|
||||
{
|
||||
QC_snprintfz(temp, sizeof(temp), "((float)(__variant)%ii)", *(int*)&pr_globals[ofs]);
|
||||
|
||||
// if (req_t && *(int*)&pr_globals[ofs] >= 1 && *(int*)&pr_globals[ofs] < strofs)
|
||||
// ; //failure to break means we'll print out a trailing /*string*/
|
||||
// else
|
||||
break;
|
||||
}
|
||||
else
|
||||
QC_snprintfz(temp, sizeof(temp), "%%%i", *(int*)&pr_globals[ofs]);
|
||||
if (pr_globals[ofs] == 0 || ((int*)pr_globals)[ofs] < 0 || ((int*)pr_globals)[ofs] >= strofs || strcmp(temp, "0.000000"))
|
||||
{
|
||||
FloatToString(temp, sizeof(temp), pr_globals[ofs]);
|
||||
break;
|
||||
// printf("Hey! That's not a float! error in %s\n", strings + df->s_name);
|
||||
// printf("%f could be %s\n", pr_globals[ofs], &strings[((int*)pr_globals)[ofs]]);
|
||||
}
|
||||
case ev_string:
|
||||
{
|
||||
const char *in;
|
||||
|
@ -1495,7 +1578,13 @@ char *DecompileImmediate_Get(dfunction_t *df, gofs_t ofs, QCC_type_t *req_t)
|
|||
}
|
||||
break;
|
||||
case ev_vector:
|
||||
QC_snprintfz(temp, sizeof(temp), "\'%f %f %f\'", pr_globals[ofs],pr_globals[ofs+1],pr_globals[ofs+2]);
|
||||
{
|
||||
char x[64], y[64], z[64];
|
||||
FloatToString(x, sizeof(x), pr_globals[ofs+0]);
|
||||
FloatToString(y, sizeof(y), pr_globals[ofs+1]);
|
||||
FloatToString(z, sizeof(z), pr_globals[ofs+2]);
|
||||
QC_snprintfz(temp, sizeof(temp), "\'%s %s %s\'", x, y, z);
|
||||
}
|
||||
break;
|
||||
// case ev_quat:
|
||||
// QC_snprintfz(temp, sizeof(temp), "\'%f %f %f %f\'", pr_globals[ofs],pr_globals[ofs+1],pr_globals[ofs+2],pr_globals[ofs+3]);
|
||||
|
@ -2498,57 +2587,15 @@ QCC_ddef_t *DecompileFunctionGlobal(int funcnum)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void DecompileFunction(const char *name, int *lastglobal)
|
||||
void DecompilePreceedingGlobals(int start, int end, const char *name)
|
||||
{
|
||||
int i, findex, ps;
|
||||
dstatement_t *ds, *ts, *altdone;
|
||||
dfunction_t *df;
|
||||
QCC_ddef_t *par;
|
||||
char *arg2;
|
||||
unsigned short dom, tom;
|
||||
int j, start, end;
|
||||
int j;
|
||||
QCC_ddef_t *ef;
|
||||
static char line[8192];
|
||||
dstatement_t *k;
|
||||
int dum;
|
||||
size_t startpos;
|
||||
|
||||
const char *matchingfield;
|
||||
|
||||
for (i = 1; i < numfunctions; i++)
|
||||
if (!strcmp(name, strings + functions[i].s_name))
|
||||
break;
|
||||
if (i == numfunctions)
|
||||
{
|
||||
printf("Fatal Error: No function named \"%s\"\n", name);
|
||||
exit(1);
|
||||
}
|
||||
df = functions + i;
|
||||
altdone = statements + numstatements;
|
||||
for (j = i+1; j < numfunctions; j++)
|
||||
{
|
||||
if (functions[j].first_statement <= 0)
|
||||
continue;
|
||||
altdone = statements + functions[j].first_statement;
|
||||
break;
|
||||
}
|
||||
|
||||
findex = i;
|
||||
|
||||
start = *lastglobal;
|
||||
|
||||
// if (dfpred->first_statement <= 0 && df->first_statement > 0)
|
||||
// start -= 1;
|
||||
|
||||
end = df->parm_start;
|
||||
if (!end)
|
||||
{
|
||||
par = DecompileFindGlobal(name);
|
||||
if (par)
|
||||
end = par - globals;
|
||||
}
|
||||
*lastglobal = max(*lastglobal, end + df->locals);
|
||||
|
||||
//print globals leading up to the function.
|
||||
for (j = start; j < end; j++)
|
||||
{
|
||||
|
@ -2584,7 +2631,7 @@ void DecompileFunction(const char *name, int *lastglobal)
|
|||
}
|
||||
else if (par->type != ev_pointer)
|
||||
{
|
||||
if (strcmp(strings + par->s_name, "IMMEDIATE") && strcmp(strings + par->s_name, ".imm"))
|
||||
if (strcmp(strings + par->s_name, "IMMEDIATE") && strcmp(strings + par->s_name, ".imm") && par->s_name)
|
||||
{
|
||||
|
||||
if (par->type == ev_field)
|
||||
|
@ -2656,8 +2703,58 @@ void DecompileFunction(const char *name, int *lastglobal)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void DecompileFunction(const char *name, int *lastglobal)
|
||||
{
|
||||
int i, findex, ps;
|
||||
dstatement_t *ds, *ts, *altdone;
|
||||
dfunction_t *df;
|
||||
QCC_ddef_t *par;
|
||||
char *arg2;
|
||||
unsigned short dom, tom;
|
||||
int j, start, end;
|
||||
static char line[8192];
|
||||
dstatement_t *k;
|
||||
int dum;
|
||||
size_t startpos;
|
||||
|
||||
|
||||
|
||||
for (i = 1; i < numfunctions; i++)
|
||||
if (!strcmp(name, strings + functions[i].s_name))
|
||||
break;
|
||||
if (i == numfunctions)
|
||||
{
|
||||
printf("Fatal Error: No function named \"%s\"\n", name);
|
||||
exit(1);
|
||||
}
|
||||
df = functions + i;
|
||||
altdone = statements + numstatements;
|
||||
for (j = i+1; j < numfunctions; j++)
|
||||
{
|
||||
if (functions[j].first_statement <= 0)
|
||||
continue;
|
||||
altdone = statements + functions[j].first_statement;
|
||||
break;
|
||||
}
|
||||
|
||||
findex = i;
|
||||
|
||||
start = *lastglobal;
|
||||
// if (dfpred->first_statement <= 0 && df->first_statement > 0)
|
||||
// start -= 1;
|
||||
end = df->parm_start;
|
||||
if (!end)
|
||||
{
|
||||
par = DecompileFindGlobal(name);
|
||||
if (par)
|
||||
end = par - globals;
|
||||
}
|
||||
*lastglobal = max(*lastglobal, end + df->locals);
|
||||
DecompilePreceedingGlobals(start, end, name);
|
||||
|
||||
/*
|
||||
* Check ''local globals''
|
||||
* Check ''local globals''
|
||||
*/
|
||||
|
||||
if (df->first_statement <= 0)
|
||||
|
@ -2967,6 +3064,7 @@ void DecompileDecompileFunctions(const char *origcopyright)
|
|||
vfile_t *f;
|
||||
char fname[512];
|
||||
int lastglob = 1;
|
||||
QCC_ddef_t *def;
|
||||
|
||||
DecompileCalcProfiles();
|
||||
|
||||
|
@ -2985,6 +3083,27 @@ void DecompileDecompileFunctions(const char *origcopyright)
|
|||
QCC_CatVFile(Decompileprogssrc, "//#pragma copyright \"%s\"\n", origcopyright);
|
||||
QCC_CatVFile(Decompileprogssrc, "\n", origcopyright);
|
||||
|
||||
def = DecompileFindGlobal("end_sys_fields");
|
||||
lastglob = def?def->ofs+1:1;
|
||||
if (lastglob != 1)
|
||||
{
|
||||
QC_snprintfz(synth_name, sizeof(synth_name), "sysdefs.qc");
|
||||
QC_snprintfz(fname, sizeof(fname), synth_name);
|
||||
if (!DecompileAlreadySeen(fname, &f))
|
||||
{
|
||||
printf("decompiling %s\n", fname);
|
||||
compilecb();
|
||||
QCC_CatVFile(Decompileprogssrc, "%s\n", fname);
|
||||
}
|
||||
if (!f)
|
||||
{
|
||||
printf("Fatal Error - Could not open \"%s\" for output.\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
Decompileofile = f;
|
||||
|
||||
DecompilePreceedingGlobals(1, lastglob, "");
|
||||
}
|
||||
|
||||
for (i = 1; i < numfunctions; i++)
|
||||
{
|
||||
|
|
|
@ -975,6 +975,7 @@ void QCC_PR_NewLine (pbool incomment);
|
|||
#define GDF_USED 64 //don't strip this, ever.
|
||||
#define GDF_BASICTYPE 128 //don't care about #merge types not being known correctly.
|
||||
#define GDF_SCANLOCAL 256 //don't use the locals hash table
|
||||
#define GDF_POSTINIT 512 //field must be initialised at the end of the compile (allows arrays to be extended later)
|
||||
QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||
QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||
void QCC_FreeTemp(QCC_sref_t t);
|
||||
|
|
|
@ -6826,94 +6826,6 @@ QCC_def_t *QCC_MemberInParentClass(char *name, QCC_type_t *clas)
|
|||
return QCC_MemberInParentClass(name, clas->parentclass);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//create fields for the types, instanciate the members to the fields.
|
||||
//we retouch the parents each time to guarentee polymorphism works.
|
||||
//FIXME: virtual methods will not work properly. Need to trace down to see if a parent already defined it
|
||||
void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas, int *basictypefield)
|
||||
{
|
||||
//we created fields for each class when we defined the actual classes.
|
||||
//we need to go through each member and match it to the offset of it's parent class, if overloaded, or create a new field if not..
|
||||
|
||||
//basictypefield is cleared before we do this
|
||||
//we emit the parent's fields first (every time), thus ensuring that we don't reuse parent fields on a child class.
|
||||
char membername[2048];
|
||||
unsigned int p;
|
||||
int a;
|
||||
unsigned int o;
|
||||
QCC_type_t *mt, *ft;
|
||||
QCC_def_t *f, *m;
|
||||
extern pbool verbose;
|
||||
if (clas->parentclass != type_entity) //parents MUST have all their fields set or inheritance would go crazy.
|
||||
QCC_PR_EmitFieldsForMembers(clas->parentclass, basictypefield);
|
||||
|
||||
for (p = 0; p < clas->num_parms; p++)
|
||||
{
|
||||
mt = clas->params[p].type;
|
||||
QC_snprintfz(membername, sizeof(membername), "%s::"MEMBERFIELDNAME, clas->name, clas->params[p].paramname);
|
||||
m = QCC_PR_GetDef(NULL, membername, NULL, false, 0, false);
|
||||
|
||||
f = QCC_MemberInParentClass(clas->params[p].paramname, clas->parentclass);
|
||||
if (f)
|
||||
{
|
||||
if (f->type->type != ev_field || typecmp(f->type->aux_type, mt))
|
||||
{
|
||||
char ct[256];
|
||||
char pt[256];
|
||||
TypeName(f->type->aux_type, pt, sizeof(pt));
|
||||
TypeName(mt, ct, sizeof(ct));
|
||||
QCC_PR_Warning(0, NULL, 0, "type mismatch on inheritance of %s::%s. %s vs %s", clas->name, clas->params[p].paramname, ct, pt);
|
||||
}
|
||||
if (!m)
|
||||
{
|
||||
basictypefield[mt->type] += 1;
|
||||
continue;
|
||||
}
|
||||
if (m->arraysize)
|
||||
QCC_Error(ERR_INTERNAL, "FTEQCC does not support overloaded arrays of members");
|
||||
a=0;
|
||||
for (o = 0; o < m->type->size; o++)
|
||||
((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+a*mt->size+f->ofs];
|
||||
continue;
|
||||
}
|
||||
|
||||
//came from parent class instead?
|
||||
if (!m)
|
||||
QCC_Error(ERR_INTERNAL, "field def missing for class member (%s::%s)", clas->name, clas->params[p].paramname);
|
||||
|
||||
for (a = 0; a < (m->arraysize?m->arraysize:1); a++)
|
||||
{
|
||||
/*if it was already set, don't go recursive and generate 500 fields for a one-member class that was inheritted from 500 times*/
|
||||
if (((int *)qcc_pr_globals)[0+a*mt->size+m->ofs])
|
||||
{
|
||||
++basictypefield[mt->type];
|
||||
continue;
|
||||
}
|
||||
|
||||
//we need the type in here so saved games can still work without saving ints as floats. (would be evil)
|
||||
ft = QCC_PR_FieldType(*basictypes[mt->type]);
|
||||
QC_snprintfz(membername, sizeof(membername), "::%s%i", basictypenames[mt->type], ++basictypefield[mt->type]);
|
||||
f = QCC_PR_GetDef(ft, membername, NULL, false, 0, GDF_CONST);
|
||||
if (!f)
|
||||
{
|
||||
//give it a location if this is the first class that uses this fieldspace
|
||||
f = QCC_PR_GetDef(ft, membername, NULL, true, 0, GDF_CONST);
|
||||
for (o = 0; o < m->type->size; o++)
|
||||
((int *)qcc_pr_globals)[o+f->ofs] = pr.size_fields + o;
|
||||
pr.size_fields += o;
|
||||
}
|
||||
|
||||
for (o = 0; o < m->type->size; o++)
|
||||
((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+f->ofs];
|
||||
|
||||
if (verbose)
|
||||
QCC_PR_Note(0, NULL, 0, "%s maps to %s", m->name, f->name);
|
||||
|
||||
f->references++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_sref_t ed)
|
||||
{ //go through clas, do the virtual thing only if the child class does not override.
|
||||
|
||||
|
@ -13641,11 +13553,14 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, const char *name, QCC_function_t *s
|
|||
if (!rootsymbol)
|
||||
{
|
||||
rootsymbol = first;
|
||||
rootsymbol->symboldata = qccHunkAlloc ((def->arraysize?def->arraysize:1) * type->size * sizeof(float));
|
||||
if (flags & GDF_POSTINIT)
|
||||
rootsymbol->symboldata = NULL;
|
||||
else
|
||||
rootsymbol->symboldata = qccHunkAlloc ((def->arraysize?def->arraysize:1) * type->size * sizeof(float));
|
||||
}
|
||||
|
||||
def->symbolheader = rootsymbol;
|
||||
def->symboldata = rootsymbol->symboldata + def->ofs;
|
||||
def->symboldata = (rootsymbol->symboldata?rootsymbol->symboldata + def->ofs:NULL);
|
||||
def->symbolsize = (def->arraysize?def->arraysize:1) * type->size;
|
||||
|
||||
if (type->type == ev_struct && (!arraysize || a>=0))
|
||||
|
|
|
@ -5619,19 +5619,24 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
d = QCC_PR_GetDef(NULL, parmname, NULL, 0, 0, GDF_CONST);
|
||||
if (!d)
|
||||
{ //don't go all weird with unioning generic fields
|
||||
QC_snprintfz(membername, sizeof(membername), "::%s%i", basictypenames[newparm->type], basicindex+1);
|
||||
QC_snprintfz(membername, sizeof(membername), "::*%s", basictypenames[newparm->type]);
|
||||
d = QCC_PR_GetDef(NULL, membername, NULL, 0, 0, GDF_CONST);
|
||||
if (!d)
|
||||
{
|
||||
d = QCC_PR_GetDef(QCC_PR_FieldType(*basictypes[newparm->type]), membername, NULL, 2, arraysize, GDF_CONST);
|
||||
for (i = 0; (unsigned int)i < newparm->size*(arraysize?arraysize:1); i++)
|
||||
d->symboldata[i]._int = pr.size_fields+i;
|
||||
pr.size_fields += i;
|
||||
d = QCC_PR_GetDef(QCC_PR_FieldType(*basictypes[newparm->type]), membername, NULL, 2, arraysize, GDF_CONST|GDF_POSTINIT);
|
||||
// for (i = 0; (unsigned int)i < newparm->size*(arraysize?arraysize:1); i++)
|
||||
// d->symboldata[i]._int = pr.size_fields+i;
|
||||
// pr.size_fields += i;
|
||||
|
||||
d->referenced = true; //always referenced, so you can inherit safely.
|
||||
}
|
||||
else if (d->arraysize != arraysize)
|
||||
QCC_PR_ParseError(ERR_INTERNAL, "array members are kinda limited, sorry. try rearranging them or adding padding for alignment\n"); //FIXME: add relocs to cope with this all of a type can then be contiguous and thus allow arrays.
|
||||
if (d->arraysize < basicindex+(arraysize?arraysize:1))
|
||||
{
|
||||
if (d->symboldata)
|
||||
QCC_PR_ParseError(ERR_INTERNAL, "array members are kinda limited, sorry. try rearranging them or adding padding for alignment\n"); //FIXME: add relocs to cope with this all of a type can then be contiguous and thus allow arrays.
|
||||
else
|
||||
d->arraysize = basicindex+(arraysize?arraysize:1);
|
||||
}
|
||||
}
|
||||
QCC_FreeDef(d);
|
||||
|
||||
|
@ -5639,7 +5644,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
//actually, that seems pointless.
|
||||
QC_snprintfz(membername, sizeof(membername), "%s::"MEMBERFIELDNAME, classname, parmname);
|
||||
// printf("define %s -> %s\n", membername, d->name);
|
||||
d = QCC_PR_DummyDef(fieldtype, membername, pr_scope, arraysize, d, 0, true, (isnull?0:GDF_CONST)|(opt_classfields?GDF_STRIP:0));
|
||||
d = QCC_PR_DummyDef(fieldtype, membername, pr_scope, arraysize, d, basicindex, true, (isnull?0:GDF_CONST)|(opt_classfields?GDF_STRIP:0));
|
||||
d->referenced = true; //always referenced, so you can inherit safely.
|
||||
}
|
||||
|
||||
|
|
|
@ -3145,6 +3145,27 @@ void QCC_PR_BeginCompilation (void *memory, int memsize)
|
|||
QCC_PrioritiseOpcodes();
|
||||
}
|
||||
|
||||
void QCC_PR_FinishFieldDef(QCC_def_t *d)
|
||||
{
|
||||
int i;
|
||||
if (d->symboldata)
|
||||
return; //nothing to finish
|
||||
|
||||
d->symbolsize = (d->arraysize?d->arraysize:1) * d->type->size;
|
||||
|
||||
if (d->symbolheader != d)
|
||||
{
|
||||
QCC_PR_FinishFieldDef(d->symbolheader);
|
||||
d->symboldata = d->symbolheader->symboldata + d->ofs;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->symboldata = qccHunkAlloc (d->symbolsize * sizeof(float));
|
||||
for (i = 0; i < d->symbolsize; i++)
|
||||
d->symboldata[i]._int = pr.size_fields++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PR_FinishCompilation
|
||||
|
@ -3172,6 +3193,8 @@ int QCC_PR_FinishCompilation (void)
|
|||
// check to make sure all functions prototyped have code
|
||||
for (d=pr.def_head.next ; d ; d=d->next)
|
||||
{
|
||||
if (d->type->type == ev_field && !d->symboldata)
|
||||
QCC_PR_FinishFieldDef(d);
|
||||
if (d->type->type == ev_function && d->constant)// function parms are ok
|
||||
{
|
||||
// f = G_FUNCTION(d->ofs);
|
||||
|
|
Loading…
Reference in a new issue