Annotation of 42BSD/ucb/dbx/c.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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