static int lookuptype(char *buf) { int n = typehash(buf); struct _type_hash *t = typeHashTab[n]; while (t) { if (!strcmp(t->name, buf)) return t->id; t = t->next; } t = Alloc(sizeof(struct _type_hash)); t->id = typeIndex++; t->name = litlate(buf); t->next = typeHashTab[n]; typeHashTab[n] = t; return -t->id; }
static Case* mkcaselist(Node *sw, int arg) { Node *n; Case *c, *c1, *c2; NodeList *l; int ord; c = C; ord = 0; for(l=sw->list; l; l=l->next) { n = l->n; c1 = mal(sizeof(*c1)); c1->link = c; c = c1; ord++; if((uint16)ord != ord) fatal("too many cases in switch"); c->ordinal = ord; c->node = n; if(n->left == N) { c->type = Tdefault; continue; } switch(arg) { case Stype: c->hash = 0; if(n->left->op == OLITERAL) { c->type = Ttypenil; continue; } if(istype(n->left->type, TINTER)) { c->type = Ttypevar; continue; } c->hash = typehash(n->left->type); c->type = Ttypeconst; continue; case Snorm: case Strue: case Sfalse: c->type = Texprvar; c->hash = typehash(n->left->type); switch(consttype(n->left)) { case CTFLT: case CTINT: case CTRUNE: case CTSTR: c->type = Texprconst; } continue; } } if(c == C) return C; // sort by value and diagnose duplicate cases switch(arg) { case Stype: c = csort(c, typecmp); for(c1=c; c1!=C; c1=c1->link) { for(c2=c1->link; c2!=C && c2->hash==c1->hash; c2=c2->link) { if(c1->type == Ttypenil || c1->type == Tdefault) break; if(c2->type == Ttypenil || c2->type == Tdefault) break; if(!eqtype(c1->node->left->type, c2->node->left->type)) continue; yyerrorl(c2->node->lineno, "duplicate case %T in type switch\n\tprevious case at %L", c2->node->left->type, c1->node->lineno); } } break; case Snorm: case Strue: case Sfalse: c = csort(c, exprcmp); for(c1=c; c1->link!=C; c1=c1->link) { if(exprcmp(c1, c1->link) != 0) continue; setlineno(c1->link->node); yyerror("duplicate case %N in switch\n\tprevious case at %L", c1->node->left, c1->node->lineno); } break; } // put list back in processing order c = csort(c, ordlcmp); return c; }