|
|
1.1 root 1: /* ident "@(#)ctrans:src/tree_copy.c 1.3" */
2: /*
3: $Source: /usr3/lang/benson/work/stripped_cfront/RCS/tree_copy.c,v $ $RCSfile: tree_copy.c,v $
4: $Revision: 1.1 $ $Date: 89/11/20 08:51:04 $
5: $Author: benson $ $Locker: $
6: $State: Exp $
7: */
8:
9: /* utilities to copy pieces of cfront trees.
10: what we have here is a somewhat parameterizable
11: action procedure for the tree walker.
12:
13: We may make more versions of this for template expansion
14: and saving things in files, or we may just make it possible
15: for this to swing more ways.
16: */
17:
18: #include "cfront.h"
19: #include "tree_walk.h"
20: #include "tree_copy.h"
21: #include <memory.h>
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: default:
67: break;
68: case nc_eof:
69: n.node = Pnode(tci->malloc(sizeof (node)));
70: *n.node = *node;
71: goto Replace;
72:
73: case nc_virt:
74: n.vr = Pvirt(tci->malloc(sizeof(virt)));
75: *n.vr = *Pvirt(node);
76: goto Replace;
77:
78: case nc_nlist:
79: n.list = Plist(tci->malloc(sizeof(name_list)));
80: *n.list = *Plist(node);
81: goto Replace;
82:
83: case nc_gen:
84: n.g = Pgen(tci->malloc(sizeof(gen)));
85: *n.g = *Pgen(node);
86: goto Replace;
87:
88: case nc_vec:
89: n.vc = Pvec(tci->malloc(sizeof(vec)));
90: *n.vc = *Pvec(node);
91: goto Replace;
92:
93: case nc_ptr:
94: n.p = Pptr(tci->malloc(sizeof(ptr)));
95: *n.p = *Pptr(node);
96: goto Replace;
97:
98: case nc_fct:
99: n.f = Pfct(tci->malloc(sizeof(fct)));
100: *n.f = *Pfct(node);
101: if(n.f->f_signature) {
102: n.f->f_signature =
103: (char *)tci->malloc(strlen(Pfct(node)->f_signature)+1);
104: strcpy(n.f->f_signature, Pfct(node)->f_signature);
105: };
106: goto Replace;
107:
108: case nc_table:
109: n.t = Ptable(tci->malloc(sizeof(table)));
110: *n.t = *Ptable(node);
111: n.t->entries = (Pname *)tci->malloc(sizeof(Pname) * n.t->size);
112: memcpy((char *)n.t->entries, (char *)Ptable(node)->entries, n.t->size * sizeof(Pname));
113: n.t->hashtbl = (short *)tci->malloc(sizeof(short) * n.t->hashsize);
114: memcpy((char *)n.t->hashtbl, (char *)Ptable(node)->hashtbl, n.t->hashsize * sizeof (short));
115: goto Replace;
116:
117: case nc_basetype:
118: // Don't copy types that have already been dealt with
119: if (type_is_defined(node)) {
120: action = tna_stop ;
121: return ;
122: }
123: n.bt = Pbase(tci->malloc(sizeof(basetype)));
124: *n.bt = *Pbase(node);
125: if(n.bt->discriminator(0) == 2 && n.bt->b_linkage) {
126: n.bt->b_linkage = tci->malloc(strlen(n.bt->b_linkage) + 1);
127: strcpy(n.bt->b_linkage, Pbase(node)->b_linkage);
128: }
129: goto Replace;
130:
131: case nc_expr:
132: // cfront needs identity maintaied for these nodes
133: if ((node == dummy) || (node == zero)) {
134: action = tna_stop ;
135: return ;
136: }
137: n.x = Pexpr(tci->malloc(sizeof(expr)));
138: *n.x = *Pexpr(node);
139: if(n.x->discriminator(1) == 3 && n.x->string) {
140: n.x->string = tci->malloc(strlen(n.x->string) + 1);
141: strcpy(n.x->string, Pexpr(node)->string);
142: }
143: if(n.x->discriminator(2) == 3 && n.x->string2) {
144: n.x->string2 = tci->malloc(strlen(n.x->string2) + 1);
145: strcpy(n.x->string2, Pexpr(node)->string2);
146: }
147: goto Replace;
148:
149: case nc_stmt:
150: n.s = Pstmt(tci->malloc(sizeof(stmt)));
151: *n.s = *Pstmt(node);
152: goto Replace;
153:
154: case nc_enumdef:
155: if (type_is_defined(node)) {
156: action = tna_stop ;
157: return ;
158: }
159: n.e = Penum(tci->malloc(sizeof(enumdef)));
160: *n.e = *Penum(node);
161: if(n.e->string) {
162: n.e->string = tci->malloc(n.e->strlen+1);
163: strcpy(n.e->string, Penum(node)->string);
164: }
165: goto Replace;
166:
167: case nc_classdef:
168: // Don't copy types that have already been dealt with
169: if (type_is_defined(node)) {
170: action = tna_stop ;
171: return ;
172: }
173: n.c = Pclass(tci->malloc(sizeof(classdef)));
174: *n.c = *Pclass(node);
175: if(n.c->string) {
176: n.c->string = tci->malloc(strlen(n.c->string)+1);
177: strcpy(n.c->string, Pclass(node)->string);
178: }
179: goto Replace;
180:
181: case nc_baseclass:
182: n.bcl = Pbcl(tci->malloc(sizeof(struct basecl)));
183: *n.bcl = *Pbcl(node);
184: goto Replace;
185:
186: case nc_iline:
187: n.iline = Pin(tci->malloc(sizeof(iline)));
188: *n.iline = *Pin(node);
189: goto Replace;
190:
191: case nc_ia:
192: n.ia = (ia *)tci->malloc(sizeof(ia));
193: *n.ia = *(ia *)node;
194: goto Replace;
195:
196: case nc_name:
197: /* check for globalosity */
198: if(Pname(node)->string && (node == (node->base == TNAME ? ktbl : gtbl)->look(Pname(node)->string, 0))) {
199: action = tna_stop;
200: return;
201: }
202: n.n = Pname(tci->malloc(sizeof(name)));
203: *n.n = *Pname(node);
204: /* First, hack exprosity */
205: if(n.x->discriminator(1) == 3 && n.n->string) {
206: n.n->string = tci->malloc(strlen(n.n->string) + 1);
207: strcpy(n.n->string, Pexpr(node)->string);
208: }
209: if(n.x->discriminator(2) == 3 && n.n->string2) {
210: n.n->string2 = tci->malloc(strlen(n.n->string2) + 1);
211: strcpy(n.n->string2, Pexpr(node)->string2);
212: /* ok, name stuff */
213: }
214: if(n.n->n_anon) {
215: n.n->n_anon = tci->malloc(strlen(n.n->n_anon)+1);
216: strcpy(n.n->n_anon, Pname(node)->n_anon);
217: }
218: if(n.n->n_template_arg_string) {
219: n.n->n_template_arg_string =
220: tci->malloc(strlen(n.n->n_template_arg_string)+1);
221: strcpy(n.n->n_template_arg_string, Pname(node)->n_template_arg_string);
222: }
223: }
224: Replace:
225: node = n.node;
226: action = tna_continue;
227: return;
228: }
229:
230: static int call_error (int i, const char * s)
231: {
232: return error (i, s);
233: }
234:
235: void
236: copy_tree (Pnode& node, tree_copy_info& tci, Hash * cht)
237: {
238: tree_walk_control twc;
239:
240: twc.call_i_error = 1;
241: twc.i_error = call_error; /* ... in type of error confuses compiler */
242: twc.action_proc = copy_walker;
243: twc.nodes_seen_hash = cht;
244: twc.callback_info = (void *)&tci;
245:
246: walk_tree (twc, node);
247: }
248:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.