Annotation of 43BSDTahoe/ucb/dbx/c.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)c.c        5.8 (Berkeley) 5/11/88";
                      9: #endif not lint
                     10: 
                     11: static char rcsid[] = "$Header: c.c,v 1.5 88/04/02 01:25:44 donn Exp $";
                     12: 
                     13: /*
                     14:  * C-dependent symbol routines.
                     15:  */
                     16: 
                     17: #include "defs.h"
                     18: #include "symbols.h"
                     19: #include "printsym.h"
                     20: #include "languages.h"
                     21: #include "c.h"
                     22: #include "tree.h"
                     23: #include "eval.h"
                     24: #include "operators.h"
                     25: #include "mappings.h"
                     26: #include "process.h"
                     27: #include "runtime.h"
                     28: #include "machine.h"
                     29: 
                     30: #ifndef public
                     31: #   include "tree.h"
                     32: #endif
                     33: 
                     34: #define isdouble(range) ( \
                     35:     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
                     36: )
                     37: 
                     38: #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
                     39: 
                     40: private Language langC;
                     41: private Language langCplpl;
                     42: 
                     43: /*
                     44:  * Initialize C language information.
                     45:  */
                     46: 
                     47: public c_init()
                     48: {
                     49:     langC = language_define("c", ".c");
                     50:     language_setop(langC, L_PRINTDECL, c_printdecl);
                     51:     language_setop(langC, L_PRINTVAL, c_printval);
                     52:     language_setop(langC, L_TYPEMATCH, c_typematch);
                     53:     language_setop(langC, L_BUILDAREF, c_buildaref);
                     54:     language_setop(langC, L_EVALAREF, c_evalaref);
                     55:     language_setop(langC, L_MODINIT, c_modinit);
                     56:     language_setop(langC, L_HASMODULES, c_hasmodules);
                     57:     language_setop(langC, L_PASSADDR, c_passaddr);
                     58: 
                     59:     langCplpl = language_define("c++", "..c");
                     60:     language_setop(langCplpl, L_PRINTDECL, c_printdecl);
                     61:     language_setop(langCplpl, L_PRINTVAL, c_printval);
                     62:     language_setop(langCplpl, L_TYPEMATCH, c_typematch);
                     63:     language_setop(langCplpl, L_BUILDAREF, c_buildaref);
                     64:     language_setop(langCplpl, L_EVALAREF, c_evalaref);
                     65:     language_setop(langCplpl, L_MODINIT, c_modinit);
                     66:     language_setop(langCplpl, L_HASMODULES, c_hasmodules);
                     67:     language_setop(langCplpl, L_PASSADDR, c_passaddr);
                     68: }
                     69: 
                     70: /*
                     71:  * Test if two types are compatible.
                     72:  */
                     73: 
                     74: public Boolean c_typematch(type1, type2)
                     75: Symbol type1, type2;
                     76: {
                     77:     Boolean b;
                     78:     register Symbol t1, t2, tmp;
                     79: 
                     80:     t1 = type1;
                     81:     t2 = type2;
                     82:     if (t1 == t2) {
                     83:        b = true;
                     84:     } else {
                     85:        t1 = rtype(t1);
                     86:        t2 = rtype(t2);
                     87:        if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) {
                     88:            tmp = t1;
                     89:            t1 = t2;
                     90:            t2 = tmp;
                     91:        }
                     92:        b = (Boolean) (
                     93:            (
                     94:                isrange(t1, "int") and !isdouble(t1) /* sigh */ and
                     95:                (t2 == t_int->type or t2 == t_char->type)
                     96:            ) or (
                     97:                isrange(t1, "char") and
                     98:                (t2 == t_char->type or t2 == t_int->type)
                     99:            ) or (
                    100:                t1->class == RANGE and isdouble(t1) and t2 == t_real->type
                    101:            ) or (
                    102:                t1->class == RANGE and t2->class == RANGE and
                    103:                t1->symvalue.rangev.lower == t2->symvalue.rangev.lower and
                    104:                t1->symvalue.rangev.upper == t2->symvalue.rangev.upper
                    105:            ) or (
                    106:                t1->class != RANGE and t1->type == t2->type and (
                    107:                    (t1->class == t2->class) or
                    108:                    (t1->class == SCAL and t2->class == CONST) or
                    109:                    (t1->class == CONST and t2->class == SCAL)
                    110:                )
                    111:            ) or (
                    112:                t1->class == PTR and c_typematch(t1->type, t_char) and
                    113:                t2->class == ARRAY and c_typematch(t2->type, t_char) and
                    114:                t2->language == primlang
                    115:            )
                    116:        );
                    117:     }
                    118:     return b;
                    119: }
                    120: 
                    121: /*
                    122:  * Print out the declaration of a C variable.
                    123:  */
                    124: 
                    125: public c_printdecl(s)
                    126: Symbol s;
                    127: {
                    128:     printdecl(s, 0);
                    129: }
                    130: 
                    131: private printdecl(s, indent)
                    132: register Symbol s;
                    133: Integer indent;
                    134: {
                    135:     register Symbol t;
                    136:     Boolean semicolon, newline;
                    137: 
                    138:     semicolon = true;
                    139:     newline = true;
                    140:     if (indent > 0) {
                    141:        printf("%*c", indent, ' ');
                    142:     }
                    143:     if (s->class == TYPE) {
                    144:        printf("typedef ");
                    145:     }
                    146:     switch (s->class) {
                    147:        case CONST:
                    148:            if (s->type->class == SCAL) {
                    149:                printf("enumeration constant with value ");
                    150:                eval(s->symvalue.constval);
                    151:                c_printval(s);
                    152:            } else {
                    153:                printf("const %s = ", symname(s));
                    154:                printval(s);
                    155:            }
                    156:            break;
                    157: 
                    158:        case TYPE:
                    159:        case VAR:
                    160:            if (s->class != TYPE and s->storage == INREG) {
                    161:                printf("register ");
                    162:            }
                    163:            if (s->type->class == ARRAY) {
                    164:                printtype(s->type, s->type->type, indent);
                    165:                t = rtype(s->type->chain);
                    166:                assert(t->class == RANGE);
                    167:                printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
                    168:            } else {
                    169:                printtype(s, s->type, indent);
                    170:                if (s->type->class != PTR) {
                    171:                    printf(" ");
                    172:                }
                    173:                printf("%s", symname(s));
                    174:            }
                    175:            break;
                    176: 
                    177:        case FIELD:
                    178:            if (s->type->class == ARRAY) {
                    179:                printtype(s->type, s->type->type, indent);
                    180:                t = rtype(s->type->chain);
                    181:                assert(t->class == RANGE);
                    182:                printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
                    183:            } else {
                    184:                printtype(s, s->type, indent);
                    185:                if (s->type->class != PTR) {
                    186:                    printf(" ");
                    187:                }
                    188:                printf("%s", symname(s));
                    189:            }
                    190:            if (isbitfield(s)) {
                    191:                printf(" : %d", s->symvalue.field.length);
                    192:            }
                    193:            break;
                    194: 
                    195:        case TAG:
                    196:            if (s->type == nil) {
                    197:                findtype(s);
                    198:                if (s->type == nil) {
                    199:                    error("unexpected missing type information");
                    200:                }
                    201:            }
                    202:            printtype(s, s->type, indent);
                    203:            break;
                    204: 
                    205:        case RANGE:
                    206:        case ARRAY:
                    207:        case RECORD:
                    208:        case VARNT:
                    209:        case PTR:
                    210:        case FFUNC:
                    211:            semicolon = false;
                    212:            printtype(s, s, indent);
                    213:            break;
                    214: 
                    215:        case SCAL:
                    216:            printf("(enumeration constant, value %d)", s->symvalue.iconval);
                    217:            break;
                    218: 
                    219:        case PROC:
                    220:            semicolon = false;
                    221:            printf("%s", symname(s));
                    222:            c_listparams(s);
                    223:            newline = false;
                    224:            break;
                    225: 
                    226:        case FUNC:
                    227:            semicolon = false;
                    228:            if (not istypename(s->type, "void")) {
                    229:                printtype(s, s->type, indent);
                    230:                printf(" ");
                    231:            }
                    232:            printf("%s", symname(s));
                    233:            c_listparams(s);
                    234:            newline = false;
                    235:            break;
                    236: 
                    237:        case MODULE:
                    238:            semicolon = false;
                    239:            printf("source file \"%s.c\"", symname(s));
                    240:            break;
                    241: 
                    242:        case PROG:
                    243:            semicolon = false;
                    244:            printf("executable file \"%s\"", symname(s));
                    245:            break;
                    246: 
                    247:        default:
                    248:            printf("[%s]", classname(s));
                    249:            break;
                    250:     }
                    251:     if (semicolon) {
                    252:        putchar(';');
                    253:     }
                    254:     if (newline) {
                    255:        putchar('\n');
                    256:     }
                    257: }
                    258: 
                    259: /*
                    260:  * Recursive whiz-bang procedure to print the type portion
                    261:  * of a declaration.
                    262:  *
                    263:  * The symbol associated with the type is passed to allow
                    264:  * searching for type names without getting "type blah = blah".
                    265:  */
                    266: 
                    267: private printtype(s, t, indent)
                    268: Symbol s;
                    269: Symbol t;
                    270: Integer indent;
                    271: {
                    272:     register Symbol i;
                    273:     long r0, r1;
                    274:     register String p;
                    275: 
                    276:     checkref(s);
                    277:     checkref(t);
                    278:     switch (t->class) {
                    279:        case VAR:
                    280:        case CONST:
                    281:        case PROC:
                    282:            panic("printtype: class %s", classname(t));
                    283:            break;
                    284: 
                    285:        case ARRAY:
                    286:            printf("array[");
                    287:            i = t->chain;
                    288:            if (i != nil) {
                    289:                for (;;) {
                    290:                    printtype(i, i, indent);
                    291:                    i = i->chain;
                    292:                    if (i == nil) {
                    293:                        break;
                    294:                    }
                    295:                    printf(", ");
                    296:                }
                    297:            }
                    298:            printf("] of ");
                    299:            printtype(t, t->type, indent);
                    300:            break;
                    301: 
                    302:        case RECORD:
                    303:        case VARNT:
                    304:            printf("%s ", c_classname(t));
                    305:            if (s->name != nil and s->class == TAG) {
                    306:                p = symname(s);
                    307:                if (p[0] == '$' and p[1] == '$') {
                    308:                    printf("%s ", &p[2]);
                    309:                } else {
                    310:                    printf("%s ", p);
                    311:                }
                    312:            }
                    313:            printf("{\n");
                    314:            for (i = t->chain; i != nil; i = i->chain) {
                    315:                assert(i->class == FIELD);
                    316:                printdecl(i, indent+4);
                    317:            }
                    318:            if (indent > 0) {
                    319:                printf("%*c", indent, ' ');
                    320:            }
                    321:            printf("}");
                    322:            break;
                    323: 
                    324:        case RANGE:
                    325:            r0 = t->symvalue.rangev.lower;
                    326:            r1 = t->symvalue.rangev.upper;
                    327:            if (istypename(t->type, "char")) {
                    328:                if (r0 < 0x20 or r0 > 0x7e) {
                    329:                    printf("%ld..", r0);
                    330:                } else {
                    331:                    printf("'%c'..", (char) r0);
                    332:                }
                    333:                if (r1 < 0x20 or r1 > 0x7e) {
                    334:                    printf("\\%lo", r1);
                    335:                } else {
                    336:                    printf("'%c'", (char) r1);
                    337:                }
                    338:            } else if (r0 > 0 and r1 == 0) {
                    339:                printf("%ld byte real", r0);
                    340:            } else if (r0 >= 0) {
                    341:                printf("%lu..%lu", r0, r1);
                    342:            } else {
                    343:                printf("%ld..%ld", r0, r1);
                    344:            }
                    345:            break;
                    346: 
                    347:        case PTR:
                    348:            printtype(t, t->type, indent);
                    349:            if (t->type->class != PTR) {
                    350:                printf(" ");
                    351:            }
                    352:            printf("*");
                    353:            break;
                    354: 
                    355:        case FUNC:
                    356:        case FFUNC:
                    357:            printtype(t, t->type, indent);
                    358:            printf("()");
                    359:            break;
                    360: 
                    361:        case TYPE:
                    362:            if (t->name != nil) {
                    363:                printname(stdout, t);
                    364:            } else {
                    365:                printtype(t, t->type, indent);
                    366:            }
                    367:            break;
                    368: 
                    369:        case TYPEREF:
                    370:            printf("@%s", symname(t));
                    371:            break;
                    372: 
                    373:        case SCAL:
                    374:            printf("enum ");
                    375:            if (s->name != nil and s->class == TAG) {
                    376:                printf("%s ", symname(s));
                    377:            }
                    378:            printf("{ ");
                    379:            i = t->chain;
                    380:            if (i != nil) {
                    381:                for (;;) {
                    382:                    printf("%s", symname(i));
                    383:                    i = i->chain;
                    384:                if (i == nil) break;
                    385:                    printf(", ");
                    386:                }
                    387:            }
                    388:            printf(" }");
                    389:            break;
                    390: 
                    391:        case TAG:
                    392:            if (t->type == nil) {
                    393:                printf("unresolved tag %s", symname(t));
                    394:            } else {
                    395:                i = rtype(t->type);
                    396:                printf("%s %s", c_classname(i), symname(t));
                    397:            }
                    398:            break;
                    399: 
                    400:        default:
                    401:            printf("(class %d)", t->class);
                    402:            break;
                    403:     }
                    404: }
                    405: 
                    406: /*
                    407:  * List the parameters of a procedure or function.
                    408:  * No attempt is made to combine like types.
                    409:  */
                    410: 
                    411: public c_listparams(s)
                    412: Symbol s;
                    413: {
                    414:     register Symbol t;
                    415: 
                    416:     putchar('(');
                    417:     for (t = s->chain; t != nil; t = t->chain) {
                    418:        printf("%s", symname(t));
                    419:        if (t->chain != nil) {
                    420:            printf(", ");
                    421:        }
                    422:     }
                    423:     putchar(')');
                    424:     if (s->chain != nil) {
                    425:        printf("\n");
                    426:        for (t = s->chain; t != nil; t = t->chain) {
                    427:            if (t->class != VAR) {
                    428:                panic("unexpected class %d for parameter", t->class);
                    429:            }
                    430:            printdecl(t, 0);
                    431:        }
                    432:     } else {
                    433:        putchar('\n');
                    434:     }
                    435: }
                    436: 
                    437: /*
                    438:  * Print out the value on the top of the expression stack
                    439:  * in the format for the type of the given symbol.
                    440:  */
                    441: 
                    442: public c_printval(s)
                    443: Symbol s;
                    444: {
                    445:     register Symbol t;
                    446:     register Address a;
                    447:     integer i, len;
                    448:     register String str;
                    449: 
                    450:     switch (s->class) {
                    451:        case CONST:
                    452:        case TYPE:
                    453:        case VAR:
                    454:        case REF:
                    455:        case FVAR:
                    456:        case TAG:
                    457:            c_printval(s->type);
                    458:            break;
                    459: 
                    460:        case FIELD:
                    461:            if (isbitfield(s)) {
                    462:                i = extractField(s);
                    463:                t = rtype(s->type);
                    464:                if (t->class == SCAL) {
                    465:                    printEnum(i, t);
                    466:                } else {
                    467:                    printRangeVal(i, t);
                    468:                }
                    469:            } else {
                    470:                c_printval(s->type);
                    471:            }
                    472:            break;
                    473: 
                    474:        case ARRAY:
                    475:            t = rtype(s->type);
                    476:            if ((t->class == RANGE and istypename(t->type, "char")) or
                    477:                t == t_char->type
                    478:            ) {
                    479:                len = size(s);
                    480:                str = (String) (sp -= len);
                    481:                if (s->language != primlang) {
                    482:                    putchar('"');
                    483:                }
                    484:                while (--len > 0 and *str != '\0') {
                    485:                    printchar(*str++);
                    486:                }
                    487:                if (*str != '\0') {     /* XXX - pitch trailing null */
                    488:                    printchar(*str);
                    489:                }
                    490:                if (s->language != primlang) {
                    491:                    putchar('"');
                    492:                }
                    493:            } else {
                    494:                printarray(s);
                    495:            }
                    496:            break;
                    497: 
                    498:        case RECORD:
                    499:            c_printstruct(s);
                    500:            break;
                    501: 
                    502:        case RANGE:
                    503:            if (s == t_boolean->type or istypename(s->type, "boolean")) {
                    504:                printRangeVal(popsmall(s), s);
                    505:            } else if (s == t_char->type or istypename(s->type, "char")) {
                    506:                printRangeVal(pop(char), s);
                    507:            } else if (s == t_real->type or isdouble(s)) {
                    508:                switch (s->symvalue.rangev.lower) {
                    509:                    case sizeof(float):
                    510:                        prtreal((double) (pop(float)));
                    511:                        break;
                    512: 
                    513:                    case sizeof(double):
                    514:                        prtreal(pop(double));
                    515:                        break;
                    516: 
                    517:                    default:
                    518:                        panic("bad real size %d", t->symvalue.rangev.lower);
                    519:                        break;
                    520:                }
                    521:            } else {
                    522:                printRangeVal(popsmall(s), s);
                    523:            }
                    524:            break;
                    525: 
                    526:        case PTR:
                    527:            t = rtype(s->type);
                    528:            a = pop(Address);
                    529:            if (a == 0) {
                    530:                printf("(nil)");
                    531:            } else if (t->class == RANGE and istypename(t->type, "char")) {
                    532:                printString(a, (boolean) (s->language != primlang));
                    533:            } else {
                    534:                printf("0x%x", a);
                    535:            }
                    536:            break;
                    537: 
                    538:        case SCAL:
                    539:            i = pop(Integer);
                    540:            printEnum(i, s);
                    541:            break;
                    542: 
                    543:        /*
                    544:         * Unresolved structure pointers?
                    545:         */
                    546:        case BADUSE:
                    547:            a = pop(Address);
                    548:            printf("@%x", a);
                    549:            break;
                    550: 
                    551:        default:
                    552:            if (ord(s->class) > ord(TYPEREF)) {
                    553:                panic("printval: bad class %d", ord(s->class));
                    554:            }
                    555:            sp -= size(s);
                    556:            printf("[%s]", c_classname(s));
                    557:            break;
                    558:     }
                    559: }
                    560: 
                    561: /*
                    562:  * Print out a C structure.
                    563:  */
                    564: 
                    565: private c_printstruct (s)
                    566: Symbol s;
                    567: {
                    568:     Symbol f;
                    569:     Stack *savesp;
                    570:     integer n, off, len;
                    571: 
                    572:     sp -= size(s);
                    573:     savesp = sp;
                    574:     printf("(");
                    575:     f = s->chain;
                    576:     for (;;) {
                    577:        off = f->symvalue.field.offset;
                    578:        len = f->symvalue.field.length;
                    579:        n = (off + len + BITSPERBYTE - 1) div BITSPERBYTE;
                    580:        sp += n;
                    581:        printf("%s = ", symname(f));
                    582:        c_printval(f);
                    583:        sp = savesp;
                    584:        f = f->chain;
                    585:     if (f == nil) break;
                    586:        printf(", ");
                    587:     }
                    588:     printf(")");
                    589: }
                    590: 
                    591: /*
                    592:  * Return the C name for the particular class of a symbol.
                    593:  */
                    594: 
                    595: public String c_classname(s)
                    596: Symbol s;
                    597: {
                    598:     String str;
                    599: 
                    600:     switch (s->class) {
                    601:        case RECORD:
                    602:            str = "struct";
                    603:            break;
                    604: 
                    605:        case VARNT:
                    606:            str = "union";
                    607:            break;
                    608: 
                    609:        case SCAL:
                    610:            str = "enum";
                    611:            break;
                    612: 
                    613:        default:
                    614:            str = classname(s);
                    615:     }
                    616:     return str;
                    617: }
                    618: 
                    619: public Node c_buildaref(a, slist)
                    620: Node a, slist;
                    621: {
                    622:     register Symbol t;
                    623:     register Node p;
                    624:     Symbol etype, atype, eltype;
                    625:     Node r, esub;
                    626: 
                    627:     t = rtype(a->nodetype);
                    628:     eltype = t->type;
                    629:     if (t->class == PTR) {
                    630:        p = slist->value.arg[0];
                    631:        if (not compatible(p->nodetype, t_int)) {
                    632:            beginerrmsg();
                    633:            fprintf(stderr, "subscript must be integer-compatible");
                    634:            enderrmsg();
                    635:        }
                    636:        r = build(O_MUL, p, build(O_LCON, (long) size(eltype)));
                    637:        r = build(O_ADD, build(O_RVAL, a), r);
                    638:        r->nodetype = eltype;
                    639:     } else if (t->class != ARRAY) {
                    640:        beginerrmsg();
                    641:        fprintf(stderr, "\"");
                    642:        prtree(stderr, a);
                    643:        fprintf(stderr, "\" is not an array");
                    644:        enderrmsg();
                    645:     } else {
                    646:        r = a;
                    647:        p = slist;
                    648:        t = t->chain;
                    649:        for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
                    650:            esub = p->value.arg[0];
                    651:            etype = rtype(esub->nodetype);
                    652:            atype = rtype(t);
                    653:            if (not compatible(atype, etype)) {
                    654:                beginerrmsg();
                    655:                fprintf(stderr, "subscript \"");
                    656:                prtree(stderr, esub);
                    657:                fprintf(stderr, "\" is the wrong type");
                    658:                enderrmsg();
                    659:            }
                    660:            r = build(O_INDEX, r, esub);
                    661:            r->nodetype = eltype;
                    662:        }
                    663:        if (p != nil or t != nil) {
                    664:            beginerrmsg();
                    665:            if (p != nil) {
                    666:                fprintf(stderr, "too many subscripts for \"");
                    667:            } else {
                    668:                fprintf(stderr, "not enough subscripts for \"");
                    669:            }
                    670:            prtree(stderr, a);
                    671:            fprintf(stderr, "\"");
                    672:            enderrmsg();
                    673:        }
                    674:     }
                    675:     return r;
                    676: }
                    677: 
                    678: /*
                    679:  * Evaluate a subscript index.
                    680:  */
                    681: 
                    682: public c_evalaref(s, base, i)
                    683: Symbol s;
                    684: Address base;
                    685: long i;
                    686: {
                    687:     Symbol t;
                    688:     long lb, ub;
                    689: 
                    690:     t = rtype(s);
                    691:     s = t->chain;
                    692:     lb = s->symvalue.rangev.lower;
                    693:     ub = s->symvalue.rangev.upper;
                    694:     if (i < lb or i > ub) {
                    695:        warning("subscript out of range");
                    696:     }
                    697:     push(long, base + (i - lb) * size(t->type));
                    698: }
                    699: 
                    700: /*
                    701:  * Initialize typetable information.
                    702:  */
                    703: 
                    704: public c_modinit (typetable)
                    705: Symbol typetable[];
                    706: {
                    707:     /* nothing right now */
                    708: }
                    709: 
                    710: public boolean c_hasmodules ()
                    711: {
                    712:     return false;
                    713: }
                    714: 
                    715: public boolean c_passaddr (param, exprtype)
                    716: Symbol param, exprtype;
                    717: {
                    718:     boolean b;
                    719:     Symbol t;
                    720: 
                    721:     t = rtype(exprtype);
                    722:     b = (boolean) (t->class == ARRAY);
                    723:     return b;
                    724: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.