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

unix.superglobalmegacorp.com

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