1
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
14
Tdefault, // default case
15
Texprconst, // normal constant case
16
Texprvar, // normal variable case
18
Ttypeconst, // type hashes
19
Ttypevar, // interface type
21
Ncase = 4, // count needed to split
24
typedef struct Case Case;
27
Node* node; // points at case statement
28
uint32 hash; // hash of a type switch
29
uint8 type; // type of case
30
uint8 diag; // suppress multiple diagnostics
31
uint16 ordinal; // position in switch
32
Case* link; // linked list to link
34
#define C ((Case*)nil)
41
for(c=c0; c!=C; c=c->link) {
44
print("case-default\n");
45
print(" ord=%d\n", c->ordinal);
48
print("case-exprconst\n");
49
print(" ord=%d\n", c->ordinal);
52
print("case-exprvar\n");
53
print(" ord=%d\n", c->ordinal);
54
print(" op=%O\n", c->node->left->op);
57
print("case-typenil\n");
58
print(" ord=%d\n", c->ordinal);
61
print("case-typeconst\n");
62
print(" ord=%d\n", c->ordinal);
63
print(" hash=%ux\n", c->hash);
66
print("case-typevar\n");
67
print(" ord=%d\n", c->ordinal);
71
print(" ord=%d\n", c->ordinal);
72
print(" op=%O\n", c->node->left->op);
73
print(" hash=%ux\n", c->hash);
81
ordlcmp(Case *c1, Case *c2)
84
if(c1->type == Tdefault)
86
if(c2->type == Tdefault)
90
if(c1->type == Ttypenil)
92
if(c2->type == Ttypenil)
96
if(c1->ordinal > c2->ordinal)
98
if(c1->ordinal < c2->ordinal)
104
exprcmp(Case *c1, Case *c2)
109
// sort non-constants last
110
if(c1->type != Texprconst)
112
if(c2->type != Texprconst)
119
if(ct != n2->val.ctype) {
120
// invalid program, but return a sort
121
// order so that we can give a better
123
return ct - n2->val.ctype;
126
// sort by constant value
130
n = mpcmpfltflt(n1->val.u.fval, n2->val.u.fval);
133
n = mpcmpfixfix(n1->val.u.xval, n2->val.u.xval);
144
typecmp(Case *c1, Case *c2)
147
// sort non-constants last
148
if(c1->type != Ttypeconst)
150
if(c2->type != Ttypeconst)
154
if(c1->hash > c2->hash)
156
if(c1->hash < c2->hash)
159
// sort by ordinal so duplicate error
160
// happens on later case.
161
if(c1->ordinal > c2->ordinal)
163
if(c1->ordinal < c2->ordinal)
169
csort(Case *l, int(*f)(Case*, Case*))
173
if(l == C || l->link == C)
193
/* set up lead element */
194
if((*f)(l1, l2) < 0) {
221
if((*f)(l1, l2) < 0) {
241
snprint(namebuf, sizeof(namebuf), "%.6d", label);
242
return newname(lookup(namebuf));
246
* build separate list of statements and cases
247
* make labels between cases and statements
248
* deal with fallthrough, break, unreachable statements
251
casebody(Node *sw, Node *typeswvar)
253
Node *os, *oc, *n, *c, *last;
255
NodeList *cas, *stat, *l, *lc;
264
stat = nil; // statements
266
os = N; // last statement
268
br = nod(OBREAK, N, N);
270
for(l=sw->list; l; l=l->next) {
274
fatal("casebody %O", n->op);
276
needvar = count(n->list) != 1 || n->list->n->op == OLITERAL;
278
go = nod(OGOTO, newlabel(), N);
281
yyerror("more than one default case");
282
// reuse original default case
287
if(n->list != nil && n->list->next == nil) {
288
// one case - reuse OCASE node.
295
// expand multi-valued cases
296
for(lc=n->list; lc; lc=lc->next) {
298
cas = list(cas, nod(OCASE, c, go));
302
stat = list(stat, nod(OLABEL, go->left, N));
303
if(typeswvar && needvar && n->nname != N) {
306
l = list1(nod(ODCL, n->nname, N));
307
l = list(l, nod(OAS, n->nname, typeswvar));
308
typechecklist(l, Etop);
309
stat = concat(stat, l);
311
stat = concat(stat, n->nbody);
313
// botch - shouldnt fall thru declaration
315
if(last->op == OXFALL) {
318
yyerror("cannot fallthrough in type switch");
322
stat = list(stat, br);
325
stat = list(stat, br);
327
cas = list(cas, def);
335
mkcaselist(Node *sw, int arg)
345
for(l=sw->list; l; l=l->next) {
347
c1 = mal(sizeof(*c1));
363
if(n->left->op == OLITERAL) {
367
if(istype(n->left->type, TINTER)) {
372
c->hash = typehash(n->left->type);
373
c->type = Ttypeconst;
380
switch(consttype(n->left)) {
384
c->type = Texprconst;
393
// sort by value and diagnose duplicate cases
396
c = csort(c, typecmp);
397
for(c1=c; c1!=C; c1=c1->link) {
398
for(c2=c1->link; c2!=C && c2->hash==c1->hash; c2=c2->link) {
399
if(c1->type == Ttypenil || c1->type == Tdefault)
401
if(c2->type == Ttypenil || c2->type == Tdefault)
403
if(!eqtype(c1->node->left->type, c2->node->left->type))
405
yyerrorl(c2->node->lineno, "duplicate case in switch\n\tprevious case at %L", c1->node->lineno);
412
c = csort(c, exprcmp);
413
for(c1=c; c1->link!=C; c1=c1->link) {
414
if(exprcmp(c1, c1->link) != 0)
416
setlineno(c1->link->node);
417
yyerror("duplicate case in switch\n\tprevious case at %L", c1->node->lineno);
422
// put list back in processing order
423
c = csort(c, ordlcmp);
427
static Node* exprname;
430
exprbsw(Case *c0, int ncase, int arg)
439
for(i=0; i<ncase; i++) {
446
a->ntest = n->left; // if val
447
a->nbody = list1(n->right); // then goto l
452
a->ntest = nod(ONOT, n->left, N); // if !val
453
typecheck(&a->ntest, Erv);
454
a->nbody = list1(n->right); // then goto l
459
a->ntest = nod(OEQ, exprname, n->left); // if name == val
460
typecheck(&a->ntest, Erv);
461
a->nbody = list1(n->right); // then goto l
469
return liststmt(cas);
472
// find the middle and recur
475
for(i=1; i<half; i++)
478
a->ntest = nod(OLE, exprname, c->node->left);
479
typecheck(&a->ntest, Erv);
480
a->nbody = list1(exprbsw(c0, half, arg));
481
a->nelse = list1(exprbsw(c->link, ncase-half, arg));
486
* normal (expression) switch.
487
* rebulid case statements into if .. goto
502
if(isconst(sw->ntest, CTBOOL)) {
504
if(sw->ntest->val.u.bval == 0)
507
walkexpr(&sw->ntest, &sw->ninit);
513
* convert the switch into OIF statements
517
if(arg != Strue && arg != Sfalse) {
518
exprname = nod(OXXX, N, N);
519
tempname(exprname, sw->ntest->type);
520
cas = list1(nod(OAS, exprname, sw->ntest));
521
typechecklist(cas, Etop);
524
c0 = mkcaselist(sw, arg);
525
if(c0 != C && c0->type == Tdefault) {
526
def = c0->node->right;
529
def = nod(OBREAK, N, N);
534
cas = list(cas, def);
535
sw->nbody = concat(cas, sw->nbody);
537
walkstmtlist(sw->nbody);
541
// deal with the variables one-at-a-time
542
if(c0->type != Texprconst) {
543
a = exprbsw(c0, 1, arg);
549
// do binary search on run of constants
551
for(c=c0; c->link!=C; c=c->link) {
552
if(c->link->type != Texprconst)
557
// break the chain at the count
561
// sort and compile constants
562
c0 = csort(c0, exprcmp);
563
a = exprbsw(c0, ncase, arg);
571
static Node* hashname;
572
static Node* facename;
573
static Node* boolname;
584
typecheck(&nblank, Erv | Easgn);
587
init = list1(nod(ODCL, var, N));
590
a->list = list(list1(var), boolname); // var,bool =
591
b = nod(ODOTTYPE, facename, N);
592
b->type = t->left->type; // interface.(type)
595
init = list(init, a);
599
b->nbody = list1(t->right); // if bool { goto l }
600
a = liststmt(list(init, b));
605
typebsw(Case *c0, int ncase)
615
for(i=0; i<ncase; i++) {
617
if(c0->type != Ttypeconst)
620
a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
621
typecheck(&a->ntest, Erv);
622
a->nbody = list1(n->right);
626
return liststmt(cas);
629
// find the middle and recur
632
for(i=1; i<half; i++)
635
a->ntest = nod(OLE, hashname, nodintconst(c->hash));
636
typecheck(&a->ntest, Erv);
637
a->nbody = list1(typebsw(c0, half));
638
a->nelse = list1(typebsw(c->link, ncase-half));
643
* convert switch of the form
644
* switch v := i.(type) { case t1: ..; case t2: ..; }
651
NodeList *cas, *hash;
660
if(sw->ntest->right == nil) {
662
yyerror("type switch must have an assignment");
665
walkexpr(&sw->ntest->right, &sw->ninit);
666
if(!istype(sw->ntest->right->type, TINTER)) {
667
yyerror("type switch must be on an interface");
673
* predeclare temporary variables
674
* and the boolean var
676
facename = nod(OXXX, N, N);
677
tempname(facename, sw->ntest->right->type);
678
a = nod(OAS, facename, sw->ntest->right);
682
casebody(sw, facename);
684
boolname = nod(OXXX, N, N);
685
tempname(boolname, types[TBOOL]);
686
typecheck(&boolname, Erv);
688
hashname = nod(OXXX, N, N);
689
tempname(hashname, types[TUINT32]);
690
typecheck(&hashname, Erv);
692
t = sw->ntest->right->type;
694
a = syslook("efacethash", 1);
696
a = syslook("ifacethash", 1);
698
a = nod(OCALL, a, N);
699
a->list = list1(facename);
700
a = nod(OAS, hashname, a);
704
c0 = mkcaselist(sw, Stype);
705
if(c0 != C && c0->type == Tdefault) {
706
def = c0->node->right;
709
def = nod(OBREAK, N, N);
713
* insert if statement into each case block
715
for(c=c0; c!=C; c=c->link) {
722
a->ntest = nod(OEQ, facename, nodlit(v));
723
typecheck(&a->ntest, Erv);
724
a->nbody = list1(n->right); // if i==nil { goto l }
730
n->right = typeone(n);
736
* generate list of if statements, binary search for constant sequences
739
if(c0->type != Ttypeconst) {
741
cas = list(cas, n->right);
746
// identify run of constants
748
while(c->link!=C && c->link->type==Ttypeconst)
754
c1 = csort(c1, typecmp);
756
// for debugging: linear search
758
for(c=c1; c!=C; c=c->link) {
760
cas = list(cas, n->right);
765
// combine adjacent cases with the same hash
767
for(c=c1; c!=C; c=c->link) {
769
hash = list1(c->node->right);
770
while(c->link != C && c->link->hash == c->hash) {
771
hash = list(hash, c->link->node->right);
772
c->link = c->link->link;
774
c->node->right = liststmt(hash);
777
// binary search among cases to narrow by hash
778
cas = list(cas, typebsw(c1, ncase));
781
cas = list(cas, def);
782
sw->nbody = concat(cas, sw->nbody);
784
walkstmtlist(sw->nbody);
793
* reorder the body into (OLIST, cases, statements)
794
* cases have OGOTO into statements.
795
* both have inserted OBREAK statements
797
walkstmtlist(sw->ninit);
799
sw->ntest = nodbool(1);
800
typecheck(&sw->ntest, Erv);
803
if(sw->ntest->op == OTYPESW) {
812
* type check switch statement
815
typecheckswitch(Node *n)
824
typechecklist(n->ninit, Etop);
826
if(n->ntest != N && n->ntest->op == OTYPESW) {
829
typecheck(&n->ntest->right, Erv);
830
t = n->ntest->right->type;
831
if(t != T && t->etype != TINTER)
832
yyerror("cannot type switch on non-interface value %+N", n->ntest->right);
837
typecheck(&n->ntest, Erv);
838
defaultlit(&n->ntest, T);
846
for(l=n->list; l; l=l->next) {
849
if(ncase->list == nil) {
852
yyerror("multiple defaults in switch (first at %L)", def->lineno);
856
for(ll=ncase->list; ll; ll=ll->next) {
858
typecheck(&ll->n, Erv | Etype);
859
if(ll->n->type == T || t == T)
862
case Erv: // expression switch
863
defaultlit(&ll->n, t);
864
if(ll->n->op == OTYPE)
865
yyerror("type %T is not an expression", ll->n->type);
866
else if(ll->n->type != T && !eqtype(ll->n->type, t))
867
yyerror("case %+N in %T switch", ll->n, t);
869
case Etype: // type switch
870
if(ll->n->op == OLITERAL && istype(ll->n->type, TNIL))
872
else if(ll->n->op != OTYPE && ll->n->type != T)
873
yyerror("%#N is not a type", ll->n);
878
if(top == Etype && n->type != T) {
882
if(ll && ll->next == nil && ll->n->type != T && !istype(ll->n->type, TNIL)) {
883
// single entry type switch
884
nvar->ntype = typenod(ll->n->type);
886
// multiple entry type switch or default
887
nvar->ntype = typenod(n->type);
891
typechecklist(ncase->nbody, Etop);