📄 stmt.c
字号:
#include "c.h"
#define SWSIZE 512
#define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
struct swtch {
Symbol sym;
int lab;
Symbol deflab;
int ncases;
int size;
int *values;
Symbol *labels;
};
struct code codehead = { Start };
Code codelist = &codehead;
float density = (float)0.5;
Table stmtlabs;
static int foldcond (Tree e1, Tree e2,Symbol *psimpleIndex);
static void branch ARGS((int));
static void caselabel ARGS((Swtch, int, int));
static Tree cmp ARGS((int, Symbol, int, int));
static Tree conditional ARGS((int));
static void dostmt ARGS((int, Swtch, int));
static int equal ARGS((Symbol, Symbol));
static void forstmt ARGS((int, Swtch, int));
static void ifstmt ARGS((int, int, Swtch, int));
static Symbol localaddr ARGS((Tree));
static void stmtlabel ARGS((void));
static void swcode ARGS((Swtch, int *, int, int));
static void swgen ARGS((Swtch));
static void swstmt ARGS((int, int, int));
static void whilestmt ARGS((int, Swtch, int));
Code code(int kind)
{
Code cp;
if (kind > Start) {
for (cp = codelist; cp->kind < Label; )
cp = cp->prev;
if (cp->kind == Jump || cp->kind == Switch)
warning(StrTab[57]);// <unreachable code\n>
}
NEW(cp, FUNC);
cp->kind = kind;
cp->prev = codelist;
cp->next = NULL;
codelist->next = cp;
codelist = cp;
return cp;
}
void addlocal(Symbol p)
{
if (!p->defined) {
code(Local)->u.var = p;
p->defined = 1;
p->scope = level;
}
}
Code definept(Coordinate *p,int type)
{
Code cp = code(Defpoint);
cp->u.point.statement = StatementCount++;
cp->u.point.src = p ? *p : src;
cp->u.point.point = npoints;
cp->u.point.type = type;
if (ncalled > 0) {
int n = findcount(cp->u.point.src.file,
cp->u.point.src.x, cp->u.point.src.y);
if (n >= 0)
refinc = (float)n/ncalled;
}
if (events.points)
{
Tree e = NULL;
apply(events.points, &cp->u.point.src, &e);
if (e)
listnodes(e, 0, 0);
}
if (glevel > 2) locus(identifiers, &cp->u.point.src);
return cp;
}
void statement(int loop,Swtch swp,int lev)
{
float ref = refinc;
if (Aflag >= 2 && lev == 15)
warning(StrTab[58]);// <more than 15 levels of nested statements\n>
switch (t) {
case IF: ifstmt(genlabel(2), loop, swp, lev + 1);
break;
case WHILE: whilestmt(genlabel(3), swp, lev + 1); break;
case DO: dostmt(genlabel(3), swp, lev + 1); expect(';');
break;
case FOR: forstmt(genlabel(4), swp, lev + 1);
break;
case BREAK: walk(NULL, 0, 0);
definept(NULL,POINT_BREAK);
if (swp && swp->lab > loop)
branch(swp->lab + 1);
else if (loop)
branch(loop + 2);
else
error(StrTab[59]);// <illegal break statement\n>
t = gettok(); expect(';');
break;
case CONTINUE: walk(NULL, 0, 0);
definept(NULL,POINT_GOTO);
if (loop)
branch(loop + 1);
else
error(StrTab[60]);// <illegal continue statement\n>
t = gettok(); expect(';');
break;
case SWITCH: swstmt(loop, genlabel(2), lev + 1);
break;
case CASE: {
int lab = genlabel(1);
if (swp == NULL)
error(StrTab[61]);// <illegal case label\n>
definelab(lab);
while (t == CASE) {
static char stop[] = { IF, ID, 0 };
Tree p;
t = gettok();
p = constexpr(0);
if (generic(p->op) == CNST && isint(p->type)) {
if (swp) {
needconst++;
p = cast(p, swp->sym->type);
needconst--;
caselabel(swp, p->u.v.i, lab);
}
} else
error(StrTab[62]);// <case label must be a constant integer expression\n>
test(':', stop);
}
definept(NULL,POINT_CASE);
statement(loop, swp, lev);
} break;
case DEFAULT: if (swp == NULL)
error(StrTab[63]);// <illegal default label\n>
else if (swp->deflab)
error(StrTab[64]);// <extra default label\n>
else {
swp->deflab = findlabel(swp->lab);
definelab(swp->deflab->u.l.label);
}
t = gettok();
expect(':');
statement(loop, swp, lev); break;
case RETURN: {
Type rty = freturn(cfunc->type);
t = gettok();
definept(NULL,POINT_RETURN);
if (t != ';')
if (rty == voidtype) {
error(StrTab[65]);// <extraneous return value\n>
expr(0);
retcode(NULL);
} else
retcode(expr(0));
else {
if (rty != voidtype
&& (rty != inttype || Aflag >= 1))
warning(StrTab[66]);// <missing return value\n>
retcode(NULL);
}
branch(cfunc->u.f.label);
} expect(';');
break;
case '{':
compound(loop, swp, lev + 1);
break;
case ';': definept(NULL,0); t = gettok(); break;
case GOTO: walk(NULL, 0, 0);
definept(NULL,POINT_GOTO);
FunctionInfo.hasgotos = 1;
t = gettok();
if (t == ID) {
Symbol p = lookup(token, stmtlabs);
if (p == NULL) {
p = install(token, &stmtlabs, 0, FUNC);
p->scope = LABELS;
p->u.l.label = genlabel(1);
p->src = src;
}
use(p, src);
branch(p->u.l.label);
t = gettok();
} else
error(StrTab[67]); expect(';');// <missing label in goto\n>
break;
case ID: if (getchr() == ':') {
stmtlabel();
statement(loop, swp, lev);
break;
}
default: definept(NULL,0);
if (kind[t] != ID) {
error(StrTab[68]);// <unrecognized statement\n>
t = gettok();
} else {
Tree e = expr0(0);
listnodes(e, 0, 0);
// if (nodecount == 0 || nodecount > 2000)
// walk(NULL, 0, 0);
// else if (glevel)
walk(NULL, 0, 0);
deallocate(STMT);
} expect(';');
break;
}
if (kind[t] != IF && kind[t] != ID
&& t != '}' && t != EOI) {
static char stop[] = { IF, ID, '}', 0 };
error(StrTab[69]);// <illegal statement termination\n>
skipto(0, stop);
}
refinc = ref;
}
static void ifstmt(int lab,int loop,Swtch swp,int lev)
{
Tree condTree;
t = gettok();
expect('(');
definept(NULL,POINT_STARTIF);
condTree = conditional(')');
walk(condTree, 0, lab);
refinc /= (float)2.0;
statement(loop, swp, lev);
if (t == ELSE) {
branch(lab + 1);
t = gettok();
definelab(lab);
definept(NULL,POINT_ELSE);
statement(loop, swp, lev);
if (findlabel(lab + 1)->ref)
definelab(lab + 1);
} else
definelab(lab);
definept(NULL,POINT_ENDIF);
}
static Tree conditional(int tok)
{
Tree p = expr(tok);
if (Aflag > 1 && isfunc(p->type))
warning(StrTab[70],// <%s used in a conditional expression\n>
funcname(p));
return cond(p);
}
static void stmtlabel(void)
{
Symbol p = lookup(token, stmtlabs);
if (p == NULL) {
p = install(token, &stmtlabs, 0, FUNC);
p->scope = LABELS;
p->u.l.label = genlabel(1);
p->src = src;
}
if (p->defined)
error(StrTab[71], p->name, &p->src);// <redefinition of label `%s' previously defined at %w\n>
p->defined = 1;
definelab(p->u.l.label);
t = gettok();
expect(':');
}
static void forstmt(int lab,Swtch swp,int lev)
{
int once = 0;
Tree e1 = NULL, e2 = NULL, e3 = NULL;
Coordinate pt2, pt3;
int start;
Symbol simpleIndex=NULL;
float indexUsage=0.0;
Node n1=NULL;
start = StatementCount;
t = gettok();
expect('(');
definept(NULL,POINT_STARTFOR);
if (kind[t] == ID)
e1 = texpr(expr0, ';', FUNC);
else
expect(';');
walk(e1, 0, 0);
pt2 = src;
refinc *= (float)10.0;
if (kind[t] == ID)
e2 = texpr(conditional, ';', FUNC);
else
expect(';');
pt3 = src;
if (kind[t] == ID)
e3 = texpr(expr0, ')', FUNC);
else {
static char stop[] = { IF, ID, '}', 0 };
test(')', stop);
}
if (e2) {
once = foldcond(e1, e2,&simpleIndex);
if (e1)
n1 = e1->node;
if (!once)
branch(lab + 3);
}
definelab(lab);
statement(lab, swp, lev);
definelab(lab + 1);
definept(&pt3,0);
if (e3)
walk(e3, 0, 0);
if (e2) {
if (!once)
definelab(lab + 3);
definept(&pt2,0);
walk(e2, lab, 0);
} else {
definept(&pt2,0);
branch(lab);
}
if (OptimizeFlag) {
ExtendDomain(level,start);
}
if (findlabel(lab + 2)->ref)
definelab(lab + 2);
definept(NULL,POINT_ENDFOR);
}
static void swstmt(int loop,int lab,int lev)
{
Tree e,exprTree;
struct swtch sw;
Code head, tail;
t = gettok();
expect('(');
definept(NULL,POINT_STARTSWITCH);
e = expr(')');
if (!isint(e->type)) {
error(StrTab[72],// <illegal type `%t' in switch expression\n>
e->type);
e = retype(e, inttype);
}
e = cast(e, promote(e->type));
if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
&& (e->kids[0]->u.sym->type == e->type ||
isenum(e->kids[0]->u.sym->type))
&& !isvolatile(e->kids[0]->u.sym->type)) {
if (OptimizeFlag) {
sw.sym = genident(REGISTER, e->type, level);
addlocal(sw.sym);
exprTree = asgn(sw.sym,e);
walk(exprTree, 0, 0);
}
else {
sw.sym = e->kids[0]->u.sym;
walk(NULL,0,0);
}
} else {
sw.sym = genident(REGISTER, e->type, level);
addlocal(sw.sym);
exprTree = asgn(sw.sym,e);
walk(exprTree, 0, 0);
}
if (OptimizeFlag)
sw.sym->x.switchSymbol = 1;
head = code(Switch);
sw.lab = lab;
sw.deflab = NULL;
sw.ncases = 0;
sw.size = SWSIZE;
sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
refinc /= (float)10.0;
statement(loop, &sw, lev);
if (sw.deflab == NULL) {
sw.deflab = findlabel(lab);
definelab(lab);
if (sw.ncases == 0)
warning(StrTab[73]);// <switch statement with no cases\n>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -