file reorg, pathnames.h, paths.h
[unix-history] / usr / src / old / dbx / c.c
index 60e371a..1bfe08d 100644 (file)
@@ -1,6 +1,14 @@
-/* Copyright (c) 1982 Regents of the University of California */
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)c.c        5.8 (Berkeley) %G%";
+#endif not lint
 
 
-static char sccsid[] = "@(#)c.c 1.3 %G%";
+static char rcsid[] = "$Header: c.c,v 1.5 88/04/02 01:25:44 donn Exp $";
 
 /*
  * C-dependent symbol routines.
 
 /*
  * C-dependent symbol routines.
@@ -19,32 +27,48 @@ static char sccsid[] = "@(#)c.c 1.3 %G%";
 #include "runtime.h"
 #include "machine.h"
 
 #include "runtime.h"
 #include "machine.h"
 
+#ifndef public
+#   include "tree.h"
+#endif
+
 #define isdouble(range) ( \
     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
 )
 
 #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
 
 #define isdouble(range) ( \
     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
 )
 
 #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
 
+private Language langC;
+private Language langCplpl;
+
 /*
  * Initialize C language information.
  */
 
 public c_init()
 {
 /*
  * Initialize C language information.
  */
 
 public c_init()
 {
-    Language lang;
-
-    lang = language_define("c", ".c");
-    language_setop(lang, L_PRINTDECL, c_printdecl);
-    language_setop(lang, L_PRINTVAL, c_printval);
-    language_setop(lang, L_TYPEMATCH, c_typematch);
-    language_setop(lang, L_BUILDAREF, c_buildaref);
-    language_setop(lang, L_EVALAREF, c_evalaref);
+    langC = language_define("c", ".c");
+    language_setop(langC, L_PRINTDECL, c_printdecl);
+    language_setop(langC, L_PRINTVAL, c_printval);
+    language_setop(langC, L_TYPEMATCH, c_typematch);
+    language_setop(langC, L_BUILDAREF, c_buildaref);
+    language_setop(langC, L_EVALAREF, c_evalaref);
+    language_setop(langC, L_MODINIT, c_modinit);
+    language_setop(langC, L_HASMODULES, c_hasmodules);
+    language_setop(langC, L_PASSADDR, c_passaddr);
+
+    langCplpl = language_define("c++", "..c");
+    language_setop(langCplpl, L_PRINTDECL, c_printdecl);
+    language_setop(langCplpl, L_PRINTVAL, c_printval);
+    language_setop(langCplpl, L_TYPEMATCH, c_typematch);
+    language_setop(langCplpl, L_BUILDAREF, c_buildaref);
+    language_setop(langCplpl, L_EVALAREF, c_evalaref);
+    language_setop(langCplpl, L_MODINIT, c_modinit);
+    language_setop(langCplpl, L_HASMODULES, c_hasmodules);
+    language_setop(langCplpl, L_PASSADDR, c_passaddr);
 }
 
 /*
  * Test if two types are compatible.
 }
 
 /*
  * Test if two types are compatible.
- *
- * Integers and reals are not compatible since they cannot always be mixed.
  */
 
 public Boolean c_typematch(type1, type2)
  */
 
 public Boolean c_typematch(type1, type2)
@@ -60,55 +84,40 @@ Symbol type1, type2;
     } else {
        t1 = rtype(t1);
        t2 = rtype(t2);
     } else {
        t1 = rtype(t1);
        t2 = rtype(t2);
-       if (t1->type == t_int or t1->type == t_char) {
+       if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) {
            tmp = t1;
            t1 = t2;
            t2 = tmp;
        }
        b = (Boolean) (
            (
            tmp = t1;
            t1 = t2;
            t2 = tmp;
        }
        b = (Boolean) (
            (
-               isrange(t1, "int") and
-               (t2->type == t_int or t2->type == t_char)
+               isrange(t1, "int") and !isdouble(t1) /* sigh */ and
+               (t2 == t_int->type or t2 == t_char->type)
            ) or (
                isrange(t1, "char") and
            ) or (
                isrange(t1, "char") and
-               (t2->type == t_char or t2->type == t_int)
+               (t2 == t_char->type or t2 == t_int->type)
            ) or (
            ) or (
-               t1->type == t2->type and (
+               t1->class == RANGE and isdouble(t1) and t2 == t_real->type
+           ) or (
+               t1->class == RANGE and t2->class == RANGE and
+               t1->symvalue.rangev.lower == t2->symvalue.rangev.lower and
+               t1->symvalue.rangev.upper == t2->symvalue.rangev.upper
+           ) or (
+               t1->class != RANGE and t1->type == t2->type and (
                    (t1->class == t2->class) or
                    (t1->class == SCAL and t2->class == CONST) or
                    (t1->class == CONST and t2->class == SCAL)
                )
                    (t1->class == t2->class) or
                    (t1->class == SCAL and t2->class == CONST) or
                    (t1->class == CONST and t2->class == SCAL)
                )
+           ) or (
+               t1->class == PTR and c_typematch(t1->type, t_char) and
+               t2->class == ARRAY and c_typematch(t2->type, t_char) and
+               t2->language == primlang
            )
        );
     }
     return b;
 }
 
            )
        );
     }
     return b;
 }
 
-/*
- * Decide if a field is a bit field.
- */
-
-private Boolean isbitfield(s)
-register Symbol s;
-{
-    Boolean b;
-    register Integer off, len;
-    register Symbol t;
-
-    off = s->symvalue.field.offset;
-    len = s->symvalue.field.length;
-    if ((off mod BITSPERBYTE) != 0 or (len mod BITSPERBYTE) != 0) {
-       b = true;
-    } else {
-       t = rtype(s->type);
-       b = (Boolean)
-           (t->class == SCAL and len != (sizeof(int)*BITSPERBYTE) or
-           len != (size(t)*BITSPERBYTE)
-       );
-    }
-    return b;
-}
-
 /*
  * Print out the declaration of a C variable.
  */
 /*
  * Print out the declaration of a C variable.
  */
@@ -137,8 +146,9 @@ Integer indent;
     switch (s->class) {
        case CONST:
            if (s->type->class == SCAL) {
     switch (s->class) {
        case CONST:
            if (s->type->class == SCAL) {
-               printf("(enumeration constant, ord %ld)",
-                   s->symvalue.iconval);
+               printf("enumeration constant with value ");
+               eval(s->symvalue.constval);
+               c_printval(s);
            } else {
                printf("const %s = ", symname(s));
                printval(s);
            } else {
                printf("const %s = ", symname(s));
                printval(s);
@@ -147,12 +157,8 @@ Integer indent;
 
        case TYPE:
        case VAR:
 
        case TYPE:
        case VAR:
-           if (s->class != TYPE) {
-               if (s->level == 2) {
-                   printf("static ");
-               } else if (s->level < 0) {
-                   printf("register ");
-               }
+           if (s->class != TYPE and s->storage == INREG) {
+               printf("register ");
            }
            if (s->type->class == ARRAY) {
                printtype(s->type, s->type->type, indent);
            }
            if (s->type->class == ARRAY) {
                printtype(s->type, s->type->type, indent);
@@ -201,10 +207,15 @@ Integer indent;
        case RECORD:
        case VARNT:
        case PTR:
        case RECORD:
        case VARNT:
        case PTR:
+       case FFUNC:
            semicolon = false;
            printtype(s, s, indent);
            break;
 
            semicolon = false;
            printtype(s, s, indent);
            break;
 
+       case SCAL:
+           printf("(enumeration constant, value %d)", s->symvalue.iconval);
+           break;
+
        case PROC:
            semicolon = false;
            printf("%s", symname(s));
        case PROC:
            semicolon = false;
            printf("%s", symname(s));
@@ -234,7 +245,8 @@ Integer indent;
            break;
 
        default:
            break;
 
        default:
-           error("class %s in c_printdecl", classname(s));
+           printf("[%s]", classname(s));
+           break;
     }
     if (semicolon) {
        putchar(';');
     }
     if (semicolon) {
        putchar(';');
@@ -298,7 +310,7 @@ Integer indent;
                    printf("%s ", p);
                }
            }
                    printf("%s ", p);
                }
            }
-           printf("{\n", t->class == RECORD ? "struct" : "union");
+           printf("{\n");
            for (i = t->chain; i != nil; i = i->chain) {
                assert(i->class == FIELD);
                printdecl(i, indent+4);
            for (i = t->chain; i != nil; i = i->chain) {
                assert(i->class == FIELD);
                printdecl(i, indent+4);
@@ -341,6 +353,7 @@ Integer indent;
            break;
 
        case FUNC:
            break;
 
        case FUNC:
+       case FFUNC:
            printtype(t, t->type, indent);
            printf("()");
            break;
            printtype(t, t->type, indent);
            printf("()");
            break;
@@ -431,7 +444,8 @@ Symbol s;
 {
     register Symbol t;
     register Address a;
 {
     register Symbol t;
     register Address a;
-    register int i, len;
+    integer i, len;
+    register String str;
 
     switch (s->class) {
        case CONST:
 
     switch (s->class) {
        case CONST:
@@ -445,21 +459,12 @@ Symbol s;
 
        case FIELD:
            if (isbitfield(s)) {
 
        case FIELD:
            if (isbitfield(s)) {
-               len = s->symvalue.field.length;
-               if (len <= BITSPERBYTE) {
-                   i = pop(char);
-               } else if (len <= sizeof(short)*BITSPERBYTE) {
-                   i = pop(short);
-               } else {
-                   i = pop(long);
-               }
-               i >>= (s->symvalue.field.offset mod BITSPERBYTE);
-               i &= ((1 << len) - 1);
+               i = extractField(s);
                t = rtype(s->type);
                if (t->class == SCAL) {
                t = rtype(s->type);
                if (t->class == SCAL) {
-                   printenum(i, t);
+                   printEnum(i, t);
                } else {
                } else {
-                   printrange(i, t);
+                   printRangeVal(i, t);
                }
            } else {
                c_printval(s->type);
                }
            } else {
                c_printval(s->type);
@@ -468,29 +473,41 @@ Symbol s;
 
        case ARRAY:
            t = rtype(s->type);
 
        case ARRAY:
            t = rtype(s->type);
-           if (t->class == RANGE and istypename(t->type, "char")) {
+           if ((t->class == RANGE and istypename(t->type, "char")) or
+               t == t_char->type
+           ) {
                len = size(s);
                len = size(s);
-               sp -= len;
-               printf("\"%.*s\"", len, sp);
+               str = (String) (sp -= len);
+               if (s->language != primlang) {
+                   putchar('"');
+               }
+               while (--len > 0 and *str != '\0') {
+                   printchar(*str++);
+               }
+               if (*str != '\0') {     /* XXX - pitch trailing null */
+                   printchar(*str);
+               }
+               if (s->language != primlang) {
+                   putchar('"');
+               }
            } else {
                printarray(s);
            }
            break;
 
        case RECORD:
            } else {
                printarray(s);
            }
            break;
 
        case RECORD:
-       case VARNT:
            c_printstruct(s);
            break;
 
        case RANGE:
            c_printstruct(s);
            break;
 
        case RANGE:
-           if (istypename(s->type, "boolean")) {
-               printrange(popsmall(s), s);
-           } else if (istypename(s->type, "char")) {
-               printrange(pop(char), s);
-           } else if (isdouble(s)) {
+           if (s == t_boolean->type or istypename(s->type, "boolean")) {
+               printRangeVal(popsmall(s), s);
+           } else if (s == t_char->type or istypename(s->type, "char")) {
+               printRangeVal(pop(char), s);
+           } else if (s == t_real->type or isdouble(s)) {
                switch (s->symvalue.rangev.lower) {
                    case sizeof(float):
                switch (s->symvalue.rangev.lower) {
                    case sizeof(float):
-                       prtreal(pop(float));
+                       prtreal((double) (pop(float)));
                        break;
 
                    case sizeof(double):
                        break;
 
                    case sizeof(double):
@@ -502,7 +519,7 @@ Symbol s;
                        break;
                }
            } else {
                        break;
                }
            } else {
-               printrange(popsmall(s), s);
+               printRangeVal(popsmall(s), s);
            }
            break;
 
            }
            break;
 
@@ -512,7 +529,7 @@ Symbol s;
            if (a == 0) {
                printf("(nil)");
            } else if (t->class == RANGE and istypename(t->type, "char")) {
            if (a == 0) {
                printf("(nil)");
            } else if (t->class == RANGE and istypename(t->type, "char")) {
-               printstring(a);
+               printString(a, (boolean) (s->language != primlang));
            } else {
                printf("0x%x", a);
            }
            } else {
                printf("0x%x", a);
            }
@@ -520,15 +537,24 @@ Symbol s;
 
        case SCAL:
            i = pop(Integer);
 
        case SCAL:
            i = pop(Integer);
-           printenum(i, s);
+           printEnum(i, s);
+           break;
+
+       /*
+        * Unresolved structure pointers?
+        */
+       case BADUSE:
+           a = pop(Address);
+           printf("@%x", a);
            break;
 
        default:
            if (ord(s->class) > ord(TYPEREF)) {
                panic("printval: bad class %d", ord(s->class));
            }
            break;
 
        default:
            if (ord(s->class) > ord(TYPEREF)) {
                panic("printval: bad class %d", ord(s->class));
            }
-           error("don't know how to print a %s", c_classname(s));
-           /* NOTREACHED */
+           sp -= size(s);
+           printf("[%s]", c_classname(s));
+           break;
     }
 }
 
     }
 }
 
@@ -536,12 +562,12 @@ Symbol s;
  * Print out a C structure.
  */
 
  * Print out a C structure.
  */
 
-private c_printstruct(s)
+private c_printstruct (s)
 Symbol s;
 {
 Symbol s;
 {
-    register Symbol f;
-    register Stack *savesp;
-    register Integer n, off, len;
+    Symbol f;
+    Stack *savesp;
+    integer n, off, len;
 
     sp -= size(s);
     savesp = sp;
 
     sp -= size(s);
     savesp = sp;
@@ -550,7 +576,7 @@ Symbol s;
     for (;;) {
        off = f->symvalue.field.offset;
        len = f->symvalue.field.length;
     for (;;) {
        off = f->symvalue.field.offset;
        len = f->symvalue.field.length;
-       n = (off + len + 7) div BITSPERBYTE;
+       n = (off + len + BITSPERBYTE - 1) div BITSPERBYTE;
        sp += n;
        printf("%s = ", symname(f));
        c_printval(f);
        sp += n;
        printf("%s = ", symname(f));
        c_printval(f);
@@ -562,84 +588,6 @@ Symbol s;
     printf(")");
 }
 
     printf(")");
 }
 
-/*
- * Print out a range type (integer, char, or boolean).
- */
-
-private printrange(i, t)
-Integer i;
-register Symbol t;
-{
-    if (istypename(t->type, "boolean")) {
-       printf(((Boolean) i) == true ? "true" : "false");
-    } else if (istypename(t->type, "char")) {
-       putchar('\'');
-       printchar(i);
-       putchar('\'');
-    } else if (t->symvalue.rangev.lower >= 0) {
-       printf("%lu", i);
-    } else {
-       printf("%ld", i);
-    }
-}
-
-/*
- * Print out a null-terminated string (pointer to char)
- * starting at the given address.
- */
-
-private printstring(addr)
-Address addr;
-{
-    register Address a;
-    register Integer i, len;
-    register Boolean endofstring;
-    union {
-       char ch[sizeof(Word)];
-       int word;
-    } u;
-
-    putchar('"');
-    a = addr;
-    endofstring = false;
-    while (not endofstring) {
-       dread(&u, a, sizeof(u));
-       i = 0;
-       do {
-           if (u.ch[i] == '\0') {
-               endofstring = true;
-           } else {
-               printchar(u.ch[i]);
-           }
-           ++i;
-       } while (i < sizeof(Word) and not endofstring);
-       a += sizeof(Word);
-    }
-    putchar('"');
-}
-
-/*
- * Print out an enumerated value by finding the corresponding
- * name in the enumeration list.
- */
-
-private printenum(i, t)
-Integer i;
-Symbol t;
-{
-    register Symbol e;
-
-    e = t->chain;
-    while (e != nil and e->symvalue.iconval != i) {
-       e = e->chain;
-    }
-    if (e != nil) {
-       printf("%s", symname(e));
-    } else {
-       printf("%d", i);
-    }
-}
-
 /*
  * Return the C name for the particular class of a symbol.
  */
 /*
  * Return the C name for the particular class of a symbol.
  */
@@ -667,23 +615,22 @@ Symbol s;
     }
     return str;
 }
     }
     return str;
 }
+
 public Node c_buildaref(a, slist)
 Node a, slist;
 {
     register Symbol t;
     register Node p;
     Symbol etype, atype, eltype;
 public Node c_buildaref(a, slist)
 Node a, slist;
 {
     register Symbol t;
     register Node p;
     Symbol etype, atype, eltype;
-    Node esub, r;
+    Node r, esub;
 
 
-    r = a;
     t = rtype(a->nodetype);
     eltype = t->type;
     if (t->class == PTR) {
        p = slist->value.arg[0];
        if (not compatible(p->nodetype, t_int)) {
            beginerrmsg();
     t = rtype(a->nodetype);
     eltype = t->type;
     if (t->class == PTR) {
        p = slist->value.arg[0];
        if (not compatible(p->nodetype, t_int)) {
            beginerrmsg();
-           fprintf(stderr, "bad type for subscript of ");
-           prtree(stderr, a);
+           fprintf(stderr, "subscript must be integer-compatible");
            enderrmsg();
        }
        r = build(O_MUL, p, build(O_LCON, (long) size(eltype)));
            enderrmsg();
        }
        r = build(O_MUL, p, build(O_LCON, (long) size(eltype)));
@@ -691,10 +638,12 @@ Node a, slist;
        r->nodetype = eltype;
     } else if (t->class != ARRAY) {
        beginerrmsg();
        r->nodetype = eltype;
     } else if (t->class != ARRAY) {
        beginerrmsg();
+       fprintf(stderr, "\"");
        prtree(stderr, a);
        prtree(stderr, a);
-       fprintf(stderr, " is not an array");
+       fprintf(stderr, "\" is not an array");
        enderrmsg();
     } else {
        enderrmsg();
     } else {
+       r = a;
        p = slist;
        t = t->chain;
        for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
        p = slist;
        t = t->chain;
        for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
@@ -703,9 +652,9 @@ Node a, slist;
            atype = rtype(t);
            if (not compatible(atype, etype)) {
                beginerrmsg();
            atype = rtype(t);
            if (not compatible(atype, etype)) {
                beginerrmsg();
-               fprintf(stderr, "subscript ");
+               fprintf(stderr, "subscript \"");
                prtree(stderr, esub);
                prtree(stderr, esub);
-               fprintf(stderr, " is the wrong type");
+               fprintf(stderr, "\" is the wrong type");
                enderrmsg();
            }
            r = build(O_INDEX, r, esub);
                enderrmsg();
            }
            r = build(O_INDEX, r, esub);
@@ -714,11 +663,12 @@ Node a, slist;
        if (p != nil or t != nil) {
            beginerrmsg();
            if (p != nil) {
        if (p != nil or t != nil) {
            beginerrmsg();
            if (p != nil) {
-               fprintf(stderr, "too many subscripts for ");
+               fprintf(stderr, "too many subscripts for \"");
            } else {
            } else {
-               fprintf(stderr, "not enough subscripts for ");
+               fprintf(stderr, "not enough subscripts for \"");
            }
            prtree(stderr, a);
            }
            prtree(stderr, a);
+           fprintf(stderr, "\"");
            enderrmsg();
        }
     }
            enderrmsg();
        }
     }
@@ -729,17 +679,46 @@ Node a, slist;
  * Evaluate a subscript index.
  */
 
  * Evaluate a subscript index.
  */
 
-public int c_evalaref(s, i)
+public c_evalaref(s, base, i)
 Symbol s;
 Symbol s;
+Address base;
 long i;
 {
 long i;
 {
+    Symbol t;
     long lb, ub;
 
     long lb, ub;
 
-    s = rtype(s)->chain;
+    t = rtype(s);
+    s = t->chain;
     lb = s->symvalue.rangev.lower;
     ub = s->symvalue.rangev.upper;
     if (i < lb or i > ub) {
     lb = s->symvalue.rangev.lower;
     ub = s->symvalue.rangev.upper;
     if (i < lb or i > ub) {
-       error("subscript out of range");
+       warning("subscript out of range");
     }
     }
-    return (i - lb);
+    push(long, base + (i - lb) * size(t->type));
+}
+
+/*
+ * Initialize typetable information.
+ */
+
+public c_modinit (typetable)
+Symbol typetable[];
+{
+    /* nothing right now */
+}
+
+public boolean c_hasmodules ()
+{
+    return false;
+}
+
+public boolean c_passaddr (param, exprtype)
+Symbol param, exprtype;
+{
+    boolean b;
+    Symbol t;
+
+    t = rtype(exprtype);
+    b = (boolean) (t->class == ARRAY);
+    return b;
 }
 }