Fix qcc bug with removed continues/breaks editing other statements after removal.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5429 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b9fd3c01be
commit
d6d8d4c695
2 changed files with 100 additions and 7 deletions
|
@ -4269,6 +4269,70 @@ QCC_statement_t *QCC_PR_SimpleStatement ( QCC_opcode_t *op, QCC_sref_t var_a, QC
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Removes trailing statements, rewinding back to a known-safe position.
|
||||||
|
*/
|
||||||
|
void QCC_UngenerateStatements(int newstatementcount)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//forget any indexes to statements if those statements are going to go away...
|
||||||
|
for (i = 0; i < num_gotos; )
|
||||||
|
{
|
||||||
|
if (pr_gotos[i].statementno >= newstatementcount)
|
||||||
|
{
|
||||||
|
memmove(&pr_gotos[i], &pr_gotos[i+1], sizeof(*pr_gotos)*(num_gotos-(i+1)));
|
||||||
|
num_gotos--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_labels; )
|
||||||
|
{ //FIXME: stripping a label? erk?
|
||||||
|
if (pr_labels[i].statementno >= newstatementcount)
|
||||||
|
{
|
||||||
|
memmove(&pr_labels[i], &pr_labels[i+1], sizeof(*pr_labels)*(num_labels-(i+1)));
|
||||||
|
num_labels--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_breaks; )
|
||||||
|
{
|
||||||
|
if (pr_breaks[i] >= newstatementcount)
|
||||||
|
{
|
||||||
|
memmove(&pr_breaks[i], &pr_breaks[i+1], sizeof(*pr_breaks)*(num_breaks-(i+1)));
|
||||||
|
num_breaks--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_continues; )
|
||||||
|
{
|
||||||
|
if (pr_continues[i] >= newstatementcount)
|
||||||
|
{
|
||||||
|
memmove(&pr_continues[i], &pr_continues[i+1], sizeof(*pr_continues)*(num_continues-(i+1)));
|
||||||
|
num_continues--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_cases; )
|
||||||
|
{
|
||||||
|
if (pr_cases[i] >= newstatementcount)
|
||||||
|
{
|
||||||
|
memmove(&pr_cases[i], &pr_cases[i+1], sizeof(*pr_cases)*(num_cases-(i+1)));
|
||||||
|
memmove(&pr_casesref[i], &pr_casesref[i+1], sizeof(*pr_casesref)*(num_cases-(i+1)));
|
||||||
|
memmove(&pr_casesref2[i], &pr_casesref2[i+1], sizeof(*pr_casesref2)*(num_cases-(i+1)));
|
||||||
|
num_cases--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
numstatements = newstatementcount;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
PR_ParseImmediate
|
PR_ParseImmediate
|
||||||
|
@ -5363,7 +5427,7 @@ static QCC_sref_t QCC_PR_Inline(QCC_sref_t fdef, QCC_ref_t **arglist, unsigned i
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.result.cast)
|
if (!ctx.result.cast)
|
||||||
numstatements = statements; //on failure, remove the extra statements
|
QCC_UngenerateStatements(statements);
|
||||||
else
|
else
|
||||||
{ //on success, make sure the args were freed
|
{ //on success, make sure the args were freed
|
||||||
while (argcount-->0)
|
while (argcount-->0)
|
||||||
|
@ -11071,7 +11135,7 @@ void QCC_PR_ParseStatement (void)
|
||||||
QCC_PR_ParseStatement ();
|
QCC_PR_ParseStatement ();
|
||||||
if (striptruth && oldlab == num_labels)
|
if (striptruth && oldlab == num_labels)
|
||||||
{
|
{
|
||||||
numstatements = oldnumst;
|
QCC_UngenerateStatements(oldnumst);
|
||||||
patch1 = NULL;
|
patch1 = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -11096,7 +11160,7 @@ void QCC_PR_ParseStatement (void)
|
||||||
if (stripfalse && oldlab == num_labels)
|
if (stripfalse && oldlab == num_labels)
|
||||||
{
|
{
|
||||||
patch2 = NULL;
|
patch2 = NULL;
|
||||||
numstatements = oldnumst;
|
QCC_UngenerateStatements(oldnumst);
|
||||||
|
|
||||||
if (patch1)
|
if (patch1)
|
||||||
patch1->b.ofs = &statements[numstatements] - patch1;
|
patch1->b.ofs = &statements[numstatements] - patch1;
|
||||||
|
@ -11118,7 +11182,7 @@ void QCC_PR_ParseStatement (void)
|
||||||
if (stripfalse && oldlab == num_labels)
|
if (stripfalse && oldlab == num_labels)
|
||||||
{
|
{
|
||||||
patch2 = NULL;
|
patch2 = NULL;
|
||||||
numstatements = oldnumst;
|
QCC_UngenerateStatements(oldnumst);
|
||||||
|
|
||||||
if (patch1)
|
if (patch1)
|
||||||
patch1->b.ofs = &statements[numstatements] - patch1;
|
patch1->b.ofs = &statements[numstatements] - patch1;
|
||||||
|
@ -13231,7 +13295,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
|
||||||
{ //FIXME: should probably always take this path, but kinda pointless until we have relocs for defs
|
{ //FIXME: should probably always take this path, but kinda pointless until we have relocs for defs
|
||||||
QCC_RemapLockedTemps(f->code, numstatements);
|
QCC_RemapLockedTemps(f->code, numstatements);
|
||||||
QCC_Marshal_Locals(f->code, numstatements);
|
QCC_Marshal_Locals(f->code, numstatements);
|
||||||
QCC_WriteAsmFunction(f, f->code, f->firstlocal); //FIXME: this will print the entire function, not just the part that we added. and we'll print it all again later, too. should probably make it a function attribute that we check at the end.
|
// QCC_WriteAsmFunction(f, f->code, f->firstlocal); //FIXME: this will print the entire function, not just the part that we added. and we'll print it all again later, too. should probably make it a function attribute that we check at the end.
|
||||||
|
|
||||||
f->numstatements = numstatements - f->code;
|
f->numstatements = numstatements - f->code;
|
||||||
f->statements = qccHunkAlloc(sizeof(*statements)*f->numstatements);
|
f->statements = qccHunkAlloc(sizeof(*statements)*f->numstatements);
|
||||||
|
|
|
@ -395,6 +395,7 @@ public:
|
||||||
if (c)
|
if (c)
|
||||||
return; //already in there.
|
return; //already in there.
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
c = new filenode_s();
|
c = new filenode_s();
|
||||||
c->name = strdup(filename);
|
c->name = strdup(filename);
|
||||||
c->parent = p;
|
c->parent = p;
|
||||||
|
@ -402,6 +403,7 @@ public:
|
||||||
p->children = cpprealloc(p->children, sizeof(*p->children)*(p->numchildren+1));
|
p->children = cpprealloc(p->children, sizeof(*p->children)*(p->numchildren+1));
|
||||||
p->children[p->numchildren] = c;
|
p->children[p->numchildren] = c;
|
||||||
p->numchildren++;
|
p->numchildren++;
|
||||||
|
endResetModel();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -925,6 +927,29 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool annotate(const char *line)
|
||||||
|
{
|
||||||
|
auto filename = line+6;
|
||||||
|
auto filenameend = strchr(filename, ':');
|
||||||
|
if (!filenameend) return false;
|
||||||
|
auto linenum = atoi(filenameend+1);
|
||||||
|
line = strchr(filenameend+1, ':')+1;
|
||||||
|
if (!line) return false;
|
||||||
|
if (strncmp(curdoc->fname, filename, filenameend-filename) || curdoc->fname[filenameend-filename])
|
||||||
|
{
|
||||||
|
auto d = FindFile(filename);
|
||||||
|
if (d)
|
||||||
|
{
|
||||||
|
curdoc = d;
|
||||||
|
s->setDocument(d->doc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false; //some other file that we're not interested in
|
||||||
|
}
|
||||||
|
|
||||||
|
s->annotate(linenum-1, s->annotation(linenum) + line + "\n", 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool saveDocument(document_s *d)
|
bool saveDocument(document_s *d)
|
||||||
{
|
{
|
||||||
|
@ -1848,7 +1873,12 @@ int GUIprintf(const char *msg, ...)
|
||||||
QString s = l.mid(0, idx);
|
QString s = l.mid(0, idx);
|
||||||
l = l.mid(idx+1);
|
l = l.mid(idx+1);
|
||||||
|
|
||||||
if (s.contains(": error") || s.contains(": werror") || !s.mid(0,5).compare("error", Qt::CaseInsensitive))
|
if (!s.mid(0, 6).compare("code: "))
|
||||||
|
{
|
||||||
|
mainwnd->docs.annotate(s.toUtf8().data());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (s.contains(": error") || s.contains(": werror") || !s.mid(0,5).compare("error", Qt::CaseInsensitive))
|
||||||
mainwnd->log.setTextColor(QColor(255, 0, 0));
|
mainwnd->log.setTextColor(QColor(255, 0, 0));
|
||||||
else if (s.contains(": warning"))
|
else if (s.contains(": warning"))
|
||||||
mainwnd->log.setTextColor(QColor(128, 128, 0));
|
mainwnd->log.setTextColor(QColor(128, 128, 0));
|
||||||
|
@ -1892,7 +1922,6 @@ void documentlist::EditFile(document_s *c, const char *filename, int linenum, bo
|
||||||
if (!CreateDocument(c))
|
if (!CreateDocument(c))
|
||||||
{
|
{
|
||||||
delete(c);
|
delete(c);
|
||||||
numdocuments--;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue