Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

stmt.c File Reference

#include "c.h"

Include dependency graph for stmt.c:

Include dependency graph

Go to the source code of this file.

Defines

#define den(i, j)   ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
#define SWSIZE   512

Functions

void addlocal (Symbol p)
void branch (int lab)
void caselabel (Swtch, long, int)
void cmp (int, Symbol, long, int)
Code code (int kind)
Tree conditional (int)
void definelab (int lab)
void definept (Coordinate *p)
void dostmt (int, Swtch, int)
int equal (Symbol, Symbol)
void equatelab (Symbol old, Symbol new)
int foldcond (Tree e1, Tree e2)
void forstmt (int, Swtch, int)
void ifstmt (int, int, Swtch, int)
Node jump (int lab)
Symbol localaddr (Tree)
int reachable (int kind)
void retcode (Tree p)
void statement (int loop, Swtch swp, int lev)
void stmtlabel (void)
void swcode (Swtch swp, int b[], int lb, int ub)
void swgen (Swtch swp)
void swstmt (int, int, int)
void whilestmt (int, Swtch, int)

Variables

code codehead = { Start }
Code codelist = &codehead
float density = 0.5
Table stmtlabs


Define Documentation

#define den i,
j   )     ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
 

Definition at line 6 of file stmt.c.

Referenced by PM_CrashLand(), and swgen().

#define SWSIZE   512
 

Definition at line 4 of file stmt.c.

Referenced by swstmt().


Function Documentation

void addlocal Symbol  p  ) 
 

Definition at line 51 of file stmt.c.

References code(), symbol::defined, p, symbol::scope, Symbol, code::u, and code::var.

Referenced by addrtree(), doLocal(), listnodes(), retcode(), swstmt(), tracecall(), and undag().

00051                         {
00052     if (!p->defined) {
00053         code(Local)->u.var = p;
00054         p->defined = 1;
00055         p->scope = level;
00056     }
00057 }

Here is the call graph for this function:

void branch int  lab  ) 
 

Definition at line 565 of file stmt.c.

References assert, code(), Code, codelist, cp, equal(), equatelab(), findlabel(), code::forest, jump(), code::kind, LABEL, code::next, NULL, node::op, p, code::prev, symbol::ref, Symbol, node::syms, code::u, V, walk(), and warning().

Referenced by forstmt(), ifstmt(), statement(), swcode(), swstmt(), and whilestmt().

00565                      {
00566     Code cp;
00567     Symbol p = findlabel(lab);
00568 
00569     assert(lab);
00570     walk(NULL, 0, 0);
00571     code(Label)->u.forest = jump(lab);
00572     for (cp = codelist->prev; cp->kind < Label; )
00573         cp = cp->prev;
00574     while (   cp->kind == Label
00575            && cp->u.forest->op == LABEL+V
00576            && !equal(cp->u.forest->syms[0], p)) {
00577         equatelab(cp->u.forest->syms[0], p);
00578         assert(cp->next);
00579         assert(cp->prev);
00580         cp->prev->next = cp->next;
00581         cp->next->prev = cp->prev;
00582         cp = cp->prev;
00583         while (cp->kind < Label)
00584             cp = cp->prev;
00585     }
00586     if (cp->kind == Jump || cp->kind == Switch) {
00587         p->ref--;
00588         codelist->prev->next = NULL;
00589         codelist = codelist->prev;
00590     } else {
00591         codelist->kind = Jump;
00592         if (cp->kind == Label
00593         &&  cp->u.forest->op == LABEL+V
00594         &&  equal(cp->u.forest->syms[0], p))
00595             warning("source code specifies an infinite loop");
00596     }
00597 }

Here is the call graph for this function:

void caselabel Swtch  ,
long  ,
int 
[static]
 

Definition at line 363 of file stmt.c.

References Aflag, error(), findlabel(), FUNC, k, swtch::labels, labs(), swtch::ncases, newarray, swtch::size, Swtch, Symbol, vals, swtch::values, and warning().

00363                                                     {
00364     int k;
00365 
00366     if (swp->ncases >= swp->size)
00367         {
00368         long   *vals = swp->values;
00369         Symbol *labs = swp->labels;
00370         swp->size *= 2;
00371         swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
00372         swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
00373         for (k = 0; k < swp->ncases; k++) {
00374             swp->values[k] = vals[k];
00375             swp->labels[k] = labs[k];
00376         }
00377         }
00378     k = swp->ncases;
00379     for ( ; k > 0 && swp->values[k-1] >= val; k--) {
00380         swp->values[k] = swp->values[k-1];
00381         swp->labels[k] = swp->labels[k-1];
00382     }
00383     if (k < swp->ncases && swp->values[k] == val)
00384         error("duplicate case label `%d'\n", val);
00385     swp->values[k] = val;
00386     swp->labels[k] = findlabel(lab);
00387     ++swp->ncases;
00388     if (Aflag >= 2 && swp->ncases == 258)
00389         warning("more than 257 cases in a switch\n");
00390 }

Here is the call graph for this function:

void cmp int  ,
Symbol  ,
long  ,
int 
[static]
 

Definition at line 474 of file stmt.c.

References cast(), cnsttree(), eqtree(), idtree(), listnodes(), n, op, p, signedint(), Symbol, symbol::type, and Type.

00474                                                    {
00475     Type ty = signedint(p->type);
00476 
00477     listnodes(eqtree(op,
00478             cast(idtree(p), ty),
00479             cnsttree(ty, n)),
00480         lab, 0);
00481 }

Here is the call graph for this function:

Code code int  kind  ) 
 

Definition at line 25 of file stmt.c.

References Code, codelist, cp, FUNC, code::kind, kind, NEW, code::next, code::prev, reachable(), and warning().

Referenced by addlocal(), addrtree(), branch(), compound(), definelab(), definept(), doAddress(), doBlockbeg(), doBlockend(), doForest(), swcode(), swstmt(), and walk().

00025                     {
00026     Code cp;
00027 
00028     if (!reachable(kind))
00029         warning("unreachable code\n");
00030 
00031     NEW(cp, FUNC);
00032     cp->kind = kind;
00033     cp->prev = codelist;
00034     cp->next = NULL;
00035     codelist->next = cp;
00036     codelist = cp;
00037     return cp;
00038 }

Here is the call graph for this function:

Tree conditional int   )  [static]
 

Definition at line 237 of file stmt.c.

References Aflag, cond(), expr(), funcname(), isfunc, p, Tree, tree::type, and warning().

Referenced by dostmt(), forstmt(), ifstmt(), and whilestmt().

00237                                  {
00238     Tree p = expr(tok);
00239 
00240     if (Aflag > 1 && isfunc(p->type))
00241         warning("%s used in a conditional expression\n",
00242             funcname(p));
00243     return cond(p);
00244 }

Here is the call graph for this function:

void definelab int  lab  ) 
 

Definition at line 534 of file stmt.c.

References ADDRG, assert, code(), Code, codelist, cp, findlabel(), code::forest, node::kids, code::kind, symbol::l, symbol::label, LABEL, newnode(), code::next, NULL, node::op, P, p, code::prev, symbol::ref, specific, Symbol, node::syms, symbol::u, code::u, V, and walk().

Referenced by dostmt(), forstmt(), funcdefn(), ifstmt(), statement(), stmtlabel(), swcode(), swstmt(), and whilestmt().

00534                         {
00535     Code cp;
00536     Symbol p = findlabel(lab);
00537 
00538     assert(lab);
00539     walk(NULL, 0, 0);
00540     code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
00541     for (cp = codelist->prev; cp->kind <= Label; )
00542         cp = cp->prev;
00543     while (   cp->kind == Jump
00544            && cp->u.forest->kids[0]
00545            && specific(cp->u.forest->kids[0]->op) == ADDRG+P
00546            && cp->u.forest->kids[0]->syms[0] == p) {
00547         assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
00548         p->ref--;
00549         assert(cp->next);
00550         assert(cp->prev);
00551         cp->prev->next = cp->next;
00552         cp->next->prev = cp->prev;
00553         cp = cp->prev;
00554         while (cp->kind <= Label)
00555             cp = cp->prev;
00556     }
00557 }

Here is the call graph for this function:

void definept Coordinate p  ) 
 

Definition at line 58 of file stmt.c.

References apply(), code(), Code, Coordinate, cp, e, events, coord::file, findcount(), glevel, identifiers, listnodes(), locus(), n, ncalled, p, code::point, Events::points, reachable(), refinc, code::src, Tree, code::u, coord::x, and coord::y.

Referenced by compound(), dcllocal(), dostmt(), forstmt(), ifstmt(), statement(), swstmt(), and whilestmt().

00058                              {
00059     Code cp = code(Defpoint);
00060 
00061     cp->u.point.src = p ? *p : src;
00062     cp->u.point.point = npoints;
00063     if (ncalled > 0) {
00064         int n = findcount(cp->u.point.src.file,
00065             cp->u.point.src.x, cp->u.point.src.y);
00066         if (n > 0)
00067             refinc = (float)n/ncalled;
00068     }
00069     if (glevel > 2) locus(identifiers, &cp->u.point.src);
00070     if (events.points && reachable(Gen))
00071         {
00072             Tree e = NULL;
00073             apply(events.points, &cp->u.point.src, &e);
00074             if (e)
00075                 listnodes(e, 0, 0);
00076         }
00077 }

Here is the call graph for this function:

void dostmt int  ,
Swtch  ,
int 
[static]
 

Definition at line 611 of file stmt.c.

References conditional(), definelab(), definept(), expect(), findlabel(), gettok(), NULL, symbol::ref, refinc, statement(), Swtch, t, and walk().

Referenced by statement().

00611                                                 {
00612     refinc *= 10.0;
00613     t = gettok();
00614     definelab(lab);
00615     statement(lab, swp, lev);
00616     definelab(lab + 1);
00617     expect(WHILE);
00618     expect('(');
00619     definept(NULL);
00620     walk(conditional(')'), lab, 0);
00621     if (findlabel(lab + 2)->ref)
00622         definelab(lab + 2);
00623 }

Here is the call graph for this function:

int equal Symbol  ,
Symbol 
[static]
 

Definition at line 603 of file stmt.c.

References assert, symbol::equatedto, symbol::l, Symbol, and symbol::u.

Referenced by branch().

00603                                             {
00604     assert(dst && lprime);
00605     for ( ; dst; dst = dst->u.l.equatedto)
00606         if (lprime == dst)
00607             return 1;
00608     return 0;
00609 }

void equatelab Symbol  old,
Symbol  new
 

Definition at line 598 of file stmt.c.

References assert, symbol::equatedto, symbol::l, NULL, symbol::ref, Symbol, and symbol::u.

Referenced by branch(), labelnode(), and listnodes().

00598                                        {
00599     assert(old->u.l.equatedto == NULL);
00600     old->u.l.equatedto = new;
00601     new->ref++;
00602 }

int foldcond Tree  e1,
Tree  e2
[static]
 

Definition at line 626 of file stmt.c.

References ASGN, CNST, EQ, generic, GT, value::i, INDIR, isaddrop, tree::kids, LE, LT, NE, tree::op, op, simplify(), tree::sym, Symbol, Tree, tree::type, tree::u, tree::v, and v.

Referenced by forstmt().

00626                                       {
00627     int op = generic(e2->op);
00628     Symbol v;
00629 
00630     if (e1 == 0 || e2 == 0)
00631         return 0;
00632     if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
00633     && generic(e1->kids[1]->op) == CNST) {
00634         v = e1->kids[0]->u.sym;
00635         e1 = e1->kids[1];
00636     } else
00637         return 0;
00638     if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
00639     && generic(e2->kids[0]->op) == INDIR
00640     && e2->kids[0]->kids[0]->u.sym == v
00641     && e2->kids[1]->op == e1->op) {
00642         e1 = simplify(op, e2->type, e1, e2->kids[1]);
00643         if (e1->op == CNST+I)
00644             return e1->u.v.i;
00645     }
00646     return 0;
00647 }

Here is the call graph for this function:

void forstmt int  ,
Swtch  ,
int 
[static]
 

Definition at line 262 of file stmt.c.

References branch(), conditional(), Coordinate, definelab(), definept(), expect(), expr0(), findlabel(), foldcond(), FUNC, gettok(), kind, NULL, symbol::ref, refinc, statement(), Swtch, t, test(), texpr(), Tree, and walk().

Referenced by statement().

00262                                                  {
00263     int once = 0;
00264     Tree e1 = NULL, e2 = NULL, e3 = NULL;
00265     Coordinate pt2, pt3;
00266     
00267     t = gettok();
00268     expect('(');
00269     definept(NULL);
00270     if (kind[t] == ID)
00271         e1 = texpr(expr0, ';', FUNC);
00272     else
00273         expect(';');
00274     walk(e1, 0, 0);
00275     pt2 = src;
00276     refinc *= 10.0;
00277     if (kind[t] == ID)
00278         e2 = texpr(conditional, ';', FUNC);
00279     else
00280         expect(';');
00281     pt3 = src;
00282     if (kind[t] == ID)
00283         e3 = texpr(expr0, ')', FUNC);
00284     else {
00285         static char stop[] = { IF, ID, '}', 0 };
00286         test(')', stop);
00287     }
00288     if (e2) {
00289         once = foldcond(e1, e2);
00290         if (!once)
00291             branch(lab + 3);
00292     }
00293     definelab(lab);
00294     statement(lab, swp, lev);
00295     definelab(lab + 1);
00296     definept(&pt3);
00297     if (e3)
00298         walk(e3, 0, 0);
00299     if (e2) {
00300         if (!once)
00301             definelab(lab + 3);
00302         definept(&pt2);
00303         walk(e2, lab, 0);
00304     } else {
00305         definept(&pt2);
00306         branch(lab);
00307     }
00308     if (findlabel(lab + 2)->ref)
00309         definelab(lab + 2);
00310 }

Here is the call graph for this function:

void ifstmt int  ,
int  ,
Swtch  ,
int 
[static]
 

Definition at line 220 of file stmt.c.

References branch(), conditional(), definelab(), definept(), expect(), findlabel(), gettok(), NULL, symbol::ref, refinc, statement(), Swtch, t, and walk().

Referenced by statement().

00220                                                           {
00221     t = gettok();
00222     expect('(');
00223     definept(NULL);
00224     walk(conditional(')'), 0, lab);
00225     refinc /= 2.0;
00226     statement(loop, swp, lev);
00227     if (t == ELSE) {
00228         branch(lab + 1);
00229         t = gettok();
00230         definelab(lab);
00231         statement(loop, swp, lev);
00232         if (findlabel(lab + 1)->ref)
00233             definelab(lab + 1);
00234     } else
00235         definelab(lab);
00236 }

Here is the call graph for this function:

Node jump int  lab  ) 
 

Definition at line 558 of file stmt.c.

References ADDRG, findlabel(), JUMP, newnode(), Node, NULL, p, symbol::ref, Symbol, ttob(), V, and voidptype.

Referenced by branch(), and listnodes().

00558                    {
00559     Symbol p = findlabel(lab);
00560 
00561     p->ref++;
00562     return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
00563         NULL, NULL);
00564 }

Here is the call graph for this function:

Symbol localaddr Tree   )  [static]
 

Definition at line 650 of file stmt.c.

References ADDRF, ADDRL, ARG, ASGN, assert, CALL, COND, generic, INDIR, tree::kids, tree::op, p, q, RIGHT, tree::sym, Symbol, Tree, and tree::u.

Referenced by retcode().

00650                                 {
00651     if (p == NULL)
00652         return NULL;
00653     switch (generic(p->op)) {
00654     case INDIR: case CALL: case ARG:
00655         return NULL;
00656     case ADDRL: case ADDRF:
00657         return p->u.sym;
00658     case RIGHT: case ASGN:
00659         if (p->kids[1])
00660             return localaddr(p->kids[1]);
00661         return localaddr(p->kids[0]);
00662     case COND: {
00663         Symbol q;
00664         assert(p->kids[1] && p->kids[1]->op == RIGHT);
00665         if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
00666             return q;
00667         return localaddr(p->kids[1]->kids[1]);
00668         }
00669     default: {
00670         Symbol q;
00671         if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
00672             return q;
00673         return localaddr(p->kids[1]);
00674         }
00675     }
00676 }

int reachable int  kind  ) 
 

Definition at line 39 of file stmt.c.

References Code, cp, code::kind, kind, and code::prev.

Referenced by code(), compound(), and definept().

00039                         {
00040     Code cp;
00041 
00042     if (kind > Start) {
00043         Code cp;
00044         for (cp = codelist; cp->kind < Label; )
00045             cp = cp->prev;
00046         if (cp->kind == Jump || cp->kind == Switch)
00047             return 0;
00048     }
00049     return 1;
00050 }

void retcode Tree  p  ) 
 

Definition at line 482 of file stmt.c.

References addlocal(), apply(), asgn(), ASGN, asgntree(), assign(), B, CALL, cast(), cfunc, symbol::computed, error(), events, freturn(), symbol::generated, genident(), idtree(), iscallb(), isfloat, isptr, tree::kids, level, localaddr(), mkop, symbol::name, NULL, p, PARAM, pointer(), promote(), q, RET, Events::returns, retv, RIGHT, rvalue(), symbol::scope, Symbol, tree(), Tree, tree::type, symbol::type, Type, walk(), and warning().

Referenced by funcdefn(), jpeg_consume_input(), jpeg_read_coefficients(), jpeg_read_header(), jpeg_start_decompress(), and statement().

00482                      {
00483     Type ty;
00484 
00485     if (p == NULL) {
00486         if (events.returns)
00487             apply(events.returns, cfunc, NULL);
00488         return;
00489     }
00490     p = pointer(p);
00491     ty = assign(freturn(cfunc->type), p);
00492     if (ty == NULL) {
00493         error("illegal return type; found `%t' expected `%t'\n",
00494             p->type, freturn(cfunc->type));
00495         return;
00496     }
00497     p = cast(p, ty);
00498     if (retv)
00499         {
00500             if (iscallb(p))
00501                 p = tree(RIGHT, p->type,
00502                     tree(CALL+B, p->type,
00503                         p->kids[0]->kids[0], idtree(retv)),
00504                     rvalue(idtree(retv)));
00505             else
00506                 p = asgntree(ASGN, rvalue(idtree(retv)), p);
00507             walk(p, 0, 0);
00508             if (events.returns)
00509                 apply(events.returns, cfunc, rvalue(idtree(retv)));
00510             return;
00511         }
00512     if (events.returns)
00513         {
00514             Symbol t1 = genident(AUTO, p->type, level);
00515             addlocal(t1);
00516             walk(asgn(t1, p), 0, 0);
00517             apply(events.returns, cfunc, idtree(t1));
00518             p = idtree(t1);
00519         }
00520     if (!isfloat(p->type))
00521         p = cast(p, promote(p->type));
00522     if (isptr(p->type))
00523         {
00524             Symbol q = localaddr(p);
00525             if (q && (q->computed || q->generated))
00526                 warning("pointer to a %s is an illegal return value\n",
00527                     q->scope == PARAM ? "parameter" : "local");
00528             else if (q)
00529                 warning("pointer to %s `%s' is an illegal return value\n",
00530                     q->scope == PARAM ? "parameter" : "local", q->name);
00531         }
00532     walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
00533 }

Here is the call graph for this function:

void statement int  loop,
Swtch  swp,
int  lev
 

Definition at line 78 of file stmt.c.

References Aflag, branch(), caselabel, cast(), cfunc, CNST, compound(), constexpr(), deallocate(), definelab(), definept(), swtch::deflab, DO, dostmt(), e, error(), expect(), expr(), expr0(), extend, symbol::f, findlabel(), forstmt(), freturn(), FUNC, generic, genlabel(), getchr(), gettok(), value::i, ID, ifstmt(), install(), isint, kind, symbol::l, swtch::lab, symbol::label, listnodes(), lookup(), needconst, nodecount, NULL, type::op, tree::op, p, ref, refinc, retcode(), symbol::scope, skipto(), src, symbol::src, STMT, stmtlabel(), stmtlabs, swstmt(), Swtch, swtch::sym, Symbol, t, test(), Tree, Type, symbol::type, tree::type, symbol::u, value::u, tree::u, use(), tree::v, walk(), warning(), and whilestmt().

Referenced by compound(), dostmt(), forstmt(), ifstmt(), swstmt(), and whilestmt().

00078                                              {
00079     float ref = refinc;
00080 
00081     if (Aflag >= 2 && lev == 15)
00082         warning("more than 15 levels of nested statements\n");
00083     switch (t) {
00084     case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
00085  break;
00086     case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
00087     case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
00088                     break;
00089 
00090     case FOR:      forstmt(genlabel(4), swp, lev + 1);
00091  break;
00092     case BREAK:    walk(NULL, 0, 0);
00093                definept(NULL);
00094                if (swp && swp->lab > loop)
00095                 branch(swp->lab + 1);
00096                else if (loop)
00097                 branch(loop + 2);
00098                else
00099                 error("illegal break statement\n");
00100                t = gettok(); expect(';');
00101                        break;
00102 
00103     case CONTINUE: walk(NULL, 0, 0);
00104                definept(NULL);
00105                if (loop)
00106                 branch(loop + 1);
00107                else
00108                 error("illegal continue statement\n");
00109                t = gettok(); expect(';');
00110                           break;
00111 
00112     case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
00113  break;
00114     case CASE:     {
00115                 int lab = genlabel(1);
00116                 if (swp == NULL)
00117                     error("illegal case label\n");
00118                 definelab(lab);
00119                 while (t == CASE) {
00120                     static char stop[] = { IF, ID, 0 };
00121                     Tree p;
00122                     t = gettok();
00123                     p = constexpr(0);
00124                     if (generic(p->op) == CNST && isint(p->type)) {
00125                         if (swp) {
00126                             needconst++;
00127                             p = cast(p, swp->sym->type);
00128                             if (p->type->op == UNSIGNED)
00129                                 p->u.v.i = extend(p->u.v.u, p->type);
00130                             needconst--;
00131                             caselabel(swp, p->u.v.i, lab);
00132                         }
00133                     } else
00134                         error("case label must be a constant integer expression\n");
00135 
00136                     test(':', stop);
00137                 }
00138                 statement(loop, swp, lev);
00139                } break;
00140     case DEFAULT:  if (swp == NULL)
00141                 error("illegal default label\n");
00142                else if (swp->deflab)
00143                 error("extra default label\n");
00144                else {
00145                 swp->deflab = findlabel(swp->lab);
00146                 definelab(swp->deflab->u.l.label);
00147                }
00148                t = gettok();
00149                expect(':');
00150                statement(loop, swp, lev); break;
00151     case RETURN:   {
00152                 Type rty = freturn(cfunc->type);
00153                 t = gettok();
00154                 definept(NULL);
00155                 if (t != ';')
00156                     if (rty == voidtype) {
00157                         error("extraneous return value\n");
00158                         expr(0);
00159                         ret