|
|
1.1 root 1: /*ident "@(#)ctrans:src/print2.c 1.3.6.27" */
2: /**************************************************************************
3:
4: C++ source for cfront, the C++ compiler front-end
5: written in the computer science research center of Bell Labs
6:
7: Copyright (c) 1984 AT&T, Inc. All rigths Reserved
8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
9:
10: print.c:
11:
12: print names and declarations
13:
14: ****************************************************************************/
15:
16: #include "cfront.h"
17:
18: extern FILE* out_file;
19: bit Cast;
20: int last_ll = 1;
21: Pin curr_icall;
22: char emode;
23: int ntok;
24:
25: static int MAIN; // fudge to get _main() called by main()
26:
27: #define eprint(e) if (e) Eprint(e)
28:
29: #ifdef DENSE
30: void chop(char*);
31: #endif
32:
33: void puttok(TOK t)
34: /*
35: print the output representation of "t"
36: */
37: {
38: // if (t<=0 || MAXTOK<t) error("illegal token %d",t);
39: // char* s = keys[t];
40: // if (s == 0) error("V representation token %d",t);
41:
42: putstring(keys[t]);
43:
44: if (12<ntok++) {
45: ntok = 0;
46: last_line.putline();
47: }
48: else if (t == SM) {
49: ntok = 0;
50: putch('\n');
51: if (last_ll) last_line.line++;
52: }
53: else
54: putch(' ');
55: }
56:
57: #define MX 20
58: #define NTBUF 10
59: class dcl_buf {
60: /*
61: buffer for assembling declaration (or cast)
62: left contains CONST_PTR => *CONST
63: CONST_RPTR => &CONST
64: PTR => *
65: RPTR => &
66: LP => (
67: right contains RP => )
68: VEC => [ rnode ]
69: FCT => ( rnode )
70: FIELD => : rnode
71: */
72: Pbase b;
73: Pname n;
74: TOK left[MX], right[MX];
75: Pnode rnode[MX];
76: Pclass lnode[MX];
77: int li, ri;
78: public:
79: void init(Pname nn) { b=0; n=nn; li=ri=0; }
80: void base(Pbase bb) { b = bb; }
81: void front(TOK t) { left[++li] = t; }
82: void front(Pclass c) { left[++li] = MEMPTR; lnode[li] = c; }
83: void back(TOK t, Pnode nod) { right[++ri] = t; rnode[ri] = nod; }
84: void paran() { front(LP); back(RP,0); }
85: void put();
86: } *tbufvec[NTBUF] = {0}, *tbuf = 0;
87:
88: int freetbuf = 0;
89:
90: void dcl_buf::put()
91: {
92: int i;
93: Pfct ff = 0;
94:
95: if (MX<=li || MX<=ri) error('i',"T buffer overflow");
96: if (b == 0) error('i',"noBT%s",Cast?" in cast":"");
97:
98: if (n && n->n_sto && n->n_sto!=REGISTER) puttok(n->n_sto);
99:
100: b->dcl_print();
101:
102: for( ; li; li--) {
103: switch (left[li]) {
104: case LP:
105: putch('(');
106: break;
107: case PTR:
108: putch('*');
109: break;
110: case RPTR:
111: if (emode)
112: putch('&');
113: else
114: putch('*');
115: break;
116: case CONST_PTR:
117: if (emode)
118: putstring("*const ");
119: else
120: putch('*');
121: break;
122: case CONST_RPTR:
123: if (emode)
124: putstring("&const ");
125: else
126: putch('*');
127: break;
128: case MEMPTR:
129: if (lnode[li]) fprintf(out_file,"%s::",lnode[li]->string);
130: }
131: }
132:
133: if (n) n->print();
134:
135: for(i=1; i<=ri; i++) {
136: switch (right[i]) {
137: case RP:
138: putch(')');
139: break;
140: case VEC:
141: putch('[');
142: { Pvec v = (Pvec) rnode[i];
143: Pexpr d = v->dim;
144: int s = v->size;
145: if (d) d->print();
146: if (s) fprintf(out_file,"%d",s);
147: }
148: putch(']');
149: break;
150: case FCT: // beware of function returning pointer to
151: // function expressed witout typedef
152: { Pfct f = Pfct(rnode[i]);
153: if (f->body) ff = f;
154: f->dcl_print();
155: break;
156: }
157: case FIELD:
158: { Pbase f = (Pbase) rnode[i];
159: Pexpr d = (Pexpr)f->b_name;
160: int s = f->b_bits;
161: putch(':');
162: if (d)
163: d->print();
164: else if (s)
165: fprintf(out_file,"%d",s);
166: else
167: puttok(ZERO);
168: break;
169: }
170: }
171: }
172: void print_body(Pfct);
173: if (ff && emode==0) print_body(ff);
174: }
175:
176: void name::dcl_print(TOK list)
177: /*
178: Print the declaration for a name (list==0) or a name list (list!=0):
179: For each name
180: (1) print storage class
181: (2) print base type
182: (3) print the name with its declarators
183: Avoid (illegal) repetition of basetypes which are class or enum declarations
184: (A name list may contain names with different base types)
185: list == SM : terminator SM
186: list == 0: single declaration with terminator SM
187: list == CM : separator CM
188: */
189: {
190: if (error_count) return;
191:
192: for (Pname n=this; n; n=n->n_list) {
193: Ptype t = n->tp;
194: int sm = 0;
195:
196: //error('d',"%s->dcl_print() tp %t sto %k",n->string,t,n->n_sto);
197:
198: if (t == 0) error('i',"N::dcl_print(%n)T missing",n);
199:
200: if (t->base == TYPE) { // unroll local typedefs:
201: Pname bn = Pbase(t)->b_name;
202: if (bn->lex_level
203: && bn->tp->base != COBJ
204: && bn->tp->base != EOBJ )
205: n->tp = t = bn->tp;
206: }
207:
208: switch (t->base) { // HACK, recursive unroller needed
209: case PTR:
210: case VEC:
211: if (Pptr(t)->typ->base == TYPE) { // unroll local typedefs:
212: Pname bn = Pbase(Pptr(t)->typ)->b_name;
213: if (bn->lex_level
214: && bn->tp->base != COBJ
215: && bn->tp->base != EOBJ )
216: Pptr(t)->typ = bn->tp;
217: }
218: }
219:
220: if (n->n_stclass==ENUM) if (list) continue; else return;
221:
222: if (n->where.line!=last_line.line || n->where.file!=last_line.file)
223: if (last_ll = n->where.line)
224: n->where.putline();
225: else
226: last_line.putline();
227:
228: int tc = Pbase(t)->b_const;
229: for (Ptype tt = t; tt->base==TYPE; tt = Pbase(tt)->b_name->tp)
230: tc |= Pbase(tt)->b_const;
231:
232: switch (t->base) {
233: case CLASS:
234: //fprintf(stderr,"class %s->dcl_print()\n",n->string);
235: if (n->base != TNAME) {
236: Pclass(t)->dcl_print(n);
237: sm = 1;
238: }
239: break;
240:
241: case ENUM:
242: Penum(t)->dcl_print(0);
243: sm = 1;
244: break;
245:
246: case FCT:
247: { Pfct f = Pfct(t);
248:
249: if (n->base == TNAME) puttok(TYPEDEF);
250:
251: //error('d',"fct %n->dcl_print() printed %d body %d defined %d",n,n->n_dcl_printed,f->body,f->defined);
252: //error('d',"n %d tbl %d tp %t inline %d",n,n->n_table,n->tp,f->f_inline);
253: if (n->n_dcl_printed==2 // definition already printed
254: || (n->n_dcl_printed==1 && f->body==0)
255: // declaration already printed
256: ) {
257: // don't print again
258: sm = 1; // no SM
259: break;
260: }
261:
262: if (f->f_result == 0) make_res(f);
263:
264: if (f->body && n->n_sto==EXTERN) n->n_sto = 0;
265:
266: if (f->f_inline) {
267: if (debug_opt) {
268: //error('d',"f %t defined %d inline %d",f,f->defined,f->f_inline);
269: if (f->defined&DEFINED
270: && f->defined&SIMPLIFIED
271: && f->f_inline!=ITOR)
272: goto prnt_def;
273: else if (n->n_dcl_printed==0)
274: goto prnt_dcl;
275: else {
276: sm = 1;
277: break;
278: }
279: }
280: if (f->f_virtual || n->n_addr_taken) {
281: prnt_dcl:
282: //error('d',"prnt_dcl %d %n %k",n,n,n->n_sto);
283: TOK st = n->n_sto;
284: Pblock b = f->body;
285: f->body = 0;
286: t->dcl_print(n);
287: n->n_dcl_printed = 1;
288: n->n_sto = st;
289: f->body = b;
290: break;
291: }
292: else
293: sm = 1; // no SM
294: }
295: else if ((f->defined&DEFINED)==0
296: || (f->defined&SIMPLIFIED)==0)
297: goto prnt_dcl;
298: else if (n->n_table==gtbl && strcmp(n->string,"main")==0) {
299: MAIN = 1;
300: gtbl->look("main",0)->use();
301: f->f_signature = 0;
302: t->dcl_print(n);
303: n->n_dcl_printed = f->body?2:1;
304: MAIN = 0;
305: }
306: else {
307: prnt_def:
308: //error('d',"prnt_def %n %k %d %k",n,n->n_oper,n,n->n_sto);
309: if (n->n_oper==CTOR || n->n_oper==DTOR) {
310: Pclass cl = Pclass(n->n_table->t_name->tp);
311: if (cl->c_body == 3) cl->print_all_vtbls(cl);
312: }
313: t->dcl_print(n);
314: n->n_dcl_printed = f->body?2:1;
315: }
316: if (f->body) sm = 1;
317: break;
318: }
319:
320: case OVERLOAD:
321: {
322: for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l) {
323: Pname nn = gl->f;
324: nn->dcl_print(0);
325: sm = 1;
326: }
327: break;
328: }
329:
330: case ASM:
331: fprintf(out_file,"asm(\"%s\")\n",(char*)Pbase(t)->b_name);
332: break;
333:
334: case INT:
335: case EOBJ:
336: case CHAR:
337: case LONG:
338: case SHORT:
339: tcx:
340: // do not allocate space for constants unless necessary
341: if (tc
342: && n->n_sto!=EXTERN // extern const one;
343: // const one = 1;
344: // allocates storage
345: && (n->n_scope==EXTERN // FUDGE const one = 1;
346: // is treated as static
347: // need loader support
348: || n->n_scope==STATIC
349: || n->n_scope==FCT)
350: ) {
351: if (n->n_evaluated) {
352: sm = 1; /* no ; */
353: break;
354: }
355: }
356: tc = 0;
357: // no break;
358:
359: default:
360: {
361: /*
362: // don't print local instance of const
363: if ( n->n_dcl_printed == 3 ) {
364: sm = 1;
365: break;
366: }
367: */
368: Pexpr i = n->n_initializer;
369: if (tc) {
370: switch (tt->base) {
371: case CHAR:
372: case SHORT:
373: case INT:
374: case LONG:
375: case EOBJ:
376: goto tcx;
377: }
378: }
379:
380: if (n->base == TNAME) {
381: for (Pname tn=ktbl->look(n->string,HIDDEN); tn; tn=tn->n_tbl_list)
382: if (tn
383: && tn->lex_level
384: && t==tn->tp) return;
385: puttok(TYPEDEF);
386: }
387:
388: if (n->n_stclass == REGISTER) {
389: // (imperfect) check against member functions
390: // register s a; a.f() illegal
391: Pname cln = n->tp->is_cl_obj();
392: if (cln) {
393: Pclass cl = Pclass(cln->tp);
394: if (cl->csu!=CLASS
395: && cl->baselist==0
396: && cl->has_itor()==0
397: && cl->virt_count==0) puttok(REGISTER);
398: }
399: else
400: puttok(REGISTER);
401: }
402:
403: if (i) {
404: if (n->n_sto==EXTERN && n->n_stclass==STATIC) {
405: n->n_initializer = 0;
406: t->dcl_print(n);
407: puttok(SM);
408: n->n_initializer = i;
409: n->n_sto = 0;
410: t->dcl_print(n);
411: n->n_sto = EXTERN;
412: }
413: else
414: t->dcl_print(n);
415: }
416: else if (n->n_evaluated && Pbase(t)->b_const) {
417: if (n->n_sto==EXTERN && n->n_stclass==STATIC) {
418: int v = n->n_evaluated;
419: n->n_evaluated = 0;
420: t->dcl_print(n);
421: puttok(SM);
422: n->n_evaluated = v;
423: n->n_sto = 0;
424: t->dcl_print(n);
425: n->n_sto = EXTERN;
426: }
427: else
428: t->dcl_print(n);
429: }
430: else {
431: //error('d',"%n sto %k val %d stc %k",n,n->n_sto,n->n_val,n_stclass);
432: if ((n->n_sto==0 || (n->n_val && n->n_evaluated==0))
433: && n_stclass==STATIC
434: && n->n_sto!=STATIC
435: && n->n_table==gtbl) {
436: if (n->n_val && n->n_evaluated==0) {
437: // extern x = f();
438: // generate int x = 0;
439: // plus dynamic initialization
440: n->n_sto = 0;
441: }
442: Ptype tt = t;
443: zaq:
444: switch (tt->base) {
445: case TYPE:
446: tt = Pbase(tt)->b_name->tp; goto zaq;
447: case COBJ: // "X a;" == "X a = {0};"
448: {
449: TOK csu = Pclass(Pbase(tt)->b_name->tp)->csu;
450: if (csu != UNION)
451: n->n_initializer = i = new expr(ILIST,zero,0);
452: break;
453: }
454: case PTR:
455: if (tt->memptr()) {
456: i = new expr(ELIST,zero,zero);
457: n->n_initializer = i = new expr(ILIST,i,zero);
458: break;
459: }
460: // no break
461: case CHAR:
462: case SHORT:
463: case INT:
464: case EOBJ:
465: case LONG:
466: case FLOAT:
467: case DOUBLE:
468: case LDOUBLE: // "int a;" == "int a = 0;"
469: n->n_initializer = i = zero;
470: }
471: }
472: t->dcl_print(n);
473: }
474:
475: if (n->n_scope!=ARG) {
476: if (i) {
477: puttok(ASSIGN);
478:
479: Pexpr i2 = i;
480: while (i2->base == CAST) i2 = i2->e1;
481: if (i2->base == ILIST) i = i2;
482: if (t!=i->tp
483: && i->base!=ZERO
484: && i->base!=ILIST /*&& i->tp!=Pchar_type*/) {
485: Ptype t1 = n->tp;
486: cmp:
487: switch (t1->base) {
488: case TYPE:
489: t1 = Pbase(t1)->b_name->tp;
490: goto cmp;
491: default:
492: i->print();
493: break;
494: // case EOBJ:
495: // goto cst;
496: case VEC:
497: if (Pvec(t1)->typ->base==CHAR) {
498: i->print();
499: break;
500: }
501: // no break
502: case PTR:
503: case RPTR:
504: if (i->tp==0 || n->tp->check(i->tp,0)) {
505: // cst:
506: putch('(');
507: bit oc = Cast;
508: Cast = 1;
509: t->print();
510: Cast = oc;
511: putch(')');
512: }
513: eprint(i);
514: }
515: }
516: else {
517: if (i==zero) {
518: while (t->base == TYPE) t = Pbase(t)->b_name->tp;
519: // if (t->base == EOBJ) {
520: // putch('(');
521: // bit oc = Cast;
522: // Cast = 1;
523: // t->print();
524: // Cast = oc;
525: // putch(')');
526: // }
527: }
528: eprint(i);
529:
530: // i->print();
531: }
532: }
533: else if (n->n_evaluated) {
534: puttok(ASSIGN);
535: if (n->tp->base!=INT || n->tp->is_unsigned()) {
536: putstring("((");
537: bit oc = Cast;
538: Cast = 1;
539: n->tp->print();
540: Cast = oc;
541: fprintf(out_file,")%d)",n->n_val);
542: }
543: else
544: fprintf(out_file,"%d",n->n_val);
545: }
546: }
547: }
548: }
549:
550: switch (list) {
551: case SM:
552: if (sm==0) puttok(SM);
553: break;
554: case 0:
555: if (sm==0) puttok(SM);
556: return;
557: case CM:
558: if (n->n_list) puttok(CM);
559: break;
560: }
561: }
562: }
563:
564: char *local_sign( Ptype pt )
565: { // get function signature for local class
566: char buf[256];
567: char* bb = pt->signature(buf);
568: int ll = bb-buf;
569: if (255 < ll) error('i',"local class N buffer overflow");
570: char *p = new char[ll+1];
571: strcpy(p,buf);
572: return p;
573: }
574:
575:
576: void enumdef::dcl_print(Pname cln)
577: /*
578: */
579: {
580: char* s = cln ? cln->string : 0;
581: fprintf(out_file,"enum %s { ",string);
582: for (Pname px, p=mem; p; p=px) {
583: px = p->n_list;
584: if (s) {
585: if (p->n_initializer)
586: fprintf(out_file,"%s__%s = %d",p->string,s,p->n_val);
587: else
588: fprintf(out_file,"%s__%s",p->string,s);
589: }
590: else {
591: if (p->n_initializer)
592: fprintf(out_file,"%s = %d",p->string,p->n_val);
593: else
594: fprintf(out_file,"%s",p->string);
595: }
596: if (px) puttok(CM);
597: p->n_initializer = 0;
598: delete p;
599: }
600: mem = 0;
601: puttok(RC);
602: puttok(SM);
603: }
604:
605:
606: extern char *make_local_name(Pclass,int=0);
607:
608: void name::print()
609: /*
610: print just the name itself
611: */
612: {
613: if (this == 0) error('i',"0->N::print()");
614:
615: if (string == 0) {
616: if (emode) putch('?');
617: return;
618: }
619:
620: // error( 'd', "%s->name::print(), base: %k", string, base );
621:
622: switch (base) {
623: case TNAME:
624: putst(string);
625: return;
626: case MDOT:
627: Pexpr(this)->print();
628: return;
629: }
630:
631: if (emode) {
632: Ptable tbl;
633: char* cs = 0;
634: bit f = 0;
635: if (tp) {
636: switch (tp->base) {
637: case OVERLOAD:
638: case FCT:
639: f = 1;
640: default:
641: if (tbl=n_table) {
642: if (tbl == gtbl) {
643: if (f == 0) putstring("::");
644: }
645: else {
646: if (tbl->t_name) {
647: cs = tbl->t_name->string;
648: fprintf(out_file,"%s::",cs);
649: }
650: }
651: }
652:
653: // local class will need to modify ???
654: if (n_scope==ARG && strcmp(string,"this")==0) {
655: // tell which "this" it is
656: Ptype tt = Pptr(tp)->typ;
657: Pname cn = Pbase(tt)->b_name;
658: fprintf(out_file,"%s::",cn->string);
659: }
660:
661: case CLASS:
662: case ENUM:
663: // case TYPE:
664: break;
665: }
666: nop:
667: switch (n_oper) {
668: case TYPE:
669: putstring("operator ");
670: if (tp) Pfct(tp)->returns->dcl_print(0);
671: break;
672: case 0:
673: putstring(string);
674: break;
675: case DTOR:
676: putch('~');
677: case CTOR:
678: if (cs)
679: putstring(cs);
680: else {
681: putstring("constructor");
682: f = 0;
683: }
684: break;
685: case TNAME:
686: putstring(string);
687: break;
688: default:
689: putstring("operator ");
690: putstring(keys[n_oper]);
691: break;
692: }
693: if (f) putstring("()");
694: }
695: else {
696: if (n_oper) goto nop;
697: if (string) putstring(string);
698: }
699: return;
700: }
701:
702: char* sig = 0;
703: Pclass cl = 0;
704: int i = n_union;
705:
706: if (tp) {
707: Ptable tbl;
708:
709: switch (tp->base) {
710: default:
711: if (tbl=n_table) { // global or member
712: Pname tn;
713: if (tbl == gtbl) {
714: // if (i) fprintf(out_file,"__O%d.",i);
715: if ( i ) {
716: if (n_anon)
717: fprintf(out_file,"__O%d.%s.", i, n_anon );
718: else fprintf(out_file,"__O%d.",i);
719: }
720: break;
721: }
722:
723: if (tn=tbl->t_name) {
724: cl = Pclass(tn->tp);
725: if (i) {
726: if (cl->string[0]=='_'
727: && cl->string[1]=='_'
728: && cl->string[2]=='C' )
729: {
730: if (n_anon)
731: fprintf(out_file,"__O%d.%s.", i, n_anon );
732: else fprintf(out_file,"__O%d.",i);
733: }
734: else
735: if ( cl->lex_level )
736: {
737: char *str = make_local_name(cl,1);
738: fprintf(out_file,"__O%d%s.",i,str);
739: delete str;
740: }
741: else
742: fprintf(out_file,"__O%d__%d%s.",i,cl->strlen,cl->string);
743: cl = 0;
744: }
745: else if (cl->string[0]=='_'
746: && cl->string[1]=='_'
747: && cl->string[2]=='C'
748: && n_stclass != STATIC )
749: cl = 0;
750: break;
751: }
752: }
753:
754: switch (n_stclass) { // local variable
755: case STATIC:
756: case EXTERN:
757: if (i)
758: fprintf(out_file,"__O%d.",i);
759: else if (n_sto==STATIC && tp->base!=FCT) {
760: if (lex_level == 0)
761: putstring("__S");
762: else
763: fprintf(out_file,"__%d",lex_level);
764: }
765: break;
766: default:
767: // encode with lexicallevel UNLESS ``special''
768: // e.g. __builtin
769: if (string[0]!='_' || string[1]!='_' || string[2] != 'C' ) {
770: // error( 'd', "print2 i: %d, lex_level: %d this: %n", i, lex_level,this );
771: if (i)
772: {
773: if (n_anon)
774: fprintf(out_file,"__%d__O%d.%s.",lex_level-1,i,n_anon);
775: else fprintf(out_file,"__%d__O%d.",lex_level-1,i);
776: }
777: else
778: fprintf(out_file,"__%d",lex_level);
779: }
780: }
781: break;
782: case CLASS:
783: case ENUM:
784: break;
785: }
786:
787: if (tp->base==FCT) {
788: sig = Pfct(tp)->f_signature;
789: if (sig && sig[0]==0) sig = 0;
790: }
791: }
792:
793: if (string) {
794: #ifdef DENSE
795: int i = strlen(string);
796: if (cl) i += cl->strlen+4; // __dd<class name>
797: if (sig) {
798: if (cl == 0) i += 2;
799: i += strlen(sig);
800: }
801:
802: if (31<i) {
803: char buf[256];
804: if (cl && sig)
805: sprintf(buf,"%s__%d%s%s",string,cl->strlen,cl->string,sig);
806: else if (cl)
807: sprintf(buf,"%s__%d%s",string,cl->strlen,cl->string);
808: else if (sig)
809: sprintf(buf,"%s__%s",string,sig);
810: else
811: sprintf(buf,"%s",string);
812: chop(buf);
813: fprintf(out_file,"%s ",buf);
814: return;
815: }
816: #endif
817: putstring(string);
818:
819: // local class
820: if ( cl ) {
821: if ( cl->lex_level ) {
822: char *str = str = make_local_name( cl, 1 );
823: putstring( str );
824: delete str;
825: }
826: else fprintf(out_file,"__%d%s",cl->strlen,cl->string);
827: }
828:
829: if (sig) {
830: if (cl == 0) putstring("__");
831: putstring(sig);
832: }
833: putch(' ');
834:
835: }
836: }
837:
838: #ifdef DENSE
839: void chop(char* buf)
840: {
841: static char alpha[] = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
842: static const asz = sizeof(alpha)-1;
843: int hash = 0;
844: char* p = &buf[29];
845:
846: while (*p) {
847: hash <<= 1;
848: if (hash & (1<<12)) {
849: hash &= ~(1<<12);
850: hash++;
851: }
852: hash ^= *p++;
853: }
854:
855: buf[29] = alpha[(int)(hash%asz)];
856: buf[30] = alpha[(int)((hash/asz)%asz)];
857: buf[31] = 0;
858: }
859: #endif
860:
861: void type::print()
862: {
863: switch (base) {
864: case PTR:
865: case RPTR:
866: case VEC:
867: Pptr(this)->dcl_print(0);
868: break;
869: case FCT:
870: Pfct(this)->dcl_print();
871: break;
872: // case VEC:
873: // Pvec(this)->dcl_print(0);
874: // break;
875: case CLASS:
876: case ENUM:
877: if (emode)
878: fprintf(out_file,"%k",base);
879: else
880: // error('i',"%p->T::print(%k %s)",this,base,Pclass(this)->string);
881: fprintf(out_file,"struct %s *",Pclass(this)->string);
882: break;
883: case TYPE:
884: if (Cast) {
885: Pbase(this)->b_name->tp->print();
886: break;
887: }
888: // no break
889: default:
890: Pbase(this)->dcl_print();
891: }
892: }
893:
894: char* type::signature(register char* p)
895: /*
896: take a signature suitable for argument types for overloaded
897: function names
898: */
899: {
900: Ptype t = this;
901: int pp = 0; // pointer to
902:
903: xx:
904: //error('d',"xx(%d) %d %k",this,t,t->base);
905:
906: // first unroll typedefs and handle derived types:
907:
908: switch (t->base) {
909: case TYPE:
910: if (Pbase(t)->b_const) *p++ = 'C';
911: t = Pbase(t)->b_name->tp;
912: goto xx;
913:
914: case VEC:
915: if (pp && Pvec(t)->size) { // A<size>_
916: *p++ = 'A';
917: sprintf(p,"%d\0",Pvec(t)->size); // don't trust
918: // sprintf return value
919: while (*++p);
920: *p++ = '_';
921: }
922: else
923: *p++ = 'P';
924: t = Pvec(t)->typ;
925: pp = 1;
926: goto xx;
927:
928: case PTR:
929: if (Pptr(t)->rdo) *p++ = 'C'; // *const
930: if (Pptr(t)->memof) { // M<size><classname>
931: Pclass cl = Pptr(t)->memof;
932: register char* s = cl->string;
933: int d = cl->strlen;
934: if (d==0) cl->strlen = d = strlen(s);
935: *p++ = 'M';
936: if (d/10) *p++ = '0'+d/10;
937: *p++ = '0'+ d%10; // assume <100 char
938: while (*p++ = *s++);
939: --p; // not the '\0'
940: }
941: else
942: *p++ = 'P';
943: t = Pptr(t)->typ;
944: pp = 1;
945: goto xx;
946:
947: case RPTR:
948: *p++ = 'R';
949: t = Pptr(t)->typ;
950: pp = 1;
951: goto xx;
952:
953: case FCT:
954: { Pfct f = Pfct(t);
955: Pname n = f->argtype;
956:
957: if (f->f_const) *p++ = 'C'; // constant member function
958: if (f->f_static) *p++ = 'S'; // static member function
959: // if (f->memof && f->f_this==0) *p++ = 'S'; //SSS static member function
960: *p++ = 'F';
961: if (n == 0)
962: *p++ = 'v'; // VOID, that is f() == f(void)
963: else
964: for ( ; n; n=n->n_list) { // print argument encoding
965: // check if argtype is the same
966: // as previously seen argtype
967: int i = 0;
968: for (Pname nn=f->argtype; n!=nn; nn=nn->n_list) {
969: i++;
970: if (nn->tp==n->tp || nn->tp->check(n->tp,0)==0) {
971: // typeof (n) == typeof(arg i)
972: int x = 1; // try for a run after n
973: Pname nnn = n;
974: while ((nnn=nnn->n_list) && x<9) {
975: if (nnn->tp==n->tp
976: || nnn->tp->check(n->tp,0)==0) {
977: x++;
978: n = nnn;
979: }
980: else
981: break;
982: }
983:
984: if (x == 1) // Ti
985: *p++ = 'T';
986: else { // Nxi
987: *p++ = 'N';
988: *p++ = '0'+x;
989: }
990:
991: // assume <100 arguments
992: if (9<i) *p++ = '0'+i/10;
993: *p++ = '0'+i%10;
994: goto zk;
995: }
996: }
997:
998: // ``normal'' case print argument type signature
999: // if (n->n_xref) *p++ = 'R';
1000: p = n->tp->signature(p);
1001: zk:;
1002: }
1003:
1004: if (f->nargs_known == ELLIPSIS) *p++ = 'e';
1005:
1006: if (pp) { // '_' result type
1007: *p++ = '_';
1008: p = f->returns->signature(p);
1009: }
1010:
1011: *p = 0;
1012: return p;
1013: }
1014: }
1015:
1016: // base type modifiers:
1017:
1018: if ( Pbase(t)->b_const ) *p++ = 'C';
1019: // if ( Pbase(t)->b_signed ) *p++ = 'S';
1020: if ( Pbase(t)->b_unsigned ) *p++ = 'U';
1021: // if ( Pbase(t)->b_volatile ) *p++ = 'V';
1022:
1023:
1024: // now base types:
1025:
1026: register char* s;
1027: int d;
1028: Pclass cl;
1029: //lll:
1030: switch (t->base) {
1031: // case TNAME: t = Pbase(t)->b_name->tp; goto lll;
1032: case ANY: break;
1033: case ZTYPE: break;
1034: case VOID: *p++ = 'v'; break;
1035: case CHAR: *p++ = 'c'; break;
1036: case SHORT: *p++ = 's'; break;
1037: // case EOBJ:
1038: case INT: *p++ = 'i'; break;
1039: case LONG: *p++ = 'l'; break;
1040: case FLOAT: *p++ = 'f'; break;
1041: case DOUBLE: *p++ = 'd'; break;
1042: case LDOUBLE: *p++ = 'r'; break;
1043: case EOBJ:
1044: // *p++ = 'i';
1045: // break;
1046: { Penum en = Penum(Pbase(t)->b_name->tp);
1047: // t = en->e_type;
1048: // goto lll;
1049: s = en->string;
1050: d = en->strlen;
1051: if (d==0) en->strlen = d = strlen(s);
1052: goto pppp;
1053: }
1054:
1055: case COBJ:
1056: { cl = Pclass(Pbase(t)->b_name->tp);
1057: s = cl->string;
1058: d = cl->strlen;
1059: if (d==0) cl->strlen = d = strlen(s);
1060: pppp:
1061: if (d/10) *p++ = '0'+d/10;
1062: *p++ = '0'+ d%10; // assume less that 99 characters
1063: while (*p++ = *s++);
1064: --p;
1065: break;
1066: }
1067: case FIELD:
1068: default:
1069: error('i',"signature of %k",t->base);
1070: }
1071:
1072: *p = 0;
1073: return p;
1074: }
1075:
1076: void basetype::dcl_print()
1077: {
1078: Pname nn;
1079: Pclass cl;
1080:
1081: if (emode) {
1082: if (b_virtual) puttok(VIRTUAL);
1083: if (b_inline) puttok(INLINE);
1084: if (b_const) puttok(CONST);
1085: }
1086: if (b_unsigned) puttok(UNSIGNED);
1087:
1088: switch (base) {
1089: case ANY:
1090: if (emode)
1091: putstring("any ");
1092: else
1093: putstring("int ");
1094: break;
1095:
1096: case ZTYPE:
1097: if (emode)
1098: putstring("zero ");
1099: else
1100: putstring("int ");
1101: break;
1102:
1103: case VOID:
1104: if (emode==0 && ansi_opt==0) {
1105: // silly trick to bypass BSD C compiler bug
1106: // void* (*)() dosn't work there
1107: // note simpl.c knows that VOID -> CHAR grep for VCVC
1108: puttok(CHAR);
1109: break;
1110: }
1111: case CHAR:
1112: case SHORT:
1113: case INT:
1114: case LONG:
1115: case FLOAT:
1116: case DOUBLE:
1117: case LDOUBLE:
1118: puttok(base);
1119: break;
1120:
1121: case EOBJ:
1122: nn = b_name;
1123: eob:
1124: if (emode == 0)
1125: // puttok(INT);
1126: Penum(nn->tp)->e_type->dcl_print();
1127: else {
1128: puttok(ENUM);
1129: nn->print();
1130: }
1131: break;
1132:
1133: case COBJ:
1134: nn = b_name;
1135: cob:
1136: cl = Pclass(nn->tp);
1137: if (cl && (cl->csu==UNION || cl->csu==ANON))
1138: puttok(UNION);
1139: else
1140: puttok(STRUCT);
1141: { // local class
1142: char* s = 0;
1143: if ( cl && cl->lex_level ) s = make_local_name( cl );
1144: putst(s?s:nn->string);
1145: delete s;
1146: }
1147: break;
1148:
1149: case TYPE:
1150: if (emode == 0) {
1151: switch (b_name->tp->base) {
1152: case COBJ:
1153: nn = Pbase(b_name->tp)->b_name;
1154: goto cob;
1155: case EOBJ:
1156: nn = Pbase(b_name->tp)->b_name;
1157: goto eob;
1158: // default:
1159: // {
1160: // if (b_name->lex_level !=0 )
1161: // {
1162: // error('d', "default: %n %t", b_name, b_name->tp );
1163: // Pbase(b_name->tp)->dcl_print();
1164: // b_name->tp->print();
1165: // return;
1166: // }
1167: // }
1168:
1169: }
1170: }
1171: b_name->print();
1172: break;
1173:
1174: default:
1175: if (emode) {
1176: if (0<base && base<=MAXTOK && keys[base])
1177: fprintf(out_file," %s",keys[base]);
1178: else
1179: putch('?');
1180: }
1181: else
1182: error('i',"%p->BT::dcl_print(%d)",this,base);
1183: }
1184: }
1185: Pbase memptr_type;
1186:
1187: void type::dcl_print(Pname n)
1188: /*
1189: "this" type is the type of "n". Print the declaration
1190: */
1191: {
1192: //error('d',"%p::dcl_print(%n)",this,n);
1193: Ptype t = this;
1194: Pptr p;
1195: TOK pre = 0;
1196:
1197: if (t == 0) error('i',"0->dcl_print()");
1198: if (n && n->tp!=t) error('i',"not %n'sT (%p)",n,t);
1199:
1200: if (base == OVERLOAD) {
1201: for (Plist gl=Pgen(this)->fct_list; gl; gl=gl->l) {
1202: Pname nn = gl->f;
1203: nn->tp->dcl_print(nn);
1204: if (gl->l) puttok(SM);
1205: }
1206: return;
1207: }
1208:
1209: tbuf = tbufvec[freetbuf];
1210: if (tbuf == 0) {
1211: if (freetbuf == NTBUF-1) error('i',"AT nesting overflow");
1212: tbufvec[freetbuf] = tbuf = new class dcl_buf;
1213: }
1214: freetbuf++;
1215: tbuf->init(n);
1216: if (n && n->n_xref) tbuf->front(PTR);
1217:
1218: while (t) {
1219: TOK k;
1220:
1221: switch (t->base) {
1222: case PTR:
1223: p = Pptr(t);
1224: k = (p->rdo) ? CONST_PTR : PTR;
1225: goto ppp;
1226: case RPTR:
1227: p = Pptr(t);
1228: k = (p->rdo) ? CONST_RPTR : RPTR;
1229: ppp:
1230: if (p->memof) {
1231: if (emode) {
1232: tbuf->front(k);
1233: tbuf->front(p->memof);
1234: }
1235: else {
1236: t = p->typ;
1237: while (t->base==TYPE) t = Pbase(t)->b_name->tp;
1238: if (t->base == FCT) {
1239: extern Pbase mptr_type;
1240: tbuf->base(mptr_type);
1241: goto zaq;
1242: }
1243: else
1244: tbuf->front(k);
1245: }
1246: }
1247: else
1248: tbuf->front(k);
1249: pre = PTR;
1250: t = p->typ;
1251: break;
1252: case VEC:
1253: { Pvec v = Pvec(t);
1254: if (Cast && pre != PTR && pre != VEC) { // for Macintosh: ptr to array uses [] notation
1255: tbuf->front(PTR);
1256: pre = PTR;
1257: }
1258: else {
1259: if (pre == PTR) tbuf->paran();
1260: tbuf->back(VEC,v);
1261: pre = VEC;
1262: }
1263: t = v->typ;
1264: break;
1265: }
1266:
1267: case FCT:
1268: { Pfct f = Pfct(t);
1269: if (pre == PTR)
1270: tbuf->paran();
1271: else if (emode && f->memof && n==0)
1272: tbuf->front(f->memof);
1273: tbuf->back(FCT,f);
1274: pre = FCT;
1275: t = (f->s_returns) ? f->s_returns : f->returns;
1276: break;
1277: }
1278: case FIELD:
1279: tbuf->back(FIELD,t);
1280: tbuf->base( Pbase(Pbase(t)->b_fieldtype) );
1281: t = 0;
1282: break;
1283: case 0:
1284: error('i',"noBT(B=0)");
1285: case TYPE:
1286: if (Cast) { // unravel type in case it contains vectors
1287: t = Pbase(t)->b_name->tp;
1288: break;
1289: }
1290:
1291: default: // the base has been reached
1292: if (emode) {
1293: char* s;
1294: for (Ptype tt = t; tt->base==TYPE; tt=Pbase(tt)->b_name->tp);
1295: switch (tt->base) {
1296: case CLASS:
1297: s = Pclass(tt)->string;
1298: if (s[0]=='_' &&s[1]=='_' && s[2]=='C') s="class";
1299: goto fret;
1300: case ENUM:
1301: s = "enum";
1302: goto fret;
1303: case OVERLOAD:
1304: s = "overloaded";
1305: fret:
1306: putstring(s);
1307: freetbuf--;
1308: return;
1309: }
1310: }
1311:
1312: tbuf->base( Pbase(t) );
1313: goto zaq;
1314: } // switch
1315: } // while
1316: zaq:
1317: tbuf->put();
1318: freetbuf--;
1319: }
1320:
1321: void fct::dcl_print()
1322: {
1323: Pname nn;
1324: //error('d',"fct::dcl_print()");
1325: if (emode) {
1326: putch('(');
1327: for (nn=argtype; nn;) {
1328: nn->tp->dcl_print(0);
1329: if (nn=nn->n_list) puttok(CM); else break;
1330: }
1331: switch (nargs_known) {
1332: case 0: // putst("?"); break;
1333: case ELLIPSIS: puttok(ELLIPSIS); break;
1334: }
1335: putch(')');
1336: if (f_const) puttok(CONST);
1337: if (f_static) puttok(STATIC); // wrong place for ``static''
1338: return;
1339: }
1340:
1341: Pname at = f_args;
1342: putch('(');
1343:
1344: if (ansi_opt) {
1345: // print typed arguments:
1346: at = (f_this) ? f_this : (f_result) ? f_result : argtype;
1347: // WNG -- note: at = f_args had 0 value with ansi_opt set
1348: // mystery fix added here
1349: if (at == 0) {
1350: if (nargs_known == ELLIPSIS) {
1351: putch(')');
1352: return;
1353: }
1354: puttok(VOID);
1355: }
1356: else if (body && Cast==0)
1357: at->dcl_print(CM); // print argument type and name
1358: else {
1359: for (nn=at; nn;) {
1360: // nn->tp->dcl_print(0); // print argument type
1361: nn->tp->dcl_print(nn); // print argument type
1362: // (there may not be a name)
1363: if (nn=nn->n_list) puttok(CM); else break;
1364: }
1365: }
1366: if (nargs_known == ELLIPSIS) putstring(",...");
1367: putch(')');
1368: }
1369: else {
1370: // print argument names followed by argument type declarations:
1371: if (body && Cast==0) {
1372: for (nn=at; nn;) {
1373: nn->print();
1374: if (nn=nn->n_list) puttok(CM); else break;
1375: }
1376: putch(')');
1377: }
1378: else
1379: putch(')');
1380: }
1381: }
1382:
1383: void print_body(Pfct f)
1384: {
1385: if (Cast==0) {
1386:
1387: if (ansi_opt==0 && f->f_args) f->f_args->dcl_print(SM);
1388:
1389: if (MAIN) {
1390: putstring("{ _main(); "); // call constructors
1391: f->body->print();
1392: puttok(RC);
1393: }
1394: else
1395: f->body->print();
1396: }
1397: }
1398:
1399: Pbcl shared_seen;
1400:
1401: void classdef::print_members()
1402: {
1403: int i;
1404:
1405: Pbcl l = baselist;
1406: // error('d',"%t->print_members()",this);
1407: if (l) {
1408: if (l->base == NAME) {
1409: l->bclass->print_members(); // first base only
1410: // pad to ensure alignment:
1411: int boff = l->bclass->real_size;
1412: int ba = l->bclass->align();
1413: int xtra = boff%ba;
1414: int waste = (xtra) ? ba-xtra : 0; // padding
1415: //error('d',"%s: size % align %d waste %d",string,boff,ba,waste);
1416: if (waste) {
1417: // waste it to protect against structure
1418: // assignments to the base class
1419: char* s = make_name('W');
1420: fprintf(out_file,"char %s[%d];\n",s,waste);
1421: delete s;
1422: }
1423: l = l->next;
1424: }
1425:
1426: for (; l; l=l->next)
1427: /* for second base etc. one must allocate as an object
1428: (rather than a list of members) to ensure proper alignment
1429: for shared base allocate a pointer
1430: size, alignment, & offset handled in cassdef::dcl()
1431: */
1432: if (l->base == NAME) {
1433: Pclass bcl = l->bclass;
1434: puttok(STRUCT);
1435: putst(bcl->string);
1436: putcat('O',bcl->string);
1437: puttok(SM);
1438: }
1439: }
1440:
1441: for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i)) {
1442: if (nn->base==NAME
1443: && nn->n_union==0
1444: && nn->tp->base!=FCT
1445: && nn->tp->base!=OVERLOAD
1446: && nn->tp->base!=CLASS
1447: && nn->tp->base!=ENUM
1448: && nn->n_stclass != STATIC) {
1449: if (nn->tp->base==FIELD && Pbase(nn->tp)->b_bits==0) continue;
1450: Pexpr i = nn->n_initializer;
1451: nn->n_initializer = 0;
1452: nn->dcl_print(0);
1453: nn->n_initializer = i;
1454: }
1455: }
1456:
1457: for (l=baselist; l; l=l->next)
1458: if (l->base==VIRTUAL && l->ptr_offset) {
1459: Pclass bcl = l->bclass;
1460: char* bs = bcl->string;
1461:
1462: puttok(STRUCT); // struct bcl* Pbcl;
1463: putst(bs);
1464: putch('*');
1465: putcat('P',bs);
1466: puttok(SM);
1467: }
1468: }
1469:
1470: void classdef::print_vtbl(Pvirt vtab)
1471: {
1472: //error('d',"%s->print_vtbl(%s) vtbl_opt %d",string,vtab->string,vtbl_opt);
1473: // error('d',"print_vtbl: lex_level: %d", lex_level );
1474:
1475: // switch (vtbl_opt) {
1476: // case -1:
1477: // case 1:
1478: vlist = new vl(this,vtab,vlist);
1479: // }
1480:
1481: int oo = vtbl_opt; // make `simulated static' name
1482: vtbl_opt = -1;
1483: char* str = lex_level ? make_local_name(this) : 0;
1484: char* s = vtbl_name(vtab->string,str?str:string);
1485: vtbl_opt = oo;
1486: // char* s = vtbl_name(vtab->string,string);
1487: // fprintf(out_file,"extern struct __mptr %s[];\n",s);
1488: s[2] = 'p'; // pointer, not tbl itself
1489: fprintf(out_file,"extern struct __mptr* %s;\n",s);
1490:
1491: delete s;
1492: delete str;
1493: }
1494:
1495: vl* vlist;
1496:
1497: void really_really_print(Pclass cl, Pvirt vtab, char* s, char* ss);
1498:
1499: int p2(Pname nn, Ptype t, Pclass cl, Pvirt vtab, char* s)
1500: {
1501: int init;
1502:
1503: if (t->base == FCT) {
1504: Pfct f = Pfct(t);
1505:
1506: //error('d',"p2 %n init %d inline %d virtual %d",nn,nn->n_initializer,f->f_inline,f->f_virtual);
1507: //error('d',"p2 %s expr %d imeasure %d body %d",s,f->f_expr,f->f_imeasure,f->body);
1508: //error('d',"sto %k",nn->n_sto);
1509: if (nn->n_initializer
1510: || nn->n_sto==STATIC
1511: || f->f_inline
1512: || f->f_imeasure
1513: || f->f_virtual==0) return 0;
1514: init = f->body!=0;
1515: }
1516: else
1517: init = nn->n_initializer!=0;
1518:
1519: int oo = vtbl_opt;
1520: vtbl_opt = 1; // make sure the name is universal
1521: char* sstr = cl->lex_level ? make_local_name(cl) : 0;
1522: char* ss = vtbl_name(vtab->string,sstr?sstr:cl->string);
1523:
1524: if (init) { // unique definition here
1525: really_really_print(cl,vtab,ss,s);
1526: }
1527: else { // unique definition elsewhere
1528: //error('d',"elsewhere %n %s",nn,ss);
1529: fprintf(out_file,"extern struct __mptr %s[];\n",ss);
1530: s[2] = 'p';
1531: fprintf(out_file,"struct __mptr* %s = ",s);
1532: fprintf(out_file,"%s;\n",ss);
1533: }
1534: vtbl_opt = oo;
1535:
1536: delete ss;
1537: delete sstr;
1538:
1539: return 1;
1540: }
1541:
1542: void classdef::really_print(Pvirt vtab)
1543: {
1544: //error('d',"really_print %t %d",this,vtbl_opt);
1545: int oo = vtbl_opt; // make `simulated static' name
1546: vtbl_opt = -1;
1547: char* str = lex_level ? make_local_name(this) : 0;
1548: char* s = vtbl_name(vtab->string,str?str:string);
1549: vtbl_opt = oo;
1550:
1551: // see if needed
1552: int i;
1553: for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
1554: Ptype t = nn->tp;
1555: zse:
1556: if (t)
1557: switch (t->base) {
1558: case TYPE:
1559: t = Pbase(t)->b_name->tp;
1560: goto zse;
1561: /*
1562: case COBJ:
1563: if (nn->n_sto == EXTERN)
1564: { Pclass cl = Pclass(Pbase(t)->b_name->tp);
1565: if (cl->has_ctor()) {
1566: p2(nn,t,this,vtab,s);
1567: return;
1568: }
1569: }
1570: break;
1571: */
1572: case FCT:
1573: if (p2(nn,t,this,vtab,s)) return;
1574: break;
1575:
1576: case OVERLOAD:
1577: { for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l)
1578: if (p2(gl->f,gl->f->tp,this,vtab,s)) return;
1579: }
1580: }
1581: }
1582:
1583: if (vtbl_opt) {
1584: // make vtbl name according to option:
1585: char* sstr = lex_level ? make_local_name(this) : 0;
1586: char* ss = vtbl_name(vtab->string,str?str:string);
1587: really_really_print(this,vtab,ss,s);
1588:
1589: delete ss;
1590: delete sstr;
1591: }
1592:
1593: delete s;
1594: delete str;
1595: }
1596:
1597: void really_really_print(Pclass, Pvirt vtab, char* s, char* ss)
1598: {
1599: //error('d',"really %s",s);
1600: // make sure function is declared before using
1601: // it in vtbl initializer
1602: Pname nn;
1603: int i;
1604: for (i=0; nn = vtab->virt_init[i].n; i++) {
1605: Pfct f = Pfct(nn->tp);
1606: if (nn->n_initializer) { // pure virtual
1607: static pv;
1608: if (pv == 0) { // VCVC void->char assumed
1609: fprintf(out_file,"char __pure_virtual_called();\n");
1610: pv = 1;
1611: }
1612: continue;
1613: }
1614: if (f->base != FCT) error('i',"vtbl %n",nn);
1615: //void expand_dtor(Pclass cl);
1616: // if (f->f_inline == IDTOR) expand_dtor(f->memof);
1617:
1618: if (nn->n_dcl_printed==0 /*|| f->f_inline*/) {
1619: if (f->f_inline && vtbl_opt) puttok(STATIC);
1620: if (f->f_result == 0) make_res(f);
1621: Ptype r = f->s_returns ? f->s_returns : f->returns;
1622: r->print();
1623: nn->print();
1624: putstring("()");
1625: puttok(SM);
1626: nn->n_dcl_printed = 1;
1627: }
1628: }
1629:
1630: // if (vtbl_opt == -1) puttok(STATIC);
1631:
1632:
1633: fprintf(out_file,"struct __mptr %s[] = {0,0,0,\n",s);
1634:
1635: Pname n;
1636: for (i=0; n=vtab->virt_init[i].n; i++) {
1637: if (n->n_initializer)
1638: putstring("0,0,(__vptp)__pure_virtual_called,\n");
1639: else {
1640: fprintf(out_file,"%d,0,(__vptp)",-vtab->virt_init[i].offset);
1641: n->print();
1642: n->n_addr_taken = 1;
1643: putstring(",\n");
1644: }
1645: }
1646: putstring("0,0,0};\n");
1647:
1648: ss[2] = 'p';
1649: fprintf(out_file,"struct __mptr* %s = ",ss);
1650: s[2] = 'v';
1651: fprintf(out_file,"%s;\n",s);
1652:
1653: //error('d',"really-> %s",s);
1654: }
1655:
1656: #include <ctype.h>
1657: extern char* src_file_name;
1658: char* vtbl_name(char* s1, char* s2)
1659: {
1660: //extern Pname def_name;
1661: char* s3 = (vtbl_opt == -1 && src_file_name) ? src_file_name : 0;
1662: // if vtbl_opt == -1 fake a static (there are no portable
1663: // way of doing a forward declaration of a static in C)
1664: int ll = s1 ? strlen(s1) : 0;
1665: int ll2 = strlen(s2);
1666: int ll3 = s3 ? strlen(s3) : 0;
1667: // int ll4 = s3&&def_name ? strlen(def_name->string) : 0;
1668: // int sz = (ll+ll2+ll3+ll4+22)/32+1; // avoid fragmentation
1669: int sz = (ll+ll2+ll3+20)/32+1; // avoid fragmentation
1670:
1671: sz *= 32;
1672: //error('d',"vtbl_name(%s,%s,%s) %d",s1?s1:"",s2,s3?s3:"",sz);
1673: char* buf = new char[sz];
1674: if (s3) {
1675: // if (s1 && def_name)
1676: // sprintf(buf,"__vtbl__%d%s__%d%s__%s__%s",ll,s1,ll2,s2,s3,def_name->string);
1677: // else
1678: if (s1)
1679: sprintf(buf,"__vtbl__%d%s__%d%s__%s",ll,s1,ll2,s2,s3);
1680: // else if (def_name)
1681: // sprintf(buf,"__vtbl__%d%s__%s__%s",ll2,s2,s3,def_name->string);
1682: else
1683: sprintf(buf,"__vtbl__%d%s__%s",ll2,s2,s3);
1684: }
1685: else if (s1)
1686: sprintf(buf,"__vtbl__%d%s__%d%s",ll,s1,ll2,s2);
1687: else
1688: sprintf(buf,"__vtbl__%d%s",ll2,s2);
1689:
1690: if (vtbl_opt == -1) {
1691: for (char* p = buf+ll2+11; *p; p++)
1692: if (!isalpha(*p) && !isdigit(*p)) *p = '_';
1693: }
1694: #ifdef DENSE
1695: chop(buf);
1696: #endif
1697: return buf;
1698: }
1699:
1700: void classdef::print_all_vtbls(Pclass bcl)
1701: {
1702: //error('d',"%t->print_all_vtbls(%t) vlt %d bl %d",this,bcl,virt_list,baselist);
1703:
1704: for (Pvirt blist = bcl->virt_list; blist; blist = blist->next) {
1705: if (this != blist->vclass) continue;
1706: if (blist->printed) continue;
1707: // if (blist->string==0 && find_vptr(this)==0) { //BSopt
1708: // continue;
1709: // }
1710: print_vtbl(blist);
1711: blist->printed = 1;
1712: }
1713:
1714: for (Pbcl b = bcl->baselist; b; b = b->next)
1715: print_all_vtbls(b->bclass);
1716:
1717: if (this==bcl) c_body = 0;
1718: }
1719:
1720: void classdef::dcl_print(Pname)
1721: {
1722: if (c_body==0 || c_body==3 || (defined&DEFINED)==0) return;
1723: c_body = 3;
1724:
1725: int i;
1726: //error('d',"%t->classdef::dcl_print",this);
1727: for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
1728: if (nn->base==NAME
1729: && nn->n_union==0
1730: && nn->tp->base==CLASS
1731: && Pclass(nn->tp)->c_body==1)
1732: Pclass(nn->tp)->dcl_print(nn);
1733: else if (nn->base == TNAME && Pbase(nn->tp)->base != COBJ)
1734: nn->dcl_print(0);
1735: else if (nn->tp && nn->tp->base == ENUM)
1736: Penum(nn->tp)->dcl_print(nn);
1737: }
1738:
1739: TOK lvl = lex_level ? LOCAL : 0;
1740: Pname n = ktbl->look(string,lvl);
1741: if (n==0) n = ktbl->look(string,HIDDEN);
1742:
1743: if (n) {
1744: if (n->where.line!=last_line.line
1745: || n->where.file!=last_line.file)
1746: if (last_ll = n->where.line)
1747: n->where.putline();
1748: else
1749: last_line.putline();
1750: }
1751:
1752: TOK c = csu==CLASS ? STRUCT : csu;
1753: puttok(c);
1754: // if (string[0]!='_' || string[1]!='_' || string[2]!='C')
1755:
1756: char *str = 0;
1757: if ( lex_level ) str = make_local_name( this );
1758: putst(str?str:string);
1759:
1760: int sm = 0;
1761: int sz = tsizeof();
1762: int dvirt = 0;
1763:
1764: fprintf(out_file,"{\t/* sizeof %s == %d */\n",str?str:string,obj_size);
1765: delete str;
1766:
1767: print_members();
1768: for (Pbcl b = baselist; b; b = b->next) { // declare virtual classes
1769: if (b->base != VIRTUAL) continue;
1770: Pclass bcl = b->bclass;
1771: dvirt += bcl->virt_count;
1772: //error('d',"%t in %t %d",b->bclass,this,b->allocated);
1773: if (b->allocated==0) continue;
1774: puttok(STRUCT); // struct bcl Obcl;
1775: putst(bcl->string);
1776: putcat('O',bcl->string);
1777: puttok(SM);
1778: }
1779: putstring("};\n");
1780:
1781: for (nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
1782: if (nn->base==NAME && nn->n_union==0) {
1783: Ptype t = nn->tp;
1784: switch (t->base) {
1785: case FCT:
1786: case OVERLOAD:
1787: break;
1788: default:
1789: if (nn->n_stclass == STATIC) {
1790: TOK b = nn->n_sto;
1791: //error('d',"print nn %n tp %t b %k eval %d",nn,nn->tp,b,nn->n_evaluated);
1792: /*
1793: Pname cn;
1794: TOK bb = ((cn=nn->tp->is_cl_obj())
1795: && Pclass(cn->tp)->has_ctor())==0
1796: ?0:b; // force explicit initialization
1797: nn->n_sto = (nn->n_evaluated) ? STATIC : bb;
1798: */
1799: nn->n_sto = (nn->n_evaluated) ? STATIC : b;
1800: nn->dcl_print(0);
1801: nn->n_sto = b;
1802: }
1803: }
1804: }
1805: }
1806: if (vtbl_opt != -1) print_all_vtbls(this); // force declaration
1807: //error('d',"dcl_print -> ");
1808: }
1809:
1810:
1811: char *
1812: make_local_name( Pclass cl, int ln )
1813: {
1814: char *buf;
1815: if ( cl->in_fct == 0 ) error( 'i', "localC %s missingFN", cl->string );
1816: char *fsig = Pfct(cl->in_fct->tp)->f_signature;
1817: if ( fsig == 0 ) fsig = local_sign( cl->in_fct->tp );
1818: char *fs = cl->in_fct->string;
1819: int class_len=cl->strlen+strlen(fsig)+strlen(fs)+strlen(cl->lcl)+4;
1820: int sz = (class_len+20)/32+1; // from vtbl_name()
1821:
1822: if ( Pfct(cl->in_fct->tp)->memof == 0 ) {
1823: sz *= 32;
1824: buf = new char[ sz ];
1825: // error('d', "make_local_name: sz: %d", sz );
1826:
1827: if (ln)
1828: sprintf(buf, "__%d%s__%s__%s%s", class_len, cl->string, fs, fsig, cl->lcl);
1829: else
1830: sprintf(buf, "%s__%s__%s%s", cl->string, fs, fsig, cl->lcl);
1831: }
1832: else
1833: {
1834: char *cs = Pclass(Pfct(cl->in_fct->tp)->memof)->string;
1835: int len = Pclass(Pfct(cl->in_fct->tp)->memof)->strlen;
1836: if ( len < 10 )
1837: ++class_len;
1838: else
1839: if ( len > 99 )
1840: class_len += 3;
1841: else class_len += 2;
1842: class_len += len;
1843: sz = (class_len+20)/32+1;
1844: sz *= 32;
1845: buf = new char[ sz ];
1846: // error('d', "make_local_name: sz: %d", sz );
1847:
1848: if ( ln )
1849: sprintf(buf, "__%d%s__%s__%d%s%s%s",class_len,cl->string,fs,len,cs,fsig,cl->lcl);
1850: else sprintf(buf, "%s__%s__%d%s%s%s",cl->string,fs,len,cs,fsig,cl->lcl);
1851: }
1852:
1853: #ifdef DENSE
1854: chop( buf );
1855: #endif
1856:
1857: return buf;
1858: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.