Try to fix some qcc bugs.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6182 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-02-07 14:34:02 +00:00
parent 88858f7698
commit c6e00068db
3 changed files with 58 additions and 17 deletions

View file

@ -220,6 +220,7 @@ QCC_sref_t QCC_PR_ParseArrayPointer (QCC_sref_t d, pbool allowarrayassign, pbool
QCC_sref_t QCC_LoadFromArray(QCC_sref_t base, QCC_sref_t index, QCC_type_t *t, pbool preserve);
void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags);
static pbool QCC_RefNeedsCalls(QCC_ref_t *ref);
QCC_ref_t *QCC_DefToRef(QCC_ref_t *ref, QCC_sref_t def); //ref is a buffer to write into, to avoid excessive allocs
QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps);
QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags);
@ -6207,17 +6208,17 @@ static void QCC_VerifyArgs_setviewprop (const char *funcname, QCC_ref_t **arglis
{
if (argtypes[i].n == vf)
{
if (argcount >= 2 && argtypes[i].t1 != arglist[1]->cast->type)
if (argcount >= 2 && argtypes[i].t1 != ((arglist[1]->cast->type==ev_boolean)?arglist[1]->cast->parentclass->type:arglist[1]->cast->type))
{
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s(%s, ...): expected %s, got %s", funcname, argtypes[i].name, basictypenames[argtypes[i].t1], TypeName(arglist[1]->cast, temp, sizeof(temp)));
return;
}
if (argcount >= 3 && argtypes[i].t2 != arglist[2]->cast->type)
if (argcount >= 3 && argtypes[i].t2 != ((arglist[2]->cast->type==ev_boolean)?arglist[2]->cast->parentclass->type:arglist[2]->cast->type))
{
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s(%s, X, ...): expected %s, got %s", funcname, argtypes[i].name, basictypenames[argtypes[i].t2], TypeName(arglist[2]->cast, temp, sizeof(temp)));
return;
}
if (argcount >= 4 && argtypes[i].t3 != arglist[3]->cast->type)
if (argcount >= 4 && argtypes[i].t3 != ((arglist[3]->cast->type==ev_boolean)?arglist[3]->cast->parentclass->type:arglist[3]->cast->type))
{
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s(%s, X, Y, ...): expected %s, got %s", funcname, argtypes[i].name, basictypenames[argtypes[i].t3], TypeName(arglist[3]->cast, temp, sizeof(temp)));
return;
@ -7953,12 +7954,13 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f
}
}
if (p)
if (p && typecmp(e->cast, p))
{
if (typecmp(e->cast, p))
{
e = QCC_PR_BuildRef(&parambuf[arg], REF_GLOBAL, QCC_EvaluateCast(QCC_RefToDef(e, true), p, true), nullsref, p, true);
}
e = QCC_PR_BuildRef(&parambuf[arg], REF_GLOBAL, QCC_EvaluateCast(QCC_RefToDef(e, true), p, true), nullsref, p, true);
}
else if (QCC_RefNeedsCalls(e))
{
e = QCC_PR_BuildRef(&parambuf[arg], REF_GLOBAL, QCC_RefToDef(e, true), nullsref, p, true);
}
param[arg] = e;
@ -11381,6 +11383,33 @@ QCC_sref_t QCC_LoadFromArray(QCC_sref_t base, QCC_sref_t index, QCC_type_t *t, p
return base;
}
static pbool QCC_RefNeedsCalls(QCC_ref_t *ref)
{
if (ref->type == REF_ACCESSOR)
return true;
if (ref->type == REF_ARRAY)
{
if (ref->index.cast)
{
int accel;
if (QCC_SRef_EvalConst(ref->index))
return false; //can short it.
if (ref->index.cast->type != ev_float || ref->cast->type != ref->base.cast->type)
accel = 2;
else
accel = 1;
if (accel == 2 && !QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
accel = QCC_OPCodeValid(&pr_opcodes[OP_GLOAD_F])&&!ref->base.sym->temp?3:1;
if (accel == 1 && (!ref->base.sym->arraylengthprefix || !QCC_OPCodeValid(&pr_opcodes[OP_FETCH_GBL_F])))
accel = QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F])?2:0;
return !accel; //if we've no acceleration, we need a call.
}
}
return false;
}
//reads a ref as required
//the result sref should ALWAYS be freed, even if freetemps is set.
QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps)
@ -12771,7 +12800,7 @@ QCC_statement_t *QCC_Generate_OP_IF(QCC_sref_t e, pbool preserve)
break;
}
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[op], e, nullsref, &st, flags|STFL_DISCARDRESULT));
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[op], e, nullsref, &st, flags));
return st;
}
QCC_statement_t *QCC_Generate_OP_IFNOT(QCC_sref_t e, pbool preserve)
@ -12844,7 +12873,7 @@ QCC_statement_t *QCC_Generate_OP_IFNOT(QCC_sref_t e, pbool preserve)
break;
}
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[op], e, nullsref, &st, flags|STFL_DISCARDRESULT));
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[op], e, nullsref, &st, flags));
return st;
}
@ -17239,7 +17268,7 @@ QCC_sref_t QCC_PR_ParseInitializerType_Internal(int arraysize, QCC_def_t *basede
if (!basedef && def.sym->temp)
{ //skip the store-to-temp
QCC_FreeTemp(def);
// QCC_FreeTemp(def);
tmp.cast = def.cast;
return tmp;
}

View file

@ -1679,7 +1679,9 @@ public:
gb->setLayout(layout);
rightlayout->addWidget(gb);
rightlayout->addWidget(new QTextEdit());
auto argbox = new QTextEdit();
argbox->setText(parameters);
rightlayout->addWidget(argbox);
}
toplayout->addLayout(leftlayout);
toplayout->addLayout(rightlayout);
@ -1880,7 +1882,7 @@ private:
debugrebuild->setShortcuts(QKeySequence::listFromString("F7"));
connect(debugrebuild, &QAction::triggered, [=]()
{
RunCompiler("", false);
RunCompiler(parameters, false);
});
auto debugsetnext = new QAction(tr("Set Next Statement"), this);
debugMenu->addAction(debugsetnext);
@ -2303,13 +2305,23 @@ int main(int argc, char* argv[])
{
size_t argl = 1;
for (int i = 1; i < argc; i++)
argl += strlen(argv[i])+1;
argl += strlen(argv[i])+3;
cmdlineargs = (char*)malloc(argl);
argl = 0;
for (int i = 1; i < argc; i++)
{
memcpy(cmdlineargs+argl, argv[i], strlen(argv[i]));
argl += strlen(argv[i]);
if (strchr(argv[i], ' '))
{
cmdlineargs[argl++] = '\"';
memcpy(cmdlineargs+argl, argv[i], strlen(argv[i]));
argl += strlen(argv[i]);
cmdlineargs[argl++] = '\"';
}
else
{
memcpy(cmdlineargs+argl, argv[i], strlen(argv[i]));
argl += strlen(argv[i]);
}
cmdlineargs[argl++] = ' ';
}
cmdlineargs[argl] = 0;

View file

@ -11636,7 +11636,7 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"gp_rumble", PF_Fixme, 0, 0, 0, 0, D("void(float devid, float amp_low, float amp_high, float duration)", "Sends a single rumble event to the game-pad specified in devid. Every time you call this, the previous effect is cancelled out.")},
{"gp_rumbletriggers", PF_Fixme, 0, 0, 0, 0, D("void(float devid, float left, float right, float duration)", "Makes the analog triggers rumble of the specified game-pad, like gp_rumble() one call cancels out the previous one on the device.")},
{"gp_setledcolor", PF_Fixme, 0, 0, 0, 0, D("void(float devid, vector color)", "Updates the game-pad LED color.")},
{"gp_settriggerfx", PF_Fixme, 0, 0, 0, 0, D("void(float devid, const void *data, int size)", "Sends a specific effect packet to the controller. On the PlayStation 5's DualSense that can adjust the tension on the analog triggers.")},
{"gp_settriggerfx", PF_Fixme, 0, 0, 0, 0, D("void(float devid, /*const*/ void *data, int size)", "Sends a specific effect packet to the controller. On the PlayStation 5's DualSense that can adjust the tension on the analog triggers.")},
//END EXT_CSQC
{"memalloc", PF_memalloc, 0, 0, 0, 384, D("__variant*(int size)", "Allocate an arbitary block of memory")},