|
|
1.1 root 1: /*
2: $Source: /usr3/lang/benson/work/stripped_cfront/RCS/tree_copy.c,v $ $RCSfile: tree_copy.c,v $
3: $Revision: 1.1 $ $Date: 89/11/20 08:51:04 $
4: $Author: benson $ $Locker: $
5: $State: Exp $
6: */
7:
8: /* utilities to copy pieces of cfront trees.
9: what we have here is a somewhat parameterizable
10: action procedure for the tree walker.
11:
12: We may make more versions of this for template expansion
13: and saving things in files, or we may just make it possible
14: for this to swing more ways. */
15:
16: #include "cfront.h"
17: #include "tree_walk.H"
18: #include "tree_copy.H"
19: #include <memory.h>
20:
21: extern loc no_where;
22:
23: /* determine whether "n" is a an already defined type */
24: static unsigned int type_is_defined(Pnode n) {
25: return (Ptype(n)->defined & DEFINED) ;
26: }
27:
28: void
29: copy_walker (Pnode& node, node_class cl, void * info,
30: tree_node_action& action, int, Pnode, tree_walk_tree&,
31: int& register_in_hash)
32: {
33: union {
34: Pnode node;
35: Pvirt vr;
36: Plist list;
37: Pgen g;
38: Pvec vc;
39: Pfct f;
40: Ptable t;
41: Pbase bt;
42: Pexpr x;
43: Pstmt s;
44: Penum e;
45: Pclass c;
46: Pbcl bcl;
47: Pin iline;
48: ia * ia;
49: Pname n;
50: Pptr p;
51: } n;
52: Pnode original_node = node;
53:
54: tree_copy_info * tci = (tree_copy_info *)info;
55: action = tna_continue;
56:
57: /* first, give an application-specific hook a shot at the node. */
58:
59: tci->check_node(node, cl, action, register_in_hash);
60: if(action != tna_continue) return;
61:
62: if(node != original_node) { /* a replacement */
63: n.node = node;
64: } else /* ok, nothing funny, we just go ahead and copy */
65: switch (cl) {
66: case nc_eof:
67: n.node = Pnode(tci->malloc(sizeof (node)));
68: *n.node = *node;
69: goto Replace;
70:
71: case nc_virt:
72: n.vr = Pvirt(tci->malloc(sizeof(virt)));
73: *n.vr = *Pvirt(node);
74: goto Replace;
75:
76: case nc_nlist:
77: n.list = Plist(tci->malloc(sizeof(name_list)));
78: *n.list = *Plist(node);
79: goto Replace;
80:
81: case nc_gen:
82: n.g = Pgen(tci->malloc(sizeof(gen)));
83: *n.g = *Pgen(node);
84: goto Replace;
85:
86: case nc_vec:
87: n.vc = Pvec(tci->malloc(sizeof(vec)));
88: *n.vc = *Pvec(node);
89: goto Replace;
90:
91: case nc_ptr:
92: n.p = Pptr(tci->malloc(sizeof(ptr)));
93: *n.p = *Pptr(node);
94: goto Replace;
95:
96: case nc_fct:
97: n.f = Pfct(tci->malloc(sizeof(fct)));
98: *n.f = *Pfct(node);
99: if(n.f->f_signature) {
100: n.f->f_signature =
101: (char *)tci->malloc(strlen(Pfct(node)->f_signature)+1);
102: strcpy(n.f->f_signature, Pfct(node)->f_signature);
103: };
104: goto Replace;
105:
106: case nc_table:
107: n.t = Ptable(tci->malloc(sizeof(table)));
108: *n.t = *Ptable(node);
109: n.t->entries = (Pname *)tci->malloc(sizeof(Pname) * n.t->size);
110: memcpy((char *)n.t->entries, (char *)Ptable(node)->entries, n.t->size * sizeof(Pname));
111: n.t->hashtbl = (short *)tci->malloc(sizeof(short) * n.t->hashsize);
112: memcpy((char *)n.t->hashtbl, (char *)Ptable(node)->hashtbl, n.t->hashsize * sizeof (short));
113: goto Replace;
114:
115: case nc_basetype:
116: // Don't copy types that have already been dealt with
117: if (type_is_defined(node)) {
118: action = tna_stop ;
119: return ;
120: }
121: n.bt = Pbase(tci->malloc(sizeof(basetype)));
122: *n.bt = *Pbase(node);
123: if(n.bt->discriminator(0) == 2 && n.bt->b_linkage) {
124: n.bt->b_linkage = tci->malloc(strlen(n.bt->b_linkage) + 1);
125: strcpy(n.bt->b_linkage, Pbase(node)->b_linkage);
126: }
127: goto Replace;
128:
129: case nc_expr:
130: // cfront needs identity maintaied for these nodes
131: if ((node == dummy) || (node == zero)) {
132: action = tna_stop ;
133: return ;
134: }
135: n.x = Pexpr(tci->malloc(sizeof(expr)));
136: *n.x = *Pexpr(node);
137: if(n.x->discriminator(1) == 3 && n.x->string) {
138: n.x->string = tci->malloc(strlen(n.x->string) + 1);
139: strcpy(n.x->string, Pexpr(node)->string);
140: }
141: if(n.x->discriminator(2) == 3 && n.x->string2) {
142: n.x->string2 = tci->malloc(strlen(n.x->string2) + 1);
143: strcpy(n.x->string2, Pexpr(node)->string2);
144: }
145: goto Replace;
146:
147: case nc_stmt:
148: n.s = Pstmt(tci->malloc(sizeof(stmt)));
149: *n.s = *Pstmt(node);
150: goto Replace;
151:
152: case nc_enumdef:
153: if (type_is_defined(node)) {
154: action = tna_stop ;
155: return ;
156: }
157: n.e = Penum(tci->malloc(sizeof(enumdef)));
158: *n.e = *Penum(node);
159: if(n.e->string) {
160: n.e->string = tci->malloc(n.e->strlen+1);
161: strcpy(n.e->string, Penum(node)->string);
162: }
163: goto Replace;
164:
165: case nc_classdef:
166: // Don't copy types that have already been dealt with
167: if (type_is_defined(node)) {
168: action = tna_stop ;
169: return ;
170: }
171: n.c = Pclass(tci->malloc(sizeof(classdef)));
172: *n.c = *Pclass(node);
173: if(n.c->string) {
174: n.c->string = tci->malloc(strlen(n.c->string)+1);
175: strcpy(n.c->string, Pclass(node)->string);
176: }
177: goto Replace;
178:
179: case nc_baseclass:
180: n.bcl = Pbcl(tci->malloc(sizeof(struct basecl)));
181: *n.bcl = *Pbcl(node);
182: goto Replace;
183:
184: case nc_iline:
185: n.iline = Pin(tci->malloc(sizeof(iline)));
186: *n.iline = *Pin(node);
187: goto Replace;
188:
189: case nc_ia:
190: n.ia = (ia *)tci->malloc(sizeof(ia));
191: *n.ia = *(ia *)node;
192: goto Replace;
193:
194: case nc_name:
195: /* check for globalosity */
196: if(Pname(node)->string && (node == (node->base == TNAME ? ktbl : gtbl)->look(Pname(node)->string, 0))) {
197: action = tna_stop;
198: return;
199: }
200: n.n = Pname(tci->malloc(sizeof(name)));
201: *n.n = *Pname(node);
202: /* First, hack exprosity */
203: if(n.x->discriminator(1) == 3 && n.n->string) {
204: n.n->string = tci->malloc(strlen(n.n->string) + 1);
205: strcpy(n.n->string, Pexpr(node)->string);
206: }
207: if(n.x->discriminator(2) == 3 && n.n->string2) {
208: n.n->string2 = tci->malloc(strlen(n.n->string2) + 1);
209: strcpy(n.n->string2, Pexpr(node)->string2);
210: /* ok, name stuff */
211: }
212: if(n.n->n_anon) {
213: n.n->n_anon = tci->malloc(strlen(n.n->n_anon)+1);
214: strcpy(n.n->n_anon, Pname(node)->n_anon);
215: }
216: if(n.n->output_string) {
217: n.n->output_string = tci->malloc(strlen(n.n->output_string)+1);
218: strcpy(n.n->output_string, Pname(node)->output_string);
219: }
220: if(n.n->n_template_arg_string) {
221: n.n->n_template_arg_string =
222: tci->malloc(strlen(n.n->n_template_arg_string)+1);
223: strcpy(n.n->n_template_arg_string, Pname(node)->n_template_arg_string);
224: }
225: }
226: Replace:
227: node = n.node;
228: action = tna_continue;
229: return;
230: }
231:
232: static int call_error (int i, const char * s)
233: {
234: return error (i, s);
235: }
236:
237: void
238: copy_tree (Pnode& node, tree_copy_info& tci, Hash * cht)
239: {
240: tree_walk_control twc;
241:
242: twc.call_i_error = 1;
243: twc.i_error = call_error; /* ... in type of error confuses compiler */
244: twc.action_proc = copy_walker;
245: twc.nodes_seen_hash = cht;
246: twc.callback_info = (void *)&tci;
247:
248: walk_tree (twc, node);
249: }
250:
251:
252: static char rcsinfo[] = "$Header: /usr3/lang/benson/work/stripped_cfront/RCS/tree_copy.c,v 1.1 89/11/20 08:51:04 benson Exp $";
253:
254:
255: /*
256: $Log: tree_copy.c,v $
257: * Revision 1.1 89/11/20 08:51:04 benson
258: * Initial revision
259: *
260: * Revision 1.5 89/10/10 08:43:12 benson
261: * new error system prototype.
262: *
263: *
264: * Revision 1.4 89/09/02 22:06:38 benson
265: * add ability to keep something out of the hash table.
266: *
267: * Revision 1.3 89/08/24 10:01:06 benson
268: * additional argument as a walker action procedure.
269: *
270: * Revision 1.2 89/08/11 15:07:19 sam
271: * - stopped copying at "defined" types
272: * - stop copying ofthe pre-defined exprs zero, and dummy
273: * - if the hook returns a new node, use it rather than mallocing a new one.
274: *
275: * Revision 1.1 89/07/21 16:46:03 benson
276: * Initial revision
277: *
278:
279: end_log
280: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.