📄 dcl2.c
字号:
/* @(#) dcl2.c 1.5 1/27/86 17:48:40 */ /*ident "@(#)cfront:src/dcl2.c 1.5" *//************************************************************************** C++ source for cfront, the C++ compiler front-end written in the computer science research center of Bell Labs Copyright (c) 1984 AT&T, Inc. All Rights Reserved THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.dcl2.c:*************************************************************************/#include "cfront.h"#include "size.h"Pname classdef.has_ictor()/* does this class have a constructor taking no arguments?*/{ Pname c = has_ctor(); Pfct f; Plist l; if (c == 0) return 0; f = (Pfct)c->tp; switch (f->base) { default: error('i',"%s: bad constructor (%k)",string,c->tp->base); case FCT: switch (f->nargs) { case 0: return c; default: if (f->argtype->n_initializer) return c; } return 0; case OVERLOAD: for (l=Pgen(f)->fct_list; l; l=l->l) { Pname n = l->f; f = (Pfct)n->tp; switch (f->nargs) { case 0: return n; default: if (f->argtype->n_initializer) return n; } } return 0; }}gen.gen(char* s){ char * p = new char[ strlen(s)+1 ]; base = OVERLOAD; strcpy(p,s); string = p; fct_list = 0;}Pname gen.add(Pname n,int sig)/* add "n" to the tail of "fct_list" (overloaded names are searched in declaration order) detect: multiple identical declarations declaration after use multiple definitions*/{ Pfct f = (Pfct)n->tp; Pname nx; if (f->base != FCT) error(0,"%n: overloaded non-F",n); if ( fct_list && (nx=find(f)) ) {//error('d',"add old %n",nx);/* Pfct nf = (Pfct)nx->tp; if (nf->body) { if (f->body) error("two definitions for overloaded%n",n); } else { if (f->body) nf->body = f->body; }*/ Nold = 1; } else { char* s = string;//error('d',"add new %s",s); if (fct_list || sig || n->n_oper) { char buf[128]; char* bb = n->tp->signature(buf); int l1 = strlen(s); int l2 = bb-buf-1; char* p = new char[l1+l2+1]; strcpy(p,s); strcpy(p+l1,buf); n->string = p; } else n->string = s; nx = new name; *nx = *n; PERM(nx); Nold = 0; if (fct_list) { Plist gl; for (gl=fct_list; gl->l; gl=gl->l) ; gl->l = new name_list(nx,0); } else fct_list = new name_list(nx,0); nx->n_list = 0; } return nx;}Pname gen.find(Pfct f){ Plist gl; for (gl=fct_list; gl; gl=gl->l) { Pname nx = gl->f; Pfct fx = (Pfct)nx->tp; Pname a, ax; int vp = 0;//error('d',"find %s",nx->string); if (fx->nargs_known != f->nargs_known) { if (fx->nargs && fx->nargs_known!=ELLIPSIS) continue; } for (ax=fx->argtype, a=f->argtype; a&&ax; ax=ax->n_list, a=a->n_list) {//error('d',"ax %d %d a %d %d",ax->tp,ax->tp->base,a->tp,a->tp->base); Ptype at = ax->tp; if ( at->check(a->tp,0)) goto xx; if ( vrp_equiv ) vp = 1; switch (at->base) { case CHAR: case SHORT: case INT: case LONG: if (Pbase(at)->b_unsigned ^ Pbase(a->tp)->b_unsigned) error('w',"the overloading mechanism cannot tell an unsigned%k from a%k",at->base,at->base); } } if (ax) { if (ax->n_initializer) error("Ir makes overloaded %s() ambiguous",string); continue; } if (a) { if (a->n_initializer) error("Ir makes overloaded %s() ambiguous",string); continue; } if ( fx->returns->check(f->returns,0) ) error("two different return valueTs for overloaded %s: %t and %t", string, fx->returns, f->returns); if (vp) error('w',"ATs differ (only): [] vs *"); return nx; xx:; } return 0;}void classdef.dcl(Pname cname, Ptable tbl){ int nmem; Pname p; Pptr cct; Pbase bt; Pname px; Ptable btbl; int bvirt; Pclass bcl; int i; int fct_seen = 0; int static_seen = 0; int local = tbl!=gtbl; int byte_old = byte_offset; int bit_old = bit_offset; int max_old = max_align; int boff; int in_union; int usz; int make_ctor = 0; int make_dtor = 0; /* this is the place for paranoia */ if (this == 0) error('i',"0->Cdef.dcl(%d)",tbl); if (base != CLASS) error('i',"Cdef.dcl(%d)",base); if (cname == 0) error('i',"unNdC"); if (cname->tp != this) error('i',"badCdef"); if (tbl == 0) error('i',"Cdef.dcl(%n,0)",cname); if (tbl->base != TABLE) error('i',"Cdef.dcl(%n,tbl=%d)",cname,tbl->base); nmem = pubmem->no_of_names() + privmem->no_of_names() + pubdef->no_of_names(); in_union = (csu==UNION || csu==ANON); if (clbase) { if (clbase->base != TNAME) error("BC%nU",clbase); clbase = Pbase(clbase->tp)->b_name; bcl = (Pclass)clbase->tp; if ((bcl->defined&SIMPLIFIED) == 0) error("BC%nU",clbase); tbl = bcl->memtbl; if (tbl->base != TABLE) error('i',"badBC table %d",tbl); btbl = tbl; bvirt = bcl->virt_count; if (bcl->csu == UNION) error('s',"C derived from union"); if (in_union) error("derived union"); else if (pubbase == 0) csu = CLASS; boff = bcl->real_size; max_align = bcl->align(); bit_ass = bcl->bit_ass; } else { btbl = 0; bvirt = 0; boff = 0; if (!in_union) csu = (virt_count) ? CLASS : STRUCT; while (tbl!=gtbl && tbl->t_name) tbl = tbl->next; // nested classes max_align = AL_STRUCT; bit_ass = 1; // can be bitwise copied } memtbl->set_scope(tbl); memtbl->set_name(cname); if (nmem) memtbl->grow((nmem<=2)?3:nmem); cc->stack(); cc->not = cname; cc->cot = this;//error('d',"classdef%n",cname); byte_offset = usz = boff; bit_offset = 0; bt = new basetype(COBJ,cname); bt->b_table = memtbl; this_type = cc->tot = cct = new ptr(PTR,bt,0); PERM(cct); PERM(bt); for (p=privmem; p; p=px) { Pname m; px = p->n_list;//error('d',"privmem%n %d",p,p->tp->base); if (p->tp->base==FCT) { Pfct f = (Pfct)p->tp; Pblock b = f->body; f->body = 0; switch( p->n_sto ) { case AUTO: case STATIC: case REGISTER: case EXTERN: error("M%n cannot be%k",p,p->n_sto); p->n_sto = 0; } m = p->dcl(memtbl,0); if (b) { if (m->tp->defined&(DEFINED|SIMPLIFIED)) error("two definitions of%n",m); else if (p->where.line!=m->where.line) error('s',"previously declared%n cannot be defined inCD",p); else Pfct(m->tp)->body = b; } fct_seen = 1; } else { m = p->dcl(memtbl,0); if (m) { if (m->n_stclass==STATIC) { static_seen = 1; m->n_sto = (tbl == gtbl) ? 0 : STATIC; if (m->n_initializer) error('s',"staticM%n withIr",m); } if (in_union) { if (usz < byte_offset) usz = byte_offset; byte_offset = 0; } } } } if (privmem && csu==STRUCT) csu = CLASS; for (p=pubmem; p; p=px) { Pname m; px = p->n_list;//error('d',"pubmem%n %d",p,p->tp->base); if (p->tp->base == FCT) { Pfct f = (Pfct)p->tp; Pblock b = f->body; f->body = 0; switch(p->n_sto) { case AUTO: case STATIC: case REGISTER: case EXTERN: error("M%n cannot be%k",p,p->n_sto); p->n_sto = 0; } m = p->dcl(memtbl,PUBLIC); if (b) { if (m->tp->defined&(DEFINED|SIMPLIFIED)) error("two definitions of%n",m); else if (p->where.line!=m->where.line) error('s',"previously declared%n cannot be defined inCD",p); else Pfct(m->tp)->body = b; } fct_seen = 1; } else { m = p->dcl(memtbl,PUBLIC); if (m) { if (m->n_stclass==STATIC) { m->n_sto = (tbl == gtbl) ? 0 : STATIC; static_seen = 1; if (m->n_initializer) error('s',"staticM%n withIr",m); } if (in_union) { if (usz < byte_offset) usz = byte_offset; byte_offset = 0; } } } /*delete p;*/ }/* pubmem = 0;*/// if (local && fct_seen) error("FM of local%k %s",csu,string); if (in_union) byte_offset = usz; if (virt_count || bvirt) { /* assign virtual indices */ Pname vp[100]; Pname nn; nn = has_ctor(); if (nn==0 || nn->n_table!=memtbl) make_ctor = 1; { // FUDGE vtbl char* s = new char[20]; sprintf(s,"%s__vtbl",string); Pname n = new name(s); n->tp = Pfctvec_type; Pname nn = gtbl->insert(n,0); nn->use(); } if (virt_count = bvirt) for (i=0; i<bvirt; i++) vp[i] = bcl->virt_init[i];for ( nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) { switch (nn->tp->base) { case FCT: { Pfct f = (Pfct)nn->tp; if (bvirt) { Pname vn = btbl->look(nn->string,0); if (vn) { /* match up with base class */ if (vn->n_table==gtbl) goto vvv; Pfct vnf; switch (vn->tp->base) { case FCT: vnf = (Pfct)vn->tp; if (vnf->f_virtual) { if (vnf->check(f,0)) error("virtual%nT mismatch:%t and%t",nn,f,vnf); f->f_virtual = vnf->f_virtual; vp[f->f_virtual-1] = nn; } else goto vvv; break; case OVERLOAD: { Pgen g = (Pgen)vn->tp; if (f->f_virtual || Pfct(g->fct_list->f->tp)->f_virtual) error('s',"virtual%n overloaded inBC but not in derivedC",nn); break; } default: goto vvv; } } else goto vvv; } else { vvv:/*error('d',"vvv: %n f_virtual %d virt_count %d",nn,f->f_virtual,virt_count);*/ if (f->f_virtual) { f->f_virtual = ++virt_count; switch (f->f_virtual) { case 1: { Pname vpn = new name("_vptr"); vpn->tp = Pfctvec_type; (void) vpn->dcl(memtbl,PUBLIC); delete vpn; } default: vp[f->f_virtual-1] = nn; } } } break; } case OVERLOAD: { Plist gl; Pgen g = (Pgen)nn->tp;/*error('d',"overload%n bvirt==%d",nn,bvirt);*/ if (bvirt) { Pname vn = btbl->look(nn->string,0); Pgen g2; Pfct f2; if (vn) {/*error('d',"vn%n tp%k",vn,vn->tp->base);*/ if (vn->n_table == gtbl) goto ovvv; switch (vn->tp->base) { default: goto ovvv; case FCT: f2 = (Pfct)vn->tp; if (f2->f_virtual || Pfct(g->fct_list->f->tp)->f_virtual) error('s',"virtual%n overloaded in derivedC but not inBC",nn); break; case OVERLOAD: g2 = (Pgen)vn->tp; for (gl=g->fct_list; gl; gl=gl->l) { Pname fn = gl->f; Pfct f = (Pfct)fn->tp; Pname vn2 = g2->find(f); if (vn2 == 0) { if (f->f_virtual) error('s',"virtual overloaded%n not found inBC",fn); } else { Pfct vn2f = (Pfct)vn2->tp; if (vn2f->f_virtual) { f->f_virtual = vn2f->f_virtual; vp[f->f_virtual-1] = fn; } } } break; } } else goto ovvv; } else { ovvv: for (gl=g->fct_list; gl; gl=gl->l) { Pname fn = gl->f; Pfct f = (Pfct)fn->tp;/*fprintf(stderr,"fn %s f %d %d %d count %d\n",fn->string,f,f->base,f->f_virtual,virt_count+1);*/ if (f->f_virtual) { f->f_virtual = ++virt_count; switch (f->f_virtual) { case 1: { Pname vpn = new name("_vptr"); vpn->tp = Pfctvec_type; (void) vpn->dcl(memtbl,0); delete vpn; } default: vp[f->f_virtual-1] = fn; } } } } break; }} } virt_init = new Pname[virt_count]; for (i=0; i<virt_count; i++) virt_init[i] = vp[i]; } Pname pnx; for (p=pubdef; p; p=pnx) { char* qs = p->n_qualifier->string; char* ms = p->string; Pname cx; Ptable ctbl; Pname mx; pnx = p->n_list;//error('d',"dcl: pubdef %s::%s",qs,ms); if (strcmp(ms,qs)==0) ms = "_ctor"; for (cx = clbase; cx; cx = Pclass(cx->tp)->clbase) { if (strcmp(cx->string,qs) == 0) goto ok; } error("publicQr %s not aBC",qs); continue; ok: ctbl = Pclass(cx->tp)->memtbl; mx = ctbl->lookc(ms,0);//error('d',"ms %d %d %d",mx,Ebase,Epriv); if (Ebase) { // cc->nof ?? if (!Ebase->has_friend(cc->nof)) error("QdMN%n is in privateBC",p); } else if (Epriv) { if (!Epriv->has_friend(cc->nof)) error("QdMN%n is private",p); } if (mx == 0) { error("C%n does not have aM %s",cx,p->string); p->tp = any_type; } else { if (mx->tp->base==OVERLOAD) error('s',"public specification of overloaded%n",mx); p->base = PUBLIC; } p->n_qualifier = mx; (void) memtbl->insert(p,0);//error('d',"bbb"); if (Nold) error("twoDs of CM%n",p); } pubdef = 0; if (bit_offset) byte_offset += (bit_offset/BI_IN_BYTE+1); real_size = byte_offset;//error('d',"%s: rz=%d (bits %d)",string,byte_offset,bit_offset); if (byte_offset < SZ_STRUCT) byte_offset = SZ_STRUCT; int waste = byte_offset%max_align; if (waste) byte_offset += max_align-waste;//error('d',"%s: sz=%d al=%d",string,byte_offset,max_align); obj_size = byte_offset; obj_align = max_align; if ( has_dtor() && has_ctor()==0) error('w',"%s has destructor but no constructor",string); { // now look look at the members Pname m; Pclass oc = in_class; int ct = has_ctor()==0; int dt = has_dtor()==0; int un = csu==UNION; Pname statc = 0; Pname statd = 0; for (m=memtbl->get_mem(i=1); m; m=memtbl->get_mem(++i) ) { if (m->base == PUBLIC) continue; Ptype t = m->tp; switch (t->base) { default: if (ct && make_ctor==0) { if (t->is_ref()) error("reference%n inC %s without constructor",m,string); if (t->tconst() && vec_const==0) error("constant%n inC %s without constructor",m,string); } break; case FCT: case OVERLOAD: case CLASS: case ENUM: continue; case VEC: break; } Pname cn = t->is_cl_obj(); if (cn == 0) cn = cl_obj_vec; if (cn) { Pclass cl = (Pclass)cn->tp; if (cl->bit_ass == 0) bit_ass = 0; // no bit copy if (ct || dt || un) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -