Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 66... Line 96...
66
 
96
 
67
    This routine checks whether the graphs gr and gs are equal.  Allowance
97
    This routine checks whether the graphs gr and gs are equal.  Allowance
68
    is made for the equivalence of virtual bases.
98
    is made for the equivalence of virtual bases.
69
*/
99
*/
70
 
100
 
71
int eq_graph
101
int
72
    PROTO_N ( ( gr, gs ) )
-
 
73
    PROTO_T ( GRAPH gr X GRAPH gs )
102
eq_graph(GRAPH gr, GRAPH gs)
74
{
103
{
75
    GRAPH hr = gr ;
104
	GRAPH hr = gr;
76
    GRAPH hs = gs ;
105
	GRAPH hs = gs;
77
    while ( !IS_NULL_graph ( gr ) ) {
106
	while (!IS_NULL_graph(gr)) {
78
	/* Calculate canonical form for virtual bases */
107
		/* Calculate canonical form for virtual bases */
79
	hr = gr ;
108
		hr = gr;
80
	gr = DEREF_graph ( graph_equal ( gr ) ) ;
109
		gr = DEREF_graph(graph_equal(gr));
81
    }
110
	}
82
    while ( !IS_NULL_graph ( gs ) ) {
111
	while (!IS_NULL_graph(gs)) {
83
	/* Calculate canonical form for virtual bases */
112
		/* Calculate canonical form for virtual bases */
84
	hs = gs ;
113
		hs = gs;
85
	gs = DEREF_graph ( graph_equal ( gs ) ) ;
114
		gs = DEREF_graph(graph_equal(gs));
86
    }
115
	}
87
    return ( EQ_graph ( hr, hs ) ) ;
116
	return (EQ_graph(hr, hs));
88
}
117
}
89
 
118
 
90
 
119
 
91
/*
120
/*
92
    SEARCH A GRAPH FOR A BASE
121
    SEARCH A GRAPH FOR A BASE
Line 95... Line 124...
95
    the first node encountered which matches ct, or the null graph if no
124
    the first node encountered which matches ct, or the null graph if no
96
    such match is found.  Note that the search algorithm is based on a
125
    such match is found.  Note that the search algorithm is based on a
97
    depth-first left-to-right traversal of the graph.
126
    depth-first left-to-right traversal of the graph.
98
*/
127
*/
99
 
128
 
100
static GRAPH search_graph
129
static GRAPH
101
    PROTO_N ( ( gr, ct ) )
-
 
102
    PROTO_T ( GRAPH gr X CLASS_TYPE ct )
130
search_graph(GRAPH gr, CLASS_TYPE ct)
103
{
131
{
104
    DECL_SPEC acc ;
132
	DECL_SPEC acc;
105
 
133
 
106
    /* Check the head of gr */
134
	/* Check the head of gr */
107
    CLASS_TYPE cr = DEREF_ctype ( graph_head ( gr ) ) ;
135
	CLASS_TYPE cr = DEREF_ctype(graph_head(gr));
108
    if ( eq_ctype ( cr, ct ) ) return ( gr ) ;
136
	if (eq_ctype(cr, ct)) {
-
 
137
		return (gr);
-
 
138
	}
109
 
139
 
110
    /* Only search first instance */
140
	/* Only search first instance */
111
    acc = DEREF_dspec ( graph_access ( gr ) ) ;
141
	acc = DEREF_dspec(graph_access(gr));
112
    if ( acc & dspec_defn ) {
142
	if (acc & dspec_defn) {
113
	/* Search the branches of gr */
143
		/* Search the branches of gr */
114
	LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
144
		LIST(GRAPH)br = DEREF_list(graph_tails(gr));
115
	while ( !IS_NULL_list ( br ) ) {
145
		while (!IS_NULL_list(br)) {
116
	    GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
146
			GRAPH gs = DEREF_graph(HEAD_list(br));
117
	    gs = search_graph ( gs, ct ) ;
147
			gs = search_graph(gs, ct);
118
	    if ( !IS_NULL_graph ( gs ) ) return ( gs ) ;
148
			if (!IS_NULL_graph(gs)) {
-
 
149
				return (gs);
-
 
150
			}
119
	    br = TAIL_list ( br ) ;
151
			br = TAIL_list(br);
-
 
152
		}
120
	}
153
	}
121
    }
-
 
122
    return ( NULL_graph ) ;
154
	return (NULL_graph);
123
}
155
}
124
 
156
 
125
 
157
 
126
/*
158
/*
127
    IS ONE GRAPH A SUBGRAPH OF ANOTHER?
159
    IS ONE GRAPH A SUBGRAPH OF ANOTHER?
128
 
160
 
129
    This routine checks whether the graph gs is a subgraph of gr (allowing
161
    This routine checks whether the graph gs is a subgraph of gr (allowing
130
    for the identification of virtual bases).
162
    for the identification of virtual bases).
131
*/
163
*/
132
 
164
 
133
int is_subgraph
165
int
134
    PROTO_N ( ( gr, gs ) )
-
 
135
    PROTO_T ( GRAPH gr X GRAPH gs )
166
is_subgraph(GRAPH gr, GRAPH gs)
136
{
167
{
137
    unsigned nt, ns ;
168
	unsigned nt, ns;
138
    CLASS_TYPE ct, cs ;
169
	CLASS_TYPE ct, cs;
139
    if ( EQ_graph ( gr, gs ) ) return ( 1 ) ;
170
	if (EQ_graph(gr, gs)) {
-
 
171
		return (1);
-
 
172
	}
140
    ct = DEREF_ctype ( graph_head ( gr ) ) ;
173
	ct = DEREF_ctype(graph_head(gr));
141
    cs = DEREF_ctype ( graph_head ( gs ) ) ;
174
	cs = DEREF_ctype(graph_head(gs));
142
    nt = DEREF_unsigned ( ctype_no_bases ( ct ) ) ;
175
	nt = DEREF_unsigned(ctype_no_bases(ct));
143
    ns = DEREF_unsigned ( ctype_no_bases ( cs ) ) ;
176
	ns = DEREF_unsigned(ctype_no_bases(cs));
144
    if ( nt == ns ) {
177
	if (nt == ns) {
145
	/* Graphs are the same size */
178
		/* Graphs are the same size */
146
	return ( eq_graph ( gr, gs ) ) ;
179
		return (eq_graph(gr, gs));
147
    }
180
	}
148
    if ( nt > ns ) {
181
	if (nt > ns) {
149
	/* gr is bigger than gs */
182
		/* gr is bigger than gs */
150
	LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
183
		LIST(GRAPH)br = DEREF_list(graph_tails(gr));
151
	while ( !IS_NULL_list ( br ) ) {
184
		while (!IS_NULL_list(br)) {
152
	    GRAPH gt = DEREF_graph ( HEAD_list ( br ) ) ;
185
			GRAPH gt = DEREF_graph(HEAD_list(br));
153
	    if ( is_subgraph ( gt, gs ) ) return ( 1 ) ;
186
			if (is_subgraph(gt, gs)) {
-
 
187
				return (1);
-
 
188
			}
154
	    br = TAIL_list ( br ) ;
189
			br = TAIL_list(br);
155
	}
190
		}
156
    }
191
	}
157
    return ( 0 ) ;
192
	return (0);
158
}
193
}
159
 
194
 
160
 
195
 
161
/*
196
/*
162
    COPY A GRAPH
197
    COPY A GRAPH
Line 165... Line 200...
165
    of the current class, with access specifiers adjusted by acc and virtual
200
    of the current class, with access specifiers adjusted by acc and virtual
166
    specifier virt.  indir is true if the graph is a subgraph of a virtual
201
    specifier virt.  indir is true if the graph is a subgraph of a virtual
167
    base and templ is true if the graph represents a template parameter.
202
    base and templ is true if the graph represents a template parameter.
168
*/
203
*/
169
 
204
 
170
static GRAPH copy_graph
205
static GRAPH
171
    PROTO_N ( ( gr, off, acc, virt, indir, templ ) )
206
copy_graph(GRAPH gr, OFFSET off, DECL_SPEC acc, int virt, int indir, int templ)
172
    PROTO_T ( GRAPH gr X OFFSET off X DECL_SPEC acc X
-
 
173
	      int virt X int indir X int templ )
-
 
174
{
207
{
175
    OFFSET offa ;
208
	OFFSET offa;
176
    DECL_SPEC as ;
209
	DECL_SPEC as;
177
    GRAPH gc, gp, gs ;
210
	GRAPH gc, gp, gs;
178
    LIST ( GRAPH ) bs ;
211
	LIST(GRAPH)bs;
179
 
-
 
180
    /* Decompose head of graph */
-
 
181
    CLASS_TYPE ct = DEREF_ctype ( graph_head ( gr ) ) ;
-
 
182
    LIST ( GRAPH ) bt = DEREF_list ( graph_tails ( gr ) ) ;
-
 
183
 
-
 
184
    /* Adjust access specifiers */
-
 
185
    DECL_SPEC at = DEREF_dspec ( graph_access ( gr ) ) ;
-
 
186
    as = join_access ( at, acc ) ;
-
 
187
    as |= shadow_access ( at ) ;
-
 
188
    if ( at & dspec_virtual ) virt = 1 ;
-
 
189
    if ( virt ) {
-
 
190
	/* Mark virtual bases */
-
 
191
	as |= dspec_virtual ;
-
 
192
	indir = 1 ;
-
 
193
    }
-
 
194
    if ( indir ) {
-
 
195
	/* Mark indirect bases */
-
 
196
	as |= dspec_mutable ;
-
 
197
    }
-
 
198
    if ( templ ) {
-
 
199
	/* Mark template parameter bases */
-
 
200
	as |= dspec_template ;
-
 
201
    }
-
 
202
    as |= dspec_inherit ;
-
 
203
    as &= ~dspec_done ;
-
 
204
 
-
 
205
    /* Search existing graph for ct */
-
 
206
    gc = DEREF_graph ( ctype_base ( crt_class ) ) ;
-
 
207
    gp = search_graph ( gc, ct ) ;
-
 
208
    if ( IS_NULL_graph ( gp ) ) as |= dspec_defn ;
-
 
209
 
-
 
210
    /* Copy components */
-
 
211
    bs = NULL_list ( GRAPH ) ;
-
 
212
    while ( !IS_NULL_list ( bt ) ) {
-
 
213
	GRAPH gt = DEREF_graph ( HEAD_list ( bt ) ) ;
-
 
214
	gt = copy_graph ( gt, off, as, 0, indir, templ ) ;
-
 
215
	CONS_graph ( gt, bs, bs ) ;
-
 
216
	bt = TAIL_list ( bt ) ;
-
 
217
    }
-
 
218
    bs = REVERSE_list ( bs ) ;
-
 
219
 
-
 
220
    /* Create new graph */
-
 
221
    MAKE_graph_basic ( ct, as, gs ) ;
-
 
222
    COPY_list ( graph_tails ( gs ), bs ) ;
-
 
223
    COPY_graph ( graph_top ( gs ), gc ) ;
-
 
224
 
-
 
225
    /* Set base offset */
-
 
226
    offa = DEREF_off ( graph_off ( gr ) ) ;
-
 
227
    if ( !IS_NULL_off ( offa ) ) {
-
 
228
	MAKE_off_deriv ( gs, off, offa, off ) ;
-
 
229
    }
-
 
230
    COPY_off ( graph_off ( gs ), off ) ;
-
 
231
 
212
 
-
 
213
	/* Decompose head of graph */
-
 
214
	CLASS_TYPE ct = DEREF_ctype(graph_head(gr));
-
 
215
	LIST(GRAPH)bt = DEREF_list(graph_tails(gr));
-
 
216
 
-
 
217
	/* Adjust access specifiers */
-
 
218
	DECL_SPEC at = DEREF_dspec(graph_access(gr));
-
 
219
	as = join_access(at, acc);
-
 
220
	as |= shadow_access(at);
-
 
221
	if (at & dspec_virtual) {
-
 
222
		virt = 1;
-
 
223
	}
-
 
224
	if (virt) {
-
 
225
		/* Mark virtual bases */
-
 
226
		as |= dspec_virtual;
-
 
227
		indir = 1;
-
 
228
	}
-
 
229
	if (indir) {
-
 
230
		/* Mark indirect bases */
-
 
231
		as |= dspec_mutable;
-
 
232
	}
-
 
233
	if (templ) {
-
 
234
		/* Mark template parameter bases */
-
 
235
		as |= dspec_template;
-
 
236
	}
-
 
237
	as |= dspec_inherit;
-
 
238
	as &= ~dspec_done;
-
 
239
 
-
 
240
	/* Search existing graph for ct */
-
 
241
	gc = DEREF_graph(ctype_base(crt_class));
-
 
242
	gp = search_graph(gc, ct);
-
 
243
	if (IS_NULL_graph(gp)) {
-
 
244
		as |= dspec_defn;
-
 
245
	}
-
 
246
 
-
 
247
	/* Copy components */
-
 
248
	bs = NULL_list(GRAPH);
-
 
249
	while (!IS_NULL_list(bt)) {
-
 
250
		GRAPH gt = DEREF_graph(HEAD_list(bt));
-
 
251
		gt = copy_graph(gt, off, as, 0, indir, templ);
-
 
252
		CONS_graph(gt, bs, bs);
-
 
253
		bt = TAIL_list(bt);
-
 
254
	}
-
 
255
	bs = REVERSE_list(bs);
-
 
256
 
-
 
257
	/* Create new graph */
-
 
258
	MAKE_graph_basic(ct, as, gs);
-
 
259
	COPY_list(graph_tails(gs), bs);
-
 
260
	COPY_graph(graph_top(gs), gc);
-
 
261
 
-
 
262
	/* Set base offset */
-
 
263
	offa = DEREF_off(graph_off(gr));
-
 
264
	if (!IS_NULL_off(offa)) {
-
 
265
		MAKE_off_deriv(gs, off, offa, off);
-
 
266
	}
-
 
267
	COPY_off(graph_off(gs), off);
-
 
268
 
232
    /* Set up-field of bases */
269
	/* Set up-field of bases */
233
    while ( !IS_NULL_list ( bs ) ) {
270
	while (!IS_NULL_list(bs)) {
234
	GRAPH gt = DEREF_graph ( HEAD_list ( bs ) ) ;
271
		GRAPH gt = DEREF_graph(HEAD_list(bs));
235
	COPY_graph ( graph_up ( gt ), gs ) ;
272
		COPY_graph(graph_up(gt), gs);
236
	bs = TAIL_list ( bs ) ;
273
		bs = TAIL_list(bs);
237
    }
274
	}
238
    return ( gs ) ;
275
	return (gs);
239
}
276
}
240
 
277
 
241
 
278
 
242
/*
279
/*
243
    FIND A COPY OF A SUBGRAPH
280
    FIND A COPY OF A SUBGRAPH
Line 252... Line 289...
252
			     |        |
289
			     |        |
253
			incl |        | incl
290
			incl |        | incl
254
			     |        |
291
			     |        |
255
			    hr ------ hs
292
			    hr ------ hs
256
				copy
293
				copy
257
*/
294
*/
258
 
295
 
259
GRAPH find_subgraph
296
GRAPH
260
    PROTO_N ( ( gr, gs, hs ) )
-
 
261
    PROTO_T ( GRAPH gr X GRAPH gs X GRAPH hs )
297
find_subgraph(GRAPH gr, GRAPH gs, GRAPH hs)
262
{
298
{
263
    if ( EQ_graph ( gs, hs ) ) return ( gr ) ;
299
	if (EQ_graph(gs, hs)) {
-
 
300
		return (gr);
-
 
301
	}
264
    if ( !IS_NULL_graph ( gr ) ) {
302
	if (!IS_NULL_graph(gr)) {
265
	LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
303
		LIST(GRAPH)br = DEREF_list(graph_tails(gr));
266
	LIST ( GRAPH ) bs = DEREF_list ( graph_tails ( gs ) ) ;
304
		LIST(GRAPH)bs = DEREF_list(graph_tails(gs));
267
	while ( !IS_NULL_list ( br ) ) {
305
		while (!IS_NULL_list(br)) {
268
	    GRAPH ar = DEREF_graph ( HEAD_list ( br ) ) ;
306
			GRAPH ar = DEREF_graph(HEAD_list(br));
269
	    GRAPH as = DEREF_graph ( HEAD_list ( bs ) ) ;
307
			GRAPH as = DEREF_graph(HEAD_list(bs));
270
	    GRAPH hr = find_subgraph ( ar, as, hs ) ;
308
			GRAPH hr = find_subgraph(ar, as, hs);
271
	    if ( !IS_NULL_graph ( hr ) ) return ( hr ) ;
309
			if (!IS_NULL_graph(hr)) {
-
 
310
				return (hr);
-
 
311
			}
272
	    br = TAIL_list ( br ) ;
312
			br = TAIL_list(br);
273
	    bs = TAIL_list ( bs ) ;
313
			bs = TAIL_list(bs);
-
 
314
		}
274
	}
315
	}
275
    }
-
 
276
    return ( NULL_graph ) ;
316
	return (NULL_graph);
277
}
317
}
278
 
318
 
279
 
319
 
280
/*
320
/*
281
    IDENTIFY TWO GRAPHS
321
    IDENTIFY TWO GRAPHS
282
 
322
 
283
    This routine identifies the graph gs with the graph gr by linking
323
    This routine identifies the graph gs with the graph gr by linking
284
    them by means of their equal fields.
324
    them by means of their equal fields.
285
*/
325
*/
286
 
326
 
287
static void identify_graph
327
static void
288
    PROTO_N ( ( gr, gs ) )
-
 
289
    PROTO_T ( GRAPH gr X GRAPH gs )
328
identify_graph(GRAPH gr, GRAPH gs)
290
{
329
{
291
    DECL_SPEC acc ;
330
	DECL_SPEC acc;
292
    LIST ( GRAPH ) br, bs ;
331
	LIST(GRAPH)br, bs;
293
    GRAPH gu = DEREF_graph ( graph_equal ( gs ) ) ;
332
	GRAPH gu = DEREF_graph(graph_equal(gs));
294
    while ( !IS_NULL_graph ( gu ) ) {
333
	while (!IS_NULL_graph(gu)) {
295
	gs = gu ;
334
		gs = gu;
296
	gu = DEREF_graph ( graph_equal ( gs ) ) ;
335
		gu = DEREF_graph(graph_equal(gs));
297
    }
336
	}
298
    br = DEREF_list ( graph_tails ( gr ) ) ;
337
	br = DEREF_list(graph_tails(gr));
299
    bs = DEREF_list ( graph_tails ( gs ) ) ;
338
	bs = DEREF_list(graph_tails(gs));
300
    while ( !IS_NULL_list ( br ) ) {
339
	while (!IS_NULL_list(br)) {
301
	GRAPH hr = DEREF_graph ( HEAD_list ( br ) ) ;
340
		GRAPH hr = DEREF_graph(HEAD_list(br));
302
	GRAPH hs = DEREF_graph ( HEAD_list ( bs ) ) ;
341
		GRAPH hs = DEREF_graph(HEAD_list(bs));
303
	identify_graph ( hr, hs ) ;
342
		identify_graph(hr, hs);
304
	br = TAIL_list ( br ) ;
343
		br = TAIL_list(br);
305
	bs = TAIL_list ( bs ) ;
344
		bs = TAIL_list(bs);
306
    }
345
	}
307
    COPY_graph ( graph_equal ( gs ), gr ) ;
346
	COPY_graph(graph_equal(gs), gr);
308
    acc = DEREF_dspec ( graph_access ( gr ) ) ;
347
	acc = DEREF_dspec(graph_access(gr));
309
    acc |= dspec_done ;
348
	acc |= dspec_done;
310
    COPY_dspec ( graph_access ( gr ), acc ) ;
349
	COPY_dspec(graph_access(gr), acc);
311
    return ;
350
	return;
312
}
351
}
313
 
352
 
314
 
353
 
315
/*
354
/*
316
    BASE CLASS INFORMATION
355
    BASE CLASS INFORMATION
317
 
356
 
318
    The variable base_info holds information about the graph being analysed
357
    The variable base_info holds information about the graph being analysed
319
    by fold_graph, for example, does it have a virtual or an ambiguous base
358
    by fold_graph, for example, does it have a virtual or an ambiguous base
320
    class?
359
    class?
321
*/
360
*/
322
 
361
 
323
static CLASS_INFO base_info = cinfo_none ;
362
static CLASS_INFO base_info = cinfo_none;
324
static LIST ( GRAPH ) virtual_bases = NULL_list ( GRAPH ) ;
363
static LIST(GRAPH) virtual_bases = NULL_list(GRAPH);
325
 
364
 
326
 
365
 
327
/*
366
/*
328
    FOLD A GRAPH
367
    FOLD A GRAPH
329
 
368
 
330
    This routine folds the graph gr by identifying all of its equal virtual
369
    This routine folds the graph gr by identifying all of its equal virtual
331
    bases.  It also defines values representing the offset of each base
370
    bases.  It also defines values representing the offset of each base
332
    from the start of its class.  It returns a list of all the base classes
371
    from the start of its class.  It returns a list of all the base classes
333
    in gr (allowing for virtual bases).  All bases added to the list are
372
    in gr (allowing for virtual bases).  All bases added to the list are
334
    marked as explicit bases.
373
    marked as explicit bases.
335
*/
374
*/
336
 
375
 
337
static LIST ( GRAPH ) fold_graph
376
static LIST(GRAPH)
338
    PROTO_N ( ( gr, br ) )
-
 
339
    PROTO_T ( GRAPH gr X LIST ( GRAPH ) br )
377
fold_graph(GRAPH gr, LIST(GRAPH)br)
340
{
378
{
341
    CLASS_TYPE ct = DEREF_ctype ( graph_head ( gr ) ) ;
379
	CLASS_TYPE ct = DEREF_ctype(graph_head(gr));
342
    DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
380
	DECL_SPEC acc = DEREF_dspec(graph_access(gr));
343
 
381
 
344
    /* Scan for previous uses of this base */
382
	/* Scan for previous uses of this base */
345
    LIST ( GRAPH ) bs = br ;
383
	LIST(GRAPH)bs = br;
346
    while ( !IS_NULL_list ( bs ) ) {
384
	while (!IS_NULL_list(bs)) {
347
	GRAPH gs = DEREF_graph ( HEAD_list ( bs ) ) ;
385
		GRAPH gs = DEREF_graph(HEAD_list(bs));
348
	CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
386
		CLASS_TYPE cs = DEREF_ctype(graph_head(gs));
349
	if ( eq_ctype ( cs, ct ) ) {
387
		if (eq_ctype(cs, ct)) {
350
	    /* Duplicate base found */
388
			/* Duplicate base found */
351
	    DECL_SPEC acs = DEREF_dspec ( graph_access ( gs ) ) ;
389
			DECL_SPEC acs = DEREF_dspec(graph_access(gs));
352
	    if ( ( acs & dspec_virtual ) && ( acc & dspec_virtual ) ) {
390
			if ((acs & dspec_virtual) && (acc & dspec_virtual)) {
353
		/* Both bases are virtual */
391
				/* Both bases are virtual */
354
		if ( !eq_graph ( gr, gs ) ) {
392
				if (!eq_graph(gr, gs)) {
355
		    /* Identify graphs if not already done */
393
					/* Identify graphs if not already
-
 
394
					 * done */
356
		    identify_graph ( gr, gs ) ;
395
					identify_graph(gr, gs);
357
		}
396
				}
358
		/* Propagate ambiguous bases */
397
				/* Propagate ambiguous bases */
359
		if ( acs & dspec_alias ) {
398
				if (acs & dspec_alias) {
360
		    acc |= dspec_alias ;
399
					acc |= dspec_alias;
361
		} else if ( acc & dspec_alias ) {
400
				} else if (acc & dspec_alias) {
362
		    while ( !IS_NULL_graph ( gs ) ) {
401
					while (!IS_NULL_graph(gs)) {
363
			acs = DEREF_dspec ( graph_access ( gs ) ) ;
402
						acs = DEREF_dspec(graph_access(gs));
364
			acs |= dspec_alias ;
403
						acs |= dspec_alias;
365
			COPY_dspec ( graph_access ( gs ), acs ) ;
404
						COPY_dspec(graph_access(gs),
-
 
405
							   acs);
366
			gs = DEREF_graph ( graph_equal ( gs ) ) ;
406
						gs = DEREF_graph(graph_equal(gs));
367
		    }
407
					}
-
 
408
				}
-
 
409
				acc |= dspec_done;
-
 
410
				COPY_dspec(graph_access(gr), acc);
-
 
411
				return (br);
-
 
412
			}
-
 
413
			/* Ambiguous base */
-
 
414
			base_info |= cinfo_ambiguous;
-
 
415
			acc |= dspec_alias;
-
 
416
			acs |= dspec_alias;
-
 
417
			COPY_dspec(graph_access(gs), acs);
368
		}
418
		}
369
		acc |= dspec_done ;
-
 
370
		COPY_dspec ( graph_access ( gr ), acc ) ;
-
 
371
		return ( br ) ;
-
 
372
	    }
-
 
373
	    /* Ambiguous base */
-
 
374
	    base_info |= cinfo_ambiguous ;
-
 
375
	    acc |= dspec_alias ;
-
 
376
	    acs |= dspec_alias ;
419
		bs = TAIL_list(bs);
377
	    COPY_dspec ( graph_access ( gs ), acs ) ;
-
 
378
	}
420
	}
379
	bs = TAIL_list ( bs ) ;
-
 
380
    }
-
 
381
 
421
 
382
    /* Add base class to list */
422
	/* Add base class to list */
383
    acc |= ( dspec_main | dspec_done ) ;
423
	acc |= (dspec_main | dspec_done);
384
    COPY_dspec ( graph_access ( gr ), acc ) ;
424
	COPY_dspec(graph_access(gr), acc);
385
    CONS_graph ( gr, br, br ) ;
425
	CONS_graph(gr, br, br);
386
 
426
 
387
    /* Fold subgraphs */
427
	/* Fold subgraphs */
388
    bs = DEREF_list ( graph_tails ( gr ) ) ;
428
	bs = DEREF_list(graph_tails(gr));
389
    while ( !IS_NULL_list ( bs ) ) {
429
	while (!IS_NULL_list(bs)) {
390
	GRAPH gs = DEREF_graph ( HEAD_list ( bs ) ) ;
430
		GRAPH gs = DEREF_graph(HEAD_list(bs));
391
	br = fold_graph ( gs, br ) ;
431
		br = fold_graph(gs, br);
392
	bs = TAIL_list ( bs ) ;
432
		bs = TAIL_list(bs);
393
    }
433
	}
394
 
434
 
395
    /* Build list of virtual classes */
435
	/* Build list of virtual classes */
396
    if ( acc & dspec_virtual ) {
436
	if (acc & dspec_virtual) {
397
	base_info |= cinfo_virtual_base ;
437
		base_info |= cinfo_virtual_base;
398
	CONS_graph ( gr, virtual_bases, virtual_bases ) ;
438
		CONS_graph(gr, virtual_bases, virtual_bases);
399
    }
439
	}
400
    return ( br ) ;
440
	return (br);
401
}
441
}
402
 
442
 
403
 
443
 
404
/*
444
/*
405
    FIND A SINGLE INHERITANCE BASE CLASS
445
    FIND A SINGLE INHERITANCE BASE CLASS
406
 
446
 
Line 410... Line 450...
410
    classes are laid out so that their single inheritance base classes
450
    classes are laid out so that their single inheritance base classes
411
    are at zero offset from the start of the class, thereby minimising
451
    are at zero offset from the start of the class, thereby minimising
412
    the cost of a base class conversion.
452
    the cost of a base class conversion.
413
*/
453
*/
414
 
454
 
415
static GRAPH find_first_base
455
static GRAPH
416
    PROTO_N ( ( gr ) )
-
 
417
    PROTO_T ( GRAPH gr )
456
find_first_base(GRAPH gr)
418
{
457
{
419
    LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
458
	LIST(GRAPH)br = DEREF_list(graph_tails(gr));
420
    if ( !IS_NULL_list ( br ) ) {
459
	if (!IS_NULL_list(br)) {
421
	GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
460
		GRAPH gs = DEREF_graph(HEAD_list(br));
422
	DECL_SPEC acc = DEREF_dspec ( graph_access ( gs ) ) ;
461
		DECL_SPEC acc = DEREF_dspec(graph_access(gs));
423
	if ( !( acc & dspec_virtual ) ) {
462
		if (!(acc & dspec_virtual)) {
424
	    return ( gs ) ;
463
			return (gs);
-
 
464
		}
425
	}
465
	}
426
    }
-
 
427
    return ( NULL_graph ) ;
466
	return (NULL_graph);
428
}
467
}
429
 
468
 
430
 
469
 
431
/*
470
/*
432
    END BASE CLASS DEFINITIONS
471
    END BASE CLASS DEFINITIONS
Line 435... Line 474...
435
    processed.  ok is false for an empty base class list.  The routine
474
    processed.  ok is false for an empty base class list.  The routine
436
    folds the base class graph of the current class and records the total
475
    folds the base class graph of the current class and records the total
437
    number of bases.  It also initialises the virtual function table.
476
    number of bases.  It also initialises the virtual function table.
438
*/
477
*/
439
 
478
 
440
void end_base_class
479
void
441
    PROTO_N ( ( ct, ok ) )
-
 
442
    PROTO_T ( CLASS_TYPE ct X int ok )
480
end_base_class(CLASS_TYPE ct, int ok)
443
{
481
{
444
    if ( !IS_NULL_ctype ( ct ) ) {
482
	if (!IS_NULL_ctype(ct)) {
445
	/* Scan for virtual bases */
483
		/* Scan for virtual bases */
446
	CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
484
		CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
447
	GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
485
		GRAPH gr = DEREF_graph(ctype_base(ct));
448
	LIST ( GRAPH ) bs = DEREF_list ( graph_tails ( gr ) ) ;
486
		LIST(GRAPH)bs = DEREF_list(graph_tails(gr));
449
	unsigned nd = LENGTH_list ( bs ) ;
487
		unsigned nd = LENGTH_list(bs);
450
	LIST ( GRAPH ) br = fold_graph ( gr, NULL_list ( GRAPH ) ) ;
488
		LIST(GRAPH)br = fold_graph(gr, NULL_list(GRAPH));
451
	unsigned nb = LENGTH_list ( br ) ;
489
		unsigned nb = LENGTH_list(br);
452
	IGNORE check_value ( OPT_VAL_base_classes, ( ulong ) ( nb - 1 ) ) ;
490
		IGNORE check_value(OPT_VAL_base_classes,(ulong)(nb - 1));
453
	IGNORE check_value ( OPT_VAL_direct_bases, ( ulong ) nd ) ;
491
		IGNORE check_value(OPT_VAL_direct_bases,(ulong)nd);
454
	COPY_unsigned ( ctype_no_bases ( ct ), nb ) ;
492
		COPY_unsigned(ctype_no_bases(ct), nb);
455
	while ( !IS_NULL_list ( br ) ) {
493
		while (!IS_NULL_list(br)) {
456
	    GRAPH gs ;
494
			GRAPH gs;
457
	    nb-- ;
495
			nb--;
458
	    DESTROY_CONS_graph ( destroy, gs, br, br ) ;
496
			DESTROY_CONS_graph(destroy, gs, br, br);
459
	    do {
497
			do {
460
		COPY_unsigned ( graph_no ( gs ), nb ) ;
498
				COPY_unsigned(graph_no(gs), nb);
461
		gs = DEREF_graph ( graph_equal ( gs ) ) ;
499
				gs = DEREF_graph(graph_equal(gs));
462
	    } while ( !IS_NULL_graph ( gs ) ) ;
500
			} while (!IS_NULL_graph(gs));
463
	}
501
		}
464
	br = REVERSE_list ( virtual_bases ) ;
502
		br = REVERSE_list(virtual_bases);
465
	COPY_list ( ctype_vbase ( ct ), br ) ;
503
		COPY_list(ctype_vbase(ct), br);
466
	nd = LENGTH_list ( br ) ;
504
		nd = LENGTH_list(br);
467
	IGNORE check_value ( OPT_VAL_virtual_bases, ( ulong ) nd ) ;
505
		IGNORE check_value(OPT_VAL_virtual_bases,(ulong)nd);
468
	virtual_bases = NULL_list ( GRAPH ) ;
506
		virtual_bases = NULL_list(GRAPH);
469
 
507
 
470
	/* Mark single inheritance bases */
508
		/* Mark single inheritance bases */
471
	do {
509
		do {
472
	    DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
510
			DECL_SPEC acc = DEREF_dspec(graph_access(gr));
473
	    acc |= dspec_ignore ;
511
			acc |= dspec_ignore;
474
	    COPY_dspec ( graph_access ( gr ), acc ) ;
512
			COPY_dspec(graph_access(gr), acc);
475
	    gr = find_first_base ( gr ) ;
513
			gr = find_first_base(gr);
476
	} while ( !IS_NULL_graph ( gr ) ) ;
514
		} while (!IS_NULL_graph(gr));
477
 
515
 
478
	/* Set up base class namespaces */
516
		/* Set up base class namespaces */
479
	while ( !IS_NULL_list ( bs ) ) {
517
		while (!IS_NULL_list(bs)) {
480
	    GRAPH gs = DEREF_graph ( HEAD_list ( bs ) ) ;
518
			GRAPH gs = DEREF_graph(HEAD_list(bs));
481
	    CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
519
			CLASS_TYPE cs = DEREF_ctype(graph_head(gs));
482
	    NAMESPACE ns = DEREF_nspace ( ctype_member ( cs ) ) ;
520
			NAMESPACE ns = DEREF_nspace(ctype_member(cs));
483
	    NAMESPACE nt = DEREF_nspace ( ctype_member ( ct ) ) ;
521
			NAMESPACE nt = DEREF_nspace(ctype_member(ct));
484
	    IGNORE use_namespace ( ns, nt, nt ) ;
522
			IGNORE use_namespace(ns, nt, nt);
485
	    uncache_namespace ( ns, 0 ) ;
523
			uncache_namespace(ns, 0);
486
	    bs = TAIL_list ( bs ) ;
524
			bs = TAIL_list(bs);
487
	}
525
		}
488
 
526
 
489
	/* Record class information */
527
		/* Record class information */
-
 
528
		if (!ok) {
490
	if ( !ok ) report ( crt_loc, ERR_class_derived_empty ( ct ) ) ;
529
			report(crt_loc, ERR_class_derived_empty(ct));
-
 
530
		}
491
	ci |= base_info ;
531
		ci |= base_info;
492
	COPY_cinfo ( ctype_info ( ct ), ci ) ;
532
		COPY_cinfo(ctype_info(ct), ci);
493
	base_info = cinfo_none ;
533
		base_info = cinfo_none;
-
 
534
		if (do_dump) {
494
	if ( do_dump ) dump_base ( ct ) ;
535
			dump_base(ct);
-
 
536
		}
495
 
537
 
496
	/* Set up virtual function table */
538
		/* Set up virtual function table */
497
	begin_virtual ( ct ) ;
539
		begin_virtual(ct);
498
    }
540
	}
499
    return ;
541
	return;
500
}
542
}
501
 
543
 
502
 
544
 
503
/*
545
/*
504
    ADD A BASE CLASS TO A CLASS DEFINITION
546
    ADD A BASE CLASS TO A CLASS DEFINITION
505
 
547
 
506
    This routine adds a base class bid with access specifier acc to the
548
    This routine adds a base class bid with access specifier acc to the
507
    current class.  virt is true to indicate a virtual base class.
549
    current class.  virt is true to indicate a virtual base class.
508
*/
550
*/
509
 
551
 
510
void add_base_class
552
void
511
    PROTO_N ( ( bid, acc, virt ) )
-
 
512
    PROTO_T ( IDENTIFIER bid X DECL_SPEC acc X int virt )
553
add_base_class(IDENTIFIER bid, DECL_SPEC acc, int virt)
513
{
554
{
514
    GRAPH gt ;
555
	GRAPH gt;
515
    int ok = 1 ;
556
	int ok = 1;
516
    CLASS_INFO cj ;
557
	CLASS_INFO cj;
517
    int templ = 0 ;
558
	int templ = 0;
518
    LIST ( GRAPH ) bt ;
559
	LIST(GRAPH)bt;
519
    TYPE s = NULL_type ;
560
	TYPE s = NULL_type;
520
    CLASS_TYPE cs = NULL_ctype ;
561
	CLASS_TYPE cs = NULL_ctype;
521
 
562
 
522
    /* Examine the derived class */
563
	/* Examine the derived class */
523
    CLASS_TYPE ct = crt_class ;
564
	CLASS_TYPE ct = crt_class;
524
    CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
565
	CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
525
    if ( ci & cinfo_union ) {
566
	if (ci & cinfo_union) {
526
	/* Derived class can't be a union */
567
		/* Derived class can't be a union */
527
	report ( crt_loc, ERR_class_union_deriv ( ct ) ) ;
568
		report(crt_loc, ERR_class_union_deriv(ct));
528
	ok = 0 ;
569
		ok = 0;
529
    }
570
	}
530
 
571
 
531
    /* Examine the base class */
572
	/* Examine the base class */
532
    if ( IS_id_class_name_etc ( bid ) ) {
573
	if (IS_id_class_name_etc(bid)) {
533
	s = DEREF_type ( id_class_name_etc_defn ( bid ) ) ;
574
		s = DEREF_type(id_class_name_etc_defn(bid));
534
    } else {
575
	} else {
535
	IDENTIFIER tid ;
576
		IDENTIFIER tid;
536
	HASHID bnm = DEREF_hashid ( id_name ( bid ) ) ;
577
		HASHID bnm = DEREF_hashid(id_name(bid));
537
	if ( crt_id_qualifier == qual_none ) {
578
		if (crt_id_qualifier == qual_none) {
538
	    tid = find_type_id ( bnm, 1 ) ;
579
			tid = find_type_id(bnm, 1);
539
	} else {
580
		} else {
540
	    NAMESPACE bns = DEREF_nspace ( id_parent ( bid ) ) ;
581
			NAMESPACE bns = DEREF_nspace(id_parent(bid));
541
	    tid = find_qual_id ( bns, bnm, 0, 1 ) ;
582
			tid = find_qual_id(bns, bnm, 0, 1);
542
	    if ( IS_NULL_id ( tid ) ) {
583
			if (IS_NULL_id(tid)) {
543
		/* Allow for implicit typename */
584
				/* Allow for implicit typename */
544
		s = check_typename ( bns, bid, btype_class ) ;
585
				s = check_typename(bns, bid, btype_class);
545
	    }
586
			}
546
	}
587
		}
547
	if ( !IS_NULL_id ( tid ) ) {
588
		if (!IS_NULL_id(tid)) {
548
	    if ( IS_id_ambig ( tid ) ) {
589
			if (IS_id_ambig(tid)) {
549
		tid = report_ambiguous ( tid, 0, 1, 1 ) ;
590
				tid = report_ambiguous(tid, 0, 1, 1);
550
	    }
591
			}
551
	    if ( IS_id_class_name_etc ( tid ) ) {
592
			if (IS_id_class_name_etc(tid)) {
552
		s = DEREF_type ( id_class_name_etc_defn ( tid ) ) ;
593
				s = DEREF_type(id_class_name_etc_defn(tid));
553
		bid = tid ;
594
				bid = tid;
554
	    }
595
			}
555
	}
596
		}
556
    }
597
	}
557
    if ( !IS_NULL_type ( s ) ) {
598
	if (!IS_NULL_type(s)) {
558
	/* Declared base type */
599
		/* Declared base type */
559
	s = expand_type ( s, 2 ) ;
600
		s = expand_type(s, 2);
560
	if ( IS_type_compound ( s ) ) {
601
		if (IS_type_compound(s)) {
561
	    cs = DEREF_ctype ( type_compound_defn ( s ) ) ;
602
			cs = DEREF_ctype(type_compound_defn(s));
562
	} else if ( IS_type_token ( s ) ) {
603
		} else if (IS_type_token(s)) {
563
	    /* Allow for template parameters */
604
			/* Allow for template parameters */
564
	    IDENTIFIER pid = DEREF_id ( type_token_tok ( s ) ) ;
605
			IDENTIFIER pid = DEREF_id(type_token_tok(s));
565
	    cs = find_class ( pid ) ;
606
			cs = find_class(pid);
566
	    templ = 1 ;
607
			templ = 1;
567
	}
608
		}
568
	if ( IS_NULL_ctype ( cs ) ) {
609
		if (IS_NULL_ctype(cs)) {
569
	    /* Inappropriate base class type */
610
			/* Inappropriate base class type */
570
	    if ( !IS_type_error ( s ) ) {
611
			if (!IS_type_error(s)) {
571
		report ( crt_loc, ERR_class_derived_class ( s ) ) ;
612
				report(crt_loc, ERR_class_derived_class(s));
572
	    }
613
			}
-
 
614
			ok = 0;
-
 
615
		} else {
-
 
616
			/* Examine base class type */
-
 
617
			bid = DEREF_id(ctype_name(cs));
-
 
618
			cj = DEREF_cinfo(ctype_info(cs));
-
 
619
			if (cj & cinfo_union) {
-
 
620
				/* Base class can't be a union */
-
 
621
				report(crt_loc, ERR_class_union_base(cs));
-
 
622
				ok = 0;
-
 
623
			} else {
-
 
624
				/* Base class must be complete */
-
 
625
				ERROR err = check_incomplete(s);
-
 
626
				if (!IS_NULL_err(err)) {
-
 
627
					ERROR err2 =
-
 
628
					    ERR_class_derived_incompl();
-
 
629
					err = concat_error(err, err2);
-
 
630
					report(crt_loc, err);
573
	    ok = 0 ;
631
					ok = 0;
-
 
632
				}
-
 
633
			}
-
 
634
		}
574
	} else {
635
	} else {
575
	    /* Examine base class type */
636
		/* Undeclared base type */
576
	    bid = DEREF_id ( ctype_name ( cs ) ) ;
-
 
577
	    cj = DEREF_cinfo ( ctype_info ( cs ) ) ;
-
 
578
	    if ( cj & cinfo_union ) {
-
 
579
		/* Base class can't be a union */
-
 
580
		report ( crt_loc, ERR_class_union_base ( cs ) ) ;
637
		report(crt_loc, ERR_dcl_type_simple_undef(bid));
581
		ok = 0 ;
638
		ok = 0;
582
	    } else {
-
 
583
		/* Base class must be complete */
-
 
584
		ERROR err = check_incomplete ( s ) ;
-
 
585
		if ( !IS_NULL_err ( err ) ) {
-
 
586
		    ERROR err2 = ERR_class_derived_incompl () ;
-
 
587
		    err = concat_error ( err, err2 ) ;
-
 
588
		    report ( crt_loc, err ) ;
-
 
589
		    ok = 0 ;
-
 
590
		}
-
 
591
	    }
-
 
592
	}
639
	}
593
    } else {
-
 
594
	/* Undeclared base type */
-
 
595
	report ( crt_loc, ERR_dcl_type_simple_undef ( bid ) ) ;
-
 
596
	ok = 0 ;
-
 
597
    }
-
 
598
 
640
 
599
    /* Check the access specifier */
641
	/* Check the access specifier */
600
    if ( acc == dspec_none ) {
642
	if (acc == dspec_none) {
601
	/* No access specifier given */
643
		/* No access specifier given */
602
	acc = crt_access ;
644
		acc = crt_access;
603
	if ( acc != prev_access ) {
645
		if (acc != prev_access) {
604
	    /* Warn about 'class C : public A, B' */
646
			/* Warn about 'class C : public A, B' */
605
	    report ( crt_loc, ERR_class_access_base_acc ( bid, acc ) ) ;
647
			report(crt_loc, ERR_class_access_base_acc(bid, acc));
-
 
648
		}
-
 
649
	}
-
 
650
	prev_access = acc;
-
 
651
	if (virt) {
-
 
652
		prev_access |= dspec_virtual;
-
 
653
	}
-
 
654
 
-
 
655
	/* Check for duplicate base classes */
-
 
656
	gt = DEREF_graph(ctype_base(ct));
-
 
657
	if (ok) {
-
 
658
		bt = DEREF_list(graph_tails(gt));
-
 
659
		while (!IS_NULL_list(bt)) {
-
 
660
			GRAPH gu = DEREF_graph(HEAD_list(bt));
-
 
661
			CLASS_TYPE cu = DEREF_ctype(graph_head(gu));
-
 
662
			if (eq_ctype(cs, cu)) {
-
 
663
				report(crt_loc, ERR_class_mi_dup(ct, cs));
-
 
664
				ok = 0;
-
 
665
				break;
-
 
666
			}
-
 
667
			bt = TAIL_list(bt);
-
 
668
		}
-
 
669
	}
-
 
670
 
-
 
671
	/* Add base class to graph */
-
 
672
	if (ok) {
-
 
673
		OFFSET off;
-
 
674
		LIST(GRAPH)bs = NULL_list(GRAPH);
-
 
675
		GRAPH gs = DEREF_graph(ctype_base(cs));
-
 
676
		MAKE_off_base(gs, off);
-
 
677
		gs = copy_graph(gs, off, acc, virt, virt, templ);
-
 
678
		COPY_graph(off_base_graph(off), gs);
-
 
679
		COPY_graph(graph_up(gs), gt);
-
 
680
		CONS_graph(gs, bs, bs);
-
 
681
		bt = DEREF_list(graph_tails(gt));
-
 
682
		if (!IS_NULL_list(bt)) {
-
 
683
			/* Mark multiple inheritance */
-
 
684
			ci |= cinfo_multiple_base;
-
 
685
		}
-
 
686
		bt = APPEND_list(bt, bs);
-
 
687
		COPY_list(graph_tails(gt), bt);
-
 
688
 
-
 
689
		/* Adjust class information */
-
 
690
		cj = DEREF_cinfo(ctype_info(cs));
-
 
691
		ci = check_class_info(ci, cj, 1, acc);
-
 
692
		COPY_cinfo(ctype_info(ct), ci);
-
 
693
 
-
 
694
		/* Use class name */
-
 
695
		use_id(bid, 0);
606
	}
696
	}
607
    }
-
 
608
    prev_access = acc ;
-
 
609
    if ( virt ) prev_access |= dspec_virtual ;
-
 
610
 
-
 
611
    /* Check for duplicate base classes */
-
 
612
    gt = DEREF_graph ( ctype_base ( ct ) ) ;
-
 
613
    if ( ok ) {
-
 
614
	bt = DEREF_list ( graph_tails ( gt ) ) ;
-
 
615
	while ( !IS_NULL_list ( bt ) ) {
-
 
616
	    GRAPH gu = DEREF_graph ( HEAD_list ( bt ) ) ;
-
 
617
	    CLASS_TYPE cu = DEREF_ctype ( graph_head ( gu ) ) ;
-
 
618
	    if ( eq_ctype ( cs, cu ) ) {
-
 
619
		report ( crt_loc, ERR_class_mi_dup ( ct, cs ) ) ;
-
 
620
		ok = 0 ;
-
 
621
		break ;
-
 
622
	    }
-
 
623
	    bt = TAIL_list ( bt ) ;
-
 
624
	}
-
 
625
    }
-
 
626
 
-
 
627
    /* Add base class to graph */
-
 
628
    if ( ok ) {
-
 
629
	OFFSET off ;
-
 
630
	LIST ( GRAPH ) bs = NULL_list ( GRAPH ) ;
-
 
631
	GRAPH gs = DEREF_graph ( ctype_base ( cs ) ) ;
-
 
632
	MAKE_off_base ( gs, off ) ;
-
 
633
	gs = copy_graph ( gs, off, acc, virt, virt, templ ) ;
-
 
634
	COPY_graph ( off_base_graph ( off ), gs ) ;
-
 
635
	COPY_graph ( graph_up ( gs ), gt ) ;
-
 
636
	CONS_graph ( gs, bs, bs ) ;
-
 
637
	bt = DEREF_list ( graph_tails ( gt ) ) ;
-
 
638
	if ( !IS_NULL_list ( bt ) ) {
-
 
639
	    /* Mark multiple inheritance */
-
 
640
	    ci |= cinfo_multiple_base ;
-
 
641
	}
-
 
642
	bt = APPEND_list ( bt, bs ) ;
-
 
643
	COPY_list ( graph_tails ( gt ), bt ) ;
-
 
644
 
-
 
645
	/* Adjust class information */
-
 
646
	cj = DEREF_cinfo ( ctype_info ( cs ) ) ;
-
 
647
	ci = check_class_info ( ci, cj, 1, acc ) ;
-
 
648
	COPY_cinfo ( ctype_info ( ct ), ci ) ;
-
 
649
 
-
 
650
	/* Use class name */
-
 
651
	use_id ( bid, 0 ) ;
-
 
652
    }
-
 
653
    return ;
697
	return;
654
}
698
}
655
 
699
 
656
 
700
 
657
/*
701
/*
658
    FIND A BASE CLASS
702
    FIND A BASE CLASS
Line 665... Line 709...
665
    checks for 'class ct : public cs {}'.  If ct is a template class
709
    checks for 'class ct : public cs {}'.  If ct is a template class
666
    then def indicates whether this operation implies that ct should
710
    then def indicates whether this operation implies that ct should
667
    be defined (not properly implemented yet).
711
    be defined (not properly implemented yet).
668
*/
712
*/
669
 
713
 
670
GRAPH find_base_class
714
GRAPH
671
    PROTO_N ( ( ct, cs, def ) )
-
 
672
    PROTO_T ( CLASS_TYPE ct X CLASS_TYPE cs X int def )
715
find_base_class(CLASS_TYPE ct, CLASS_TYPE cs, int def)
673
{
716
{
674
    unsigned nt, ns ;
717
	unsigned nt, ns;
675
    complete_class ( ct, 1 ) ;
718
	complete_class(ct, 1);
676
    nt = DEREF_unsigned ( ctype_no_bases ( ct ) ) ;
719
	nt = DEREF_unsigned(ctype_no_bases(ct));
677
    ns = DEREF_unsigned ( ctype_no_bases ( cs ) ) ;
720
	ns = DEREF_unsigned(ctype_no_bases(cs));
678
    if ( nt >= ns ) {
721
	if (nt >= ns) {
679
	/* ct is bigger than cs */
722
		/* ct is bigger than cs */
680
	GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
723
		GRAPH gr = DEREF_graph(ctype_base(ct));
681
	return ( search_graph ( gr, cs ) ) ;
724
		return (search_graph(gr, cs));
682
    }
725
	}
683
    UNUSED ( def ) ;
726
	UNUSED(def);
684
    return ( NULL_graph ) ;
727
	return (NULL_graph);
685
}
728
}
686
 
729
 
687
 
730
 
688
/*
731
/*
689
    COMPARE TWO CLASSES
732
    COMPARE TWO CLASSES
Line 693... Line 736...
693
    class if the two classes are not so related.  The first guess is based
736
    class if the two classes are not so related.  The first guess is based
694
    on the relative numbers of base classes of each type.  def is as in
737
    on the relative numbers of base classes of each type.  def is as in
695
    find_base_class.
738
    find_base_class.
696
*/
739
*/
697
 
740
 
698
CLASS_TYPE compare_base_class
741
CLASS_TYPE
699
    PROTO_N ( ( ct, cs, def ) )
-
 
700
    PROTO_T ( CLASS_TYPE ct X CLASS_TYPE cs X int def )
742
compare_base_class(CLASS_TYPE ct, CLASS_TYPE cs, int def)
701
{
743
{
702
    unsigned nt, ns ;
744
	unsigned nt, ns;
703
    complete_class ( ct, 1 ) ;
745
	complete_class(ct, 1);
704
    complete_class ( cs, 1 ) ;
746
	complete_class(cs, 1);
705
    nt = DEREF_unsigned ( ctype_no_bases ( ct ) ) ;
747
	nt = DEREF_unsigned(ctype_no_bases(ct));
706
    ns = DEREF_unsigned ( ctype_no_bases ( cs ) ) ;
748
	ns = DEREF_unsigned(ctype_no_bases(cs));
707
    if ( nt >= ns ) {
749
	if (nt >= ns) {
708
	/* ct is bigger than cs */
750
		/* ct is bigger than cs */
709
	GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
751
		GRAPH gr = DEREF_graph(ctype_base(ct));
710
	gr = search_graph ( gr, cs ) ;
752
		gr = search_graph(gr, cs);
711
	if ( !IS_NULL_graph ( gr ) ) return ( cs ) ;
753
		if (!IS_NULL_graph(gr)) {
-
 
754
			return (cs);
-
 
755
		}
712
    } else {
756
	} else {
713
	/* ct is smaller than cs */
757
		/* ct is smaller than cs */
714
	GRAPH gr = DEREF_graph ( ctype_base ( cs ) ) ;
758
		GRAPH gr = DEREF_graph(ctype_base(cs));
715
	gr = search_graph ( gr, ct ) ;
759
		gr = search_graph(gr, ct);
716
	if ( !IS_NULL_graph ( gr ) ) return ( ct ) ;
760
		if (!IS_NULL_graph(gr)) {
-
 
761
			return (ct);
717
    }
762
		}
-
 
763
	}
718
    UNUSED ( def ) ;
764
	UNUSED(def);
719
    return ( NULL_ctype ) ;
765
	return (NULL_ctype);
720
}
766
}
721
 
767
 
722
 
768
 
723
/*
769
/*
724
    CHECK AN AMBIGUOUS BASE CLASS
770
    CHECK AN AMBIGUOUS BASE CLASS
725
 
771
 
726
    This routine checks whether the base class corresponding to the node
772
    This routine checks whether the base class corresponding to the node
727
    gr is ambiguous.  It returns a suitable error message.
773
    gr is ambiguous.  It returns a suitable error message.
728
*/
774
*/
729
 
775
 
730
ERROR check_ambig_base
776
ERROR
731
    PROTO_N ( ( gr ) )
-
 
732
    PROTO_T ( GRAPH gr )
777
check_ambig_base(GRAPH gr)
733
{
778
{
734
    if ( !IS_NULL_graph ( gr ) ) {
779
    if (!IS_NULL_graph(gr)) {
735
	DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
780
	DECL_SPEC acc = DEREF_dspec(graph_access(gr));
736
	if ( acc & dspec_alias ) {
781
	if (acc & dspec_alias) {
737
	    /* Ambiguous base class */
782
	    /* Ambiguous base class */
738
	    GRAPH gt = DEREF_graph ( graph_top ( gr ) ) ;
783
	    GRAPH gt = DEREF_graph(graph_top(gr));
739
	    CLASS_TYPE ct = DEREF_ctype ( graph_head ( gt ) ) ;
784
	    CLASS_TYPE ct = DEREF_ctype(graph_head(gt));
740
	    CLASS_TYPE cs = DEREF_ctype ( graph_head ( gr ) ) ;
785
	    CLASS_TYPE cs = DEREF_ctype(graph_head(gr));
741
	    ERROR err = ERR_class_member_lookup_ambig ( cs, ct ) ;
786
	    ERROR err = ERR_class_member_lookup_ambig(cs, ct);
742
	    return ( err ) ;
787
	    return (err);
743
	}
788
	}
744
    }
789
    }
745
    return ( NULL_err ) ;
790
    return (NULL_err);
746
}
791
}
747
 
792
 
748
 
793
 
749
/*
794
/*
750
    CHECK A VIRTUAL BASE CLASS
795
    CHECK A VIRTUAL BASE CLASS
751
 
796
 
752
    This routine checks whether the base class corresponding to the node
797
    This routine checks whether the base class corresponding to the node
753
    gr is a virtual base of a base class of a virtual base.  It returns a
798
    gr is a virtual base of a base class of a virtual base.  It returns a
754
    suitable error message.
799
    suitable error message.
755
*/
800
*/
756
 
801
 
757
ERROR check_virt_base
802
ERROR
758
    PROTO_N ( ( gr ) )
-
 
759
    PROTO_T ( GRAPH gr )
803
check_virt_base(GRAPH gr)
760
{
804
{
761
    if ( !IS_NULL_graph ( gr ) ) {
805
	if (!IS_NULL_graph(gr)) {
762
	DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
806
		DECL_SPEC acc = DEREF_dspec(graph_access(gr));
763
	if ( acc & dspec_mutable ) {
807
		if (acc & dspec_mutable) {
764
	    /* Virtual base class */
808
			/* Virtual base class */
765
	    GRAPH gt = DEREF_graph ( graph_top ( gr ) ) ;
809
			GRAPH gt = DEREF_graph(graph_top(gr));
766
	    CLASS_TYPE ct = DEREF_ctype ( graph_head ( gt ) ) ;
810
			CLASS_TYPE ct = DEREF_ctype(graph_head(gt));
767
	    CLASS_TYPE cs = DEREF_ctype ( graph_head ( gr ) ) ;
811
			CLASS_TYPE cs = DEREF_ctype(graph_head(gr));
768
	    ERROR err = ERR_class_derived_virt ( cs, ct ) ;
812
			ERROR err = ERR_class_derived_virt(cs, ct);
769
	    return ( err ) ;
813
			return (err);
770
	}
814
		}
771
    }
815
	}
772
    return ( NULL_err ) ;
816
	return (NULL_err);
773
}
817
}
774
 
818
 
775
 
819
 
776
/*
820
/*
777
    FIND A UNIQUE BASE CLASS
821
    FIND A UNIQUE BASE CLASS
778
 
822
 
779
    This routine returns the graph representing the unique direct base
823
    This routine returns the graph representing the unique direct base
780
    class of ct if this exists.  Otherwise it adds an error to err and
824
    class of ct if this exists.  Otherwise it adds an error to err and
781
    returns the null graph.
825
    returns the null graph.
782
*/
826
*/
783
 
827
 
784
GRAPH uniq_base_class
828
GRAPH
785
    PROTO_N ( ( ct, err ) )
-
 
786
    PROTO_T ( CLASS_TYPE ct X ERROR *err )
829
uniq_base_class(CLASS_TYPE ct, ERROR *err)
787
{
830
{
788
    GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
831
	GRAPH gr = DEREF_graph(ctype_base(ct));
789
    LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
832
	LIST(GRAPH)br = DEREF_list(graph_tails(gr));
790
    if ( LENGTH_list ( br ) == 1 ) {
833
	if (LENGTH_list(br) == 1) {
791
	GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
834
		GRAPH gs = DEREF_graph(HEAD_list(br));
792
	return ( gs ) ;
835
		return (gs);
793
    }
836
	}
794
    add_error ( err, ERR_class_base_init_uniq ( ct ) ) ;
837
	add_error(err, ERR_class_base_init_uniq(ct));
795
    return ( NULL_graph ) ;
838
	return (NULL_graph);
796
}
839
}
797
 
840
 
798
 
841
 
799
/*
842
/*
800
    FIND THE SHORTEST ROUTE TO A BASE CLASS
843
    FIND THE SHORTEST ROUTE TO A BASE CLASS
801
 
844
 
802
    There may be several path for accessing a virtual base class.  This
845
    There may be several path for accessing a virtual base class.  This
803
    routine finds the shortest such path in terms of virtual base
846
    routine finds the shortest such path in terms of virtual base
804
    indirections for reaching the base gr.
847
    indirections for reaching the base gr.
805
*/
848
*/
806
 
849
 
807
GRAPH min_base_class
850
GRAPH
808
    PROTO_N ( ( gr ) )
-
 
809
    PROTO_T ( GRAPH gr )
851
min_base_class(GRAPH gr)
810
{
852
{
811
    GRAPH gs = gr ;
853
	GRAPH gs = gr;
812
    unsigned n = ( unsigned ) UINT_MAX ;
854
	unsigned n = (unsigned)UINT_MAX;
813
    while ( !IS_NULL_graph ( gs ) ) {
855
	while (!IS_NULL_graph(gs)) {
814
	GRAPH gt = gs ;
856
		GRAPH gt = gs;
815
	unsigned m = 0 ;
857
		unsigned m = 0;
816
	while ( !IS_NULL_graph ( gt ) ) {
858
		while (!IS_NULL_graph(gt)) {
817
	    /* Find base class depth */
859
			/* Find base class depth */
818
	    DECL_SPEC acc = DEREF_dspec ( graph_access ( gt ) ) ;
860
			DECL_SPEC acc = DEREF_dspec(graph_access(gt));
819
	    if ( acc & dspec_virtual ) m++ ;
861
			if (acc & dspec_virtual) {
-
 
862
				m++;
-
 
863
			}
820
	    gt = DEREF_graph ( graph_up ( gt ) ) ;
864
			gt = DEREF_graph(graph_up(gt));
821
	}
865
		}
822
	if ( m < n ) {
866
		if (m < n) {
823
	    /* Shortest path so far */
867
			/* Shortest path so far */
824
	    gr = gs ;
868
			gr = gs;
825
	    n = m ;
869
			n = m;
-
 
870
		}
-
 
871
		gs = DEREF_graph(graph_equal(gs));
826
	}
872
	}
827
	gs = DEREF_graph ( graph_equal ( gs ) ) ;
-
 
828
    }
-
 
829
    return ( gr ) ;
873
	return (gr);
830
}
874
}
831
 
875
 
832
 
876
 
833
/*
877
/*
834
    FIND A DIRECT OR VIRTUAL BASE CLASS
878
    FIND A DIRECT OR VIRTUAL BASE CLASS
835
 
879
 
836
    This routine checks whether the class cs denotes a direct or a virtual
880
    This routine checks whether the class cs denotes a direct or a virtual
837
    base class of ct.  If so it returns the corresponding graph.  If it is
881
    base class of ct.  If so it returns the corresponding graph.  If it is
838
    both then an error is added to err and the direct base is returned.
882
    both then an error is added to err and the direct base is returned.
839
    Otherwise an error is added to err and the null graph is returned.
883
    Otherwise an error is added to err and the null graph is returned.
840
*/
884
*/
841
 
885
 
842
GRAPH direct_base_class
886
GRAPH
843
    PROTO_N ( ( ct, cs, err ) )
-
 
844
    PROTO_T ( CLASS_TYPE ct X CLASS_TYPE cs X ERROR *err )
887
direct_base_class(CLASS_TYPE ct, CLASS_TYPE cs, ERROR *err)
845
{
888
{
846
    GRAPH gt = NULL_graph ;
889
	GRAPH gt = NULL_graph;
847
    GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
890
	GRAPH gr = DEREF_graph(ctype_base(ct));
848
    LIST ( GRAPH ) bd = DEREF_list ( graph_tails ( gr ) ) ;
891
	LIST(GRAPH)bd = DEREF_list(graph_tails(gr));
849
    LIST ( GRAPH ) bv = DEREF_list ( ctype_vbase ( ct ) ) ;
892
	LIST(GRAPH)bv = DEREF_list(ctype_vbase(ct));
850
 
893
 
851
    /* Scan through direct base classes */
894
	/* Scan through direct base classes */
852
    while ( !IS_NULL_list ( bd ) ) {
895
	while (!IS_NULL_list(bd)) {
853
	GRAPH gs = DEREF_graph ( HEAD_list ( bd ) ) ;
896
		GRAPH gs = DEREF_graph(HEAD_list(bd));
854
	CLASS_TYPE cr = DEREF_ctype ( graph_head ( gs ) ) ;
897
		CLASS_TYPE cr = DEREF_ctype(graph_head(gs));
855
	if ( eq_ctype ( cr, cs ) ) {
898
		if (eq_ctype(cr, cs)) {
856
	    gt = gs ;
899
			gt = gs;
857
	    break ;
900
			break;
858
	}
901
		}
859
	bd = TAIL_list ( bd ) ;
902
		bd = TAIL_list(bd);
860
    }
903
	}
861
 
904
 
862
    /* Scan through virtual base classes */
905
	/* Scan through virtual base classes */
863
    while ( !IS_NULL_list ( bv ) ) {
906
	while (!IS_NULL_list(bv)) {
864
	GRAPH gs = DEREF_graph ( HEAD_list ( bv ) ) ;
907
		GRAPH gs = DEREF_graph(HEAD_list(bv));
865
	CLASS_TYPE cr = DEREF_ctype ( graph_head ( gs ) ) ;
908
		CLASS_TYPE cr = DEREF_ctype(graph_head(gs));
866
	if ( eq_ctype ( cr, cs ) ) {
909
		if (eq_ctype(cr, cs)) {
867
	    if ( IS_NULL_graph ( gt ) ) {
910
			if (IS_NULL_graph(gt)) {
868
		gt = gs ;
911
				gt = gs;
869
	    } else if ( !eq_graph ( gt, gs ) ) {
912
			} else if (!eq_graph(gt, gs)) {
870
		/* Both a direct and a virtual base */
913
				/* Both a direct and a virtual base */
871
		add_error ( err, ERR_class_base_init_ambig ( cs ) ) ;
914
				add_error(err, ERR_class_base_init_ambig(cs));
872
	    }
915
			}
873
	    break ;
916
			break;
874
	}
917
		}
875
	bv = TAIL_list ( bv ) ;
918
		bv = TAIL_list(bv);
876
    }
919
	}
877
 
920
 
878
    /* Return result */
921
	/* Return result */
879
    if ( IS_NULL_graph ( gt ) ) {
922
	if (IS_NULL_graph(gt)) {
880
	/* Neither a direct nor a virtual base */
923
		/* Neither a direct nor a virtual base */
881
	add_error ( err, ERR_class_base_init_base ( cs ) ) ;
924
		add_error(err, ERR_class_base_init_base(cs));
882
    }
925
	}
883
    return ( gt ) ;
926
	return (gt);
884
}
927
}
885
 
928
 
886
 
929
 
887
/*
930
/*
888
    FIND AN AMBIGUOUS BASE CLASS
931
    FIND AN AMBIGUOUS BASE CLASS
889
 
932
 
890
    This routine searches the graph gr for any ambiguous base class,
933
    This routine searches the graph gr for any ambiguous base class,
891
    returning the corresponding node if it is found, or the null graph
934
    returning the corresponding node if it is found, or the null graph
892
    otherwise.
935
    otherwise.
893
*/
936
*/
894
 
937
 
895
GRAPH find_ambig_base
938
GRAPH
896
    PROTO_N ( ( gr ) )
-
 
897
    PROTO_T ( GRAPH gr )
939
find_ambig_base(GRAPH gr)
898
{
940
{
899
    DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
941
	DECL_SPEC acc = DEREF_dspec(graph_access(gr));
900
    if ( acc & dspec_alias ) {
942
	if (acc & dspec_alias) {
901
	/* Ambiguous classes are marked */
943
		/* Ambiguous classes are marked */
902
	return ( gr ) ;
944
		return (gr);
903
    }
945
	}
904
    if ( acc & dspec_defn ) {
946
	if (acc & dspec_defn) {
905
	/* Only search the first occurrence of each class */
947
		/* Only search the first occurrence of each class */
906
	LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
948
		LIST(GRAPH)br = DEREF_list(graph_tails(gr));
907
	while ( !IS_NULL_list ( br ) ) {
949
		while (!IS_NULL_list(br)) {
908
	    GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
950
			GRAPH gs = DEREF_graph(HEAD_list(br));
909
	    gs = find_ambig_base ( gs ) ;
951
			gs = find_ambig_base(gs);
910
	    if ( !IS_NULL_graph ( gs ) ) return ( gs ) ;
952
			if (!IS_NULL_graph(gs)) {
-
 
953
				return (gs);
-
 
954
			}
911
	    br = TAIL_list ( br ) ;
955
			br = TAIL_list(br);
912
	}
956
		}
913
    }
957
	}
914
    return ( NULL_graph ) ;
958
	return (NULL_graph);
915
}
959
}
916
 
960
 
917
 
961
 
918
/*
962
/*
919
    EXPAND A BASE CLASS GRAPH
963
    EXPAND A BASE CLASS GRAPH
920
 
964
 
921
    This routine expands any token definitions in the base class graph
965
    This routine expands any token definitions in the base class graph
922
    gr.  The null graph is returned if the result is not a valid base
966
    gr.  The null graph is returned if the result is not a valid base
923
    class.
967
    class.
924
*/
968
*/
925
 
969
 
926
GRAPH expand_graph
970
GRAPH
927
    PROTO_N ( ( gr, rec ) )
-
 
928
    PROTO_T ( GRAPH gr X int rec )
971
expand_graph(GRAPH gr, int rec)
929
{
-
 
930
    if ( !IS_NULL_graph ( gr ) ) {
-
 
931
	TYPE t = NULL_type ;
-
 
932
	GRAPH gt = DEREF_graph ( graph_top ( gr ) ) ;
-
 
933
	CLASS_TYPE ct = DEREF_ctype ( graph_head ( gt ) ) ;
-
 
934
	CLASS_TYPE cs = DEREF_ctype ( graph_head ( gr ) ) ;
-
 
935
	ct = expand_ctype ( ct, rec, &t ) ;
-
 
936
	if ( IS_NULL_ctype ( ct ) ) return ( NULL_graph ) ;
-
 
937
	cs = expand_ctype ( cs, rec, &t ) ;
-
 
938
	if ( IS_NULL_ctype ( cs ) ) return ( NULL_graph ) ;
-
 
939
	gr = find_base_class ( ct, cs, 1 ) ;
-
 
940
    }
-
 
941
    return ( gr ) ;
-
 
942
}
-
 
943
 
-
 
944
 
-
 
945
/*
-
 
946
    CONSTRUCT AN INHERITED IDENTIFIER
-
 
947
 
-
 
948
    This routine constructs an identifier representing the inherited value
-
 
949
    of id in the namespace ns.  gr and off give the corresponding base class
-
 
950
    if appropriate.
-
 
951
*/
-
 
952
 
-
 
953
static IDENTIFIER inherit_id
-
 
954
    PROTO_N ( ( ns, gr, off, id, prev ) )
-
 
955
    PROTO_T ( NAMESPACE ns X GRAPH gr X OFFSET off X IDENTIFIER id X int prev )
-
 
956
{
972
{
957
    HASHID nm ;
-
 
958
    DECL_SPEC ds ;
-
 
959
    unsigned tag ;
-
 
960
    NAMESPACE pns ;
-
 
961
    IDENTIFIER cid ;
-
 
962
    LIST ( IDENTIFIER ) p = NULL_list ( IDENTIFIER ) ;
-
 
963
 
-
 
964
    /* Check for trivial inheritance */
-
 
965
    if ( IS_NULL_id ( id ) ) return ( NULL_id ) ;
-
 
966
    pns = DEREF_nspace ( id_parent ( id ) ) ;
-
 
967
    if ( EQ_nspace ( pns, ns ) ) return ( id ) ;
-
 
968
 
-
 
969
    /* Check for previous declarations */
-
 
970
    tag = TAG_id ( id ) ;
-
 
971
    nm = DEREF_hashid ( id_name ( id ) ) ;
-
 
972
    if ( !IS_NULL_graph ( gr ) && !prev ) {
-
 
973
	LIST ( IDENTIFIER ) q ;
-
 
974
	p = DEREF_list ( graph_member ( gr ) ) ;
-
 
975
	q = p ;
-
 
976
	while ( !IS_NULL_list ( q ) ) {
-
 
977
	    IDENTIFIER qid = DEREF_id ( HEAD_list ( q ) ) ;
-
 
978
	    HASHID qnm = DEREF_hashid ( id_name ( qid ) ) ;
-
 
979
	    if ( EQ_hashid ( qnm, nm ) && tag == TAG_id ( qid ) ) {
-
 
980
		/* Already have inherited member */
-
 
981
		return ( qid ) ;
-
 
982
	    }
-
 
983
	    q = TAIL_list ( q ) ;
-
 
984
	}
-
 
985
    }
-
 
986
 
-
 
987
    /* Calculate inherited access */
-
 
988
    ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
989
    if ( !IS_NULL_graph ( gr ) ) {
973
	if (!IS_NULL_graph(gr)) {
990
	int adjust = 1 ;
974
		TYPE t = NULL_type;
991
	if ( tag == id_class_name_tag ) {
975
		GRAPH gt = DEREF_graph(graph_top(gr));
992
	    CLASS_TYPE cs = DEREF_ctype ( graph_head ( gr ) ) ;
976
		CLASS_TYPE ct = DEREF_ctype(graph_head(gt));
993
	    TYPE t = DEREF_type ( id_class_name_defn ( id ) ) ;
977
		CLASS_TYPE cs = DEREF_ctype(graph_head(gr));
994
	    if ( IS_type_compound ( t ) ) {
978
		ct = expand_ctype(ct, rec, &t);
995
		CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
-
 
996
		if ( eq_ctype ( cs, ct ) ) {
979
		if (IS_NULL_ctype(ct)) {
997
		    /* This is an injected base class name */
-
 
998
		    adjust = 0 ;
980
			return (NULL_graph);
999
		}
981
		}
1000
	    }
-
 
1001
	}
-
 
1002
	if ( adjust ) {
-
 
1003
	    DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
-
 
1004
	    DECL_SPEC acc2 = unshadow_access ( acc ) ;
-
 
1005
	    acc = join_access ( ds, acc ) ;
982
		cs = expand_ctype(cs, rec, &t);
1006
	    acc2 = join_access ( ds, acc2 ) ;
-
 
1007
	    ds &= ~( dspec_access | dspec_access2 ) ;
-
 
1008
	    ds |= acc ;
-
 
1009
	    ds |= shadow_access ( acc2 ) ;
-
 
1010
	}
-
 
1011
    }
-
 
1012
    ds |= dspec_inherit ;
-
 
1013
    ds &= ~dspec_alias ;
-
 
1014
 
-
 
1015
    /* Copy the identifier */
-
 
1016
    cid = copy_id ( id, 0 ) ;
-
 
1017
    if ( !EQ_id ( cid, id ) ) {
-
 
1018
	switch ( tag ) {
-
 
1019
	    case id_function_tag :
-
 
1020
	    case id_mem_func_tag :
-
 
1021
	    case id_stat_mem_func_tag : {
-
 
1022
		/* Functions */
-
 
1023
		IDENTIFIER over ;
-
 
1024
		over = DEREF_id ( id_function_etc_over ( cid ) ) ;
-
 
1025
		if ( !IS_NULL_id ( over ) ) {
983
		if (IS_NULL_ctype(cs)) {
1026
		    /* Overloaded functions */
984
			return (NULL_graph);
1027
		    over = inherit_id ( ns, gr, off, over, 1 ) ;
-
 
1028
		    COPY_id ( id_function_etc_over ( cid ), over ) ;
-
 
1029
		}
985
		}
1030
		break ;
-
 
1031
	    }
-
 
1032
	    case id_member_tag : {
-
 
1033
		/* Members */
-
 
1034
		if ( !IS_NULL_graph ( gr ) ) {
-
 
1035
		    /* Add base class offset */
986
		gr = find_base_class(ct, cs, 1);
1036
		    OFFSET off1 = DEREF_off ( id_member_off ( cid ) ) ;
-
 
1037
		    MAKE_off_plus ( off, off1, off1 ) ;
-
 
1038
		    COPY_off ( id_member_off ( cid ), off1 ) ;
-
 
1039
		    COPY_graph ( id_member_base ( cid ), gr ) ;
-
 
1040
		}
-
 
1041
		break ;
-
 
1042
	    }
-
 
1043
	}
987
	}
1044
	COPY_nspace ( id_parent ( cid ), ns ) ;
-
 
1045
	COPY_dspec ( id_storage ( cid ), ds ) ;
988
	return (gr);
1046
    }
989
}
1047
 
990
 
-
 
991
 
-
 
992
/*
-
 
993
    CONSTRUCT AN INHERITED IDENTIFIER
-
 
994
 
-
 
995
    This routine constructs an identifier representing the inherited value
-
 
996
    of id in the namespace ns.  gr and off give the corresponding base class
-
 
997
    if appropriate.
-
 
998
*/
-
 
999
 
-
 
1000
static IDENTIFIER
-
 
1001
inherit_id(NAMESPACE ns, GRAPH gr, OFFSET off, IDENTIFIER id, int prev)
-
 
1002
{
-
 
1003
	HASHID nm;
-
 
1004
	DECL_SPEC ds;
-
 
1005
	unsigned tag;
-
 
1006
	NAMESPACE pns;
-
 
1007
	IDENTIFIER cid;
-
 
1008
	LIST(IDENTIFIER)p = NULL_list(IDENTIFIER);
-
 
1009
 
-
 
1010
	/* Check for trivial inheritance */
-
 
1011
	if (IS_NULL_id(id)) {
-
 
1012
		return (NULL_id);
-
 
1013
	}
-
 
1014
	pns = DEREF_nspace(id_parent(id));
-
 
1015
	if (EQ_nspace(pns, ns)) {
-
 
1016
		return (id);
-
 
1017
	}
-
 
1018
 
-
 
1019
	/* Check for previous declarations */
-
 
1020
	tag = TAG_id(id);
-
 
1021
	nm = DEREF_hashid(id_name(id));
-
 
1022
	if (!IS_NULL_graph(gr) && !prev) {
-
 
1023
		LIST(IDENTIFIER)q;
-
 
1024
		p = DEREF_list(graph_member(gr));
-
 
1025
		q = p;
-
 
1026
		while (!IS_NULL_list(q)) {
-
 
1027
			IDENTIFIER qid = DEREF_id(HEAD_list(q));
-
 
1028
			HASHID qnm = DEREF_hashid(id_name(qid));
-
 
1029
			if (EQ_hashid(qnm, nm) && tag == TAG_id(qid)) {
-
 
1030
				/* Already have inherited member */
-
 
1031
				return (qid);
-
 
1032
			}
-
 
1033
			q = TAIL_list(q);
-
 
1034
		}
-
 
1035
	}
-
 
1036
 
-
 
1037
	/* Calculate inherited access */
-
 
1038
	ds = DEREF_dspec(id_storage(id));
-
 
1039
	if (!IS_NULL_graph(gr)) {
-
 
1040
		int adjust = 1;
-
 
1041
		if (tag == id_class_name_tag) {
-
 
1042
			CLASS_TYPE cs = DEREF_ctype(graph_head(gr));
-
 
1043
			TYPE t = DEREF_type(id_class_name_defn(id));
-
 
1044
			if (IS_type_compound(t)) {
-
 
1045
				CLASS_TYPE ct =
-
 
1046
				    DEREF_ctype(type_compound_defn(t));
-
 
1047
				if (eq_ctype(cs, ct)) {
-
 
1048
					/* This is an injected base class
-
 
1049
					 * name */
-
 
1050
					adjust = 0;
-
 
1051
				}
-
 
1052
			}
-
 
1053
		}
-
 
1054
		if (adjust) {
-
 
1055
			DECL_SPEC acc = DEREF_dspec(graph_access(gr));
-
 
1056
			DECL_SPEC acc2 = unshadow_access(acc);
-
 
1057
			acc = join_access(ds, acc);
-
 
1058
			acc2 = join_access(ds, acc2);
-
 
1059
			ds &= ~(dspec_access | dspec_access2);
-
 
1060
			ds |= acc;
-
 
1061
			ds |= shadow_access(acc2);
-
 
1062
		}
-
 
1063
	}
-
 
1064
	ds |= dspec_inherit;
-
 
1065
	ds &= ~dspec_alias;
-
 
1066
 
-
 
1067
	/* Copy the identifier */
-
 
1068
	cid = copy_id(id, 0);
-
 
1069
	if (!EQ_id(cid, id)) {
-
 
1070
		switch (tag) {
-
 
1071
		case id_function_tag:
-
 
1072
		case id_mem_func_tag:
-
 
1073
		case id_stat_mem_func_tag: {
-
 
1074
			/* Functions */
-
 
1075
			IDENTIFIER over;
-
 
1076
			over = DEREF_id(id_function_etc_over(cid));
-
 
1077
			if (!IS_NULL_id(over)) {
-
 
1078
				/* Overloaded functions */
-
 
1079
				over = inherit_id(ns, gr, off, over, 1);
-
 
1080
				COPY_id(id_function_etc_over(cid), over);
-
 
1081
			}
-
 
1082
			break;
-
 
1083
		}
-
 
1084
		case id_member_tag: {
-
 
1085
			/* Members */
-
 
1086
			if (!IS_NULL_graph(gr)) {
-
 
1087
				/* Add base class offset */
-
 
1088
				OFFSET off1 = DEREF_off(id_member_off(cid));
-
 
1089
				MAKE_off_plus(off, off1, off1);
-
 
1090
				COPY_off(id_member_off(cid), off1);
-
 
1091
				COPY_graph(id_member_base(cid), gr);
-
 
1092
			}
-
 
1093
			break;
-
 
1094
		}
-
 
1095
		}
-
 
1096
		COPY_nspace(id_parent(cid), ns);
-
 
1097
		COPY_dspec(id_storage(cid), ds);
-
 
1098
	}
-
 
1099
 
1048
    /* Add to list of inherited members */
1100
	/* Add to list of inherited members */
1049
    if ( !IS_NULL_graph ( gr ) && !prev ) {
1101
	if (!IS_NULL_graph(gr) && !prev) {
1050
	CONS_id ( cid, p, p ) ;
1102
		CONS_id(cid, p, p);
1051
	COPY_list ( graph_member ( gr ), p ) ;
1103
		COPY_list(graph_member(gr), p);
1052
    }
1104
	}
1053
    return ( cid ) ;
1105
	return (cid);
1054
}
1106
}
1055
 
1107
 
1056
 
1108
 
1057
/*
1109
/*
1058
    TYPE REPRESENTING A SET OF MEMBER LOOK-UPS
1110
    TYPE REPRESENTING A SET OF MEMBER LOOK-UPS
1059
 
1111
 
1060
    This structure is used to represent a list of class member look-ups.
1112
    This structure is used to represent a list of class member look-ups.
1061
    Each look-up consists of a member identifier plus a base class graph
1113
    Each look-up consists of a member identifier plus a base class graph
1062
    indicating from which base class it is inherited.
1114
    indicating from which base class it is inherited.
1063
*/
1115
*/
1064
 
1116
 
1065
typedef struct {
1117
typedef struct {
1066
    LIST ( IDENTIFIER ) ids ;
1118
	LIST(IDENTIFIER) ids;
1067
    LIST ( GRAPH ) bases ;
1119
	LIST(GRAPH) bases;
1068
} MEMBER_LOOKUP ;
1120
} MEMBER_LOOKUP;
1069
 
1121
 
1070
 
1122
 
1071
/*
1123
/*
1072
    RESOLVE AMBIGUOUS MEMBER LOOK-UP
1124
    RESOLVE AMBIGUOUS MEMBER LOOK-UP
1073
 
1125
 
1074
    This routine resolves the potentially ambiguous member look-up for the
1126
    This routine resolves the potentially ambiguous member look-up for the
1075
    member named nm in the namespace ns given by mems.  If form is not
1127
    member named nm in the namespace ns given by mems.  If form is not
1076
    the null type then it gives a list of template arguments to be
1128
    the null type then it gives a list of template arguments to be
1077
    applied to nm.  The routine also destroys mems.
1129
    applied to nm.  The routine also destroys mems.
1078
*/
1130
*/
1079
 
1131
 
1080
static IDENTIFIER resolve_member
1132
static IDENTIFIER
1081
    PROTO_N ( ( ns, nm, mems, form, dominate ) )
-
 
1082
    PROTO_T ( NAMESPACE ns X HASHID nm X MEMBER_LOOKUP *mems X
1133
resolve_member(NAMESPACE ns, HASHID nm, MEMBER_LOOKUP *mems, TYPE form,
1083
	      TYPE form X int dominate )
1134
	       int dominate)
1084
{
1135
{
1085
    IDENTIFIER id = NULL_id ;
1136
	IDENTIFIER id = NULL_id;
1086
    LIST ( IDENTIFIER ) ambig = NULL_list ( IDENTIFIER ) ;
1137
	LIST(IDENTIFIER)ambig = NULL_list(IDENTIFIER);
1087
    LIST ( IDENTIFIER ) pids = mems->ids ;
1138
	LIST(IDENTIFIER)pids = mems->ids;
1088
    LIST ( GRAPH ) grs = mems->bases ;
1139
	LIST(GRAPH)grs = mems->bases;
1089
 
1140
 
1090
    /* Check for empty lists */
1141
	/* Check for empty lists */
1091
    if ( IS_NULL_list ( pids ) ) return ( NULL_id ) ;
-
 
1092
 
-
 
1093
    /* Scan through various look-ups */
-
 
1094
    while ( !IS_NULL_list ( pids ) ) {
-
 
1095
	IDENTIFIER pid = DEREF_id ( HEAD_list ( pids ) ) ;
-
 
1096
	GRAPH gp = DEREF_graph ( HEAD_list ( grs ) ) ;
-
 
1097
	if ( !IS_NULL_id ( pid ) ) {
1142
	if (IS_NULL_list(pids)) {
1098
	    int ok = 1 ;
-
 
1099
	    int dep = IS_id_member ( pid ) ;
-
 
1100
	    IDENTIFIER pal = DEREF_id ( id_alias ( pid ) ) ;
-
 
1101
	    DECL_SPEC pds = DEREF_dspec ( id_storage ( pid ) ) ;
-
 
1102
	    DECL_SPEC gds = DEREF_dspec ( graph_access ( gp ) ) ;
-
 
1103
	    DECL_SPEC acc = join_access ( pds, gds ) ;
-
 
1104
	    OFFSET off = DEREF_off ( graph_off ( gp ) ) ;
-
 
1105
 
-
 
1106
	    /* Mark equivalent look-ups */
-
 
1107
	    LIST ( IDENTIFIER ) qids = TAIL_list ( pids ) ;
-
 
1108
	    LIST ( GRAPH ) hrs = TAIL_list ( grs ) ;
-
 
1109
	    while ( !IS_NULL_list ( qids ) ) {
-
 
1110
		IDENTIFIER qid = DEREF_id ( HEAD_list ( qids ) ) ;
-
 
1111
		IDENTIFIER qal = DEREF_id ( id_alias ( qid ) ) ;
-
 
1112
		GRAPH hp = DEREF_graph ( HEAD_list ( hrs ) ) ;
-
 
1113
		if ( EQ_id ( pal, qal ) ) {
-
 
1114
		    if ( !dep || eq_graph ( gp, hp ) ) {
-
 
1115
			/* This represents the same member */
-
 
1116
			DECL_SPEC acc2 ;
-
 
1117
			COPY_id ( HEAD_list ( qids ), NULL_id ) ;
-
 
1118
			pds = DEREF_dspec ( id_storage ( qid ) ) ;
-
 
1119
			gds = DEREF_dspec ( graph_access ( hp ) ) ;
-
 
1120
			acc2 = join_access ( pds, gds ) ;
-
 
1121
			if ( acc2 < acc ) {
-
 
1122
			    /* More accessible by this route */
-
 
1123
			    gp = hp ;
-
 
1124
			    acc = acc2 ;
-
 
1125
			}
-
 
1126
		    }
-
 
1127
		} else {
-
 
1128
		    /* Check for dominating bases */
-
 
1129
		    if ( is_subgraph ( gp, hp ) ) {
-
 
1130
			if ( dominate ) {
-
 
1131
			    COPY_id ( HEAD_list ( qids ), NULL_id ) ;
-
 
1132
			}
-
 
1133
		    } else if ( is_subgraph ( hp, gp ) ) {
-
 
1134
			ok = 0 ;
-
 
1135
			break ;
-
 
1136
		    }
-
 
1137
		}
-
 
1138
		qids = TAIL_list ( qids ) ;
-
 
1139
		hrs = TAIL_list ( hrs ) ;
-
 
1140
	    }
-
 
1141
 
-
 
1142
	    /* Record look-up */
-
 
1143
	    if ( ok ) {
-
 
1144
		int prev = 0 ;
-
 
1145
		if ( !IS_NULL_type ( form ) && IS_type_token ( form ) ) {
-
 
1146
		    /* Allow for templates */
-
 
1147
		    LIST ( TOKEN ) args ;
-
 
1148
		    args = DEREF_list ( type_token_args ( form ) ) ;
-
 
1149
		    pid = apply_template ( pid, args, 0, 0 ) ;
-
 
1150
		    prev = 1 ;
-
 
1151
		}
-
 
1152
		pid = inherit_id ( ns, gp, off, pid, prev ) ;
-
 
1153
		if ( IS_NULL_id ( id ) ) {
-
 
1154
		    id = pid ;
1143
		return (NULL_id);
1155
		} else {
-
 
1156
		    CONS_id ( pid, ambig, ambig ) ;
-
 
1157
		}
-
 
1158
	    }
-
 
1159
	}
1144
	}
-
 
1145
 
-
 
1146
	/* Scan through various look-ups */
-
 
1147
	while (!IS_NULL_list(pids)) {
-
 
1148
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
-
 
1149
		GRAPH gp = DEREF_graph(HEAD_list(grs));
-
 
1150
		if (!IS_NULL_id(pid)) {
-
 
1151
			int ok = 1;
-
 
1152
			int dep = IS_id_member(pid);
-
 
1153
			IDENTIFIER pal = DEREF_id(id_alias(pid));
-
 
1154
			DECL_SPEC pds = DEREF_dspec(id_storage(pid));
-
 
1155
			DECL_SPEC gds = DEREF_dspec(graph_access(gp));
-
 
1156
			DECL_SPEC acc = join_access(pds, gds);
-
 
1157
			OFFSET off = DEREF_off(graph_off(gp));
-
 
1158
 
-
 
1159
			/* Mark equivalent look-ups */
-
 
1160
			LIST(IDENTIFIER)qids = TAIL_list(pids);
-
 
1161
			LIST(GRAPH)hrs = TAIL_list(grs);
-
 
1162
			while (!IS_NULL_list(qids)) {
-
 
1163
				IDENTIFIER qid = DEREF_id(HEAD_list(qids));
-
 
1164
				IDENTIFIER qal = DEREF_id(id_alias(qid));
-
 
1165
				GRAPH hp = DEREF_graph(HEAD_list(hrs));
-
 
1166
				if (EQ_id(pal, qal)) {
-
 
1167
					if (!dep || eq_graph(gp, hp)) {
-
 
1168
						/* This represents the same
-
 
1169
						 * member */
-
 
1170
						DECL_SPEC acc2;
-
 
1171
						COPY_id(HEAD_list(qids),
-
 
1172
							NULL_id);
-
 
1173
						pds = DEREF_dspec(id_storage(qid));
-
 
1174
						gds = DEREF_dspec(graph_access(hp));
-
 
1175
						acc2 = join_access(pds, gds);
-
 
1176
						if (acc2 < acc) {
-
 
1177
							/* More accessible by
-
 
1178
							 * this route */
-
 
1179
							gp = hp;
-
 
1180
							acc = acc2;
-
 
1181
						}
-
 
1182
					}
-
 
1183
				} else {
-
 
1184
					/* Check for dominating bases */
-
 
1185
					if (is_subgraph(gp, hp)) {
-
 
1186
						if (dominate) {
-
 
1187
							COPY_id(HEAD_list(qids),
-
 
1188
								NULL_id);
-
 
1189
						}
-
 
1190
					} else if (is_subgraph(hp, gp)) {
-
 
1191
						ok = 0;
-
 
1192
						break;
-
 
1193
					}
-
 
1194
				}
-
 
1195
				qids = TAIL_list(qids);
-
 
1196
				hrs = TAIL_list(hrs);
-
 
1197
			}
-
 
1198
 
-
 
1199
			/* Record look-up */
-
 
1200
			if (ok) {
-
 
1201
				int prev = 0;
-
 
1202
				if (!IS_NULL_type(form) &&
-
 
1203
				    IS_type_token(form)) {
-
 
1204
					/* Allow for templates */
-
 
1205
					LIST(TOKEN)args;
-
 
1206
					args =
-
 
1207
					    DEREF_list(type_token_args(form));
-
 
1208
					pid = apply_template(pid, args, 0, 0);
-
 
1209
					prev = 1;
-
 
1210
				}
-
 
1211
				pid = inherit_id(ns, gp, off, pid, prev);
-
 
1212
				if (IS_NULL_id(id)) {
-
 
1213
					id = pid;
-
 
1214
				} else {
-
 
1215
					CONS_id(pid, ambig, ambig);
-
 
1216
				}
-
 
1217
			}
-
 
1218
		}
1160
	pids = TAIL_list ( pids ) ;
1219
		pids = TAIL_list(pids);
1161
	grs = TAIL_list ( grs ) ;
1220
		grs = TAIL_list(grs);
1162
    }
1221
	}
1163
 
1222
 
1164
    /* Construct the result */
1223
	/* Construct the result */
1165
    if ( !IS_NULL_list ( ambig ) ) {
1224
	if (!IS_NULL_list(ambig)) {
1166
	DECL_SPEC ds ;
1225
		DECL_SPEC ds;
1167
	CONS_id ( id, ambig, ambig ) ;
1226
		CONS_id(id, ambig, ambig);
1168
	ds = find_ambig_dspec ( ambig ) ;
1227
		ds = find_ambig_dspec(ambig);
1169
	ds |= dspec_inherit ;
1228
		ds |= dspec_inherit;
1170
	MAKE_id_ambig ( nm, ds, ns, crt_loc, ambig, 1, id ) ;
1229
		MAKE_id_ambig(nm, ds, ns, crt_loc, ambig, 1, id);
1171
    }
1230
	}
1172
 
1231
 
1173
    /* Destroy lists */
1232
	/* Destroy lists */
1174
    DESTROY_list ( mems->ids, SIZE_id ) ;
1233
	DESTROY_list(mems->ids, SIZE_id);
1175
    DESTROY_list ( mems->bases, SIZE_graph ) ;
1234
	DESTROY_list(mems->bases, SIZE_graph);
1176
    return ( id ) ;
1235
	return (id);
1177
}
1236
}
1178
 
1237
 
1179
 
1238
 
1180
/*
1239
/*
1181
    SEARCH A BASE CLASS GRAPH FOR AN IDENTIFIER
1240
    SEARCH A BASE CLASS GRAPH FOR AN IDENTIFIER
1182
 
1241
 
1183
    This routine searches the graph gr for all visible members named nm,
1242
    This routine searches the graph gr for all visible members named nm,
1184
    storing the result in mems.  If cs is not the null class then only
1243
    storing the result in mems.  If cs is not the null class then only
1185
    base classes lying below such a class are searched.  If type is nonzero
1244
    base classes lying below such a class are searched.  If type is nonzero
1186
    then only type members are found.  depth gives a depth count and is
1245
    then only type members are found.  depth gives a depth count and is
1187
    used because the top level is searched elsewhere.
1246
    used because the top level is searched elsewhere.
1188
*/
1247
*/
1189
 
1248
 
1190
static void search_base
1249
static void
1191
    PROTO_N ( ( gr, nm, mems, cs, type, depth ) )
-
 
1192
    PROTO_T ( GRAPH gr X HASHID nm X MEMBER_LOOKUP *mems X
1250
search_base(GRAPH gr, HASHID nm, MEMBER_LOOKUP *mems, CLASS_TYPE cs, int type,
1193
	      CLASS_TYPE cs X int type X int depth )
1251
	    int depth)
1194
{
1252
{
1195
    LIST ( GRAPH ) br ;
1253
	LIST(GRAPH)br;
1196
    LIST ( GRAPH ) gres = NULL_list ( GRAPH ) ;
1254
	LIST(GRAPH)gres = NULL_list(GRAPH);
1197
    LIST ( IDENTIFIER ) res = NULL_list ( IDENTIFIER ) ;
1255
	LIST(IDENTIFIER)res = NULL_list(IDENTIFIER);
1198
    DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
1256
	DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1199
    if ( !( acc & dspec_done ) ) {
1257
	if (!(acc & dspec_done)) {
1200
	/* Not yet in scope */
1258
		/* Not yet in scope */
1201
	mems->ids = res ;
1259
		mems->ids = res;
1202
	mems->bases = gres ;
1260
		mems->bases = gres;
1203
	return ;
1261
		return;
-
 
1262
	}
-
 
1263
 
-
 
1264
	/* Search derived class */
-
 
1265
	if (depth) {
-
 
1266
		CLASS_TYPE ct = DEREF_ctype(graph_head(gr));
-
 
1267
		if (IS_NULL_ctype(cs) || eq_ctype(ct, cs)) {
-
 
1268
			NAMESPACE ns = DEREF_nspace(ctype_member(ct));
-
 
1269
			IDENTIFIER id = search_id(ns, nm, 0, type);
-
 
1270
			if (!IS_NULL_id(id)) {
-
 
1271
				DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
1272
				if ((ds & dspec_inherit) &&
-
 
1273
				    !(ds & dspec_alias)) {
-
 
1274
					/* Ignore inherited members */
-
 
1275
					/* EMPTY */
-
 
1276
				} else {
-
 
1277
					CONS_id(id, res, res);
-
 
1278
					CONS_graph(gr, gres, gres);
-
 
1279
					mems->ids = res;
-
 
1280
					mems->bases = gres;
-
 
1281
					return;
1204
    }
1282
				}
-
 
1283
			}
-
 
1284
			cs = NULL_ctype;
-
 
1285
		}
-
 
1286
	}
1205
 
1287
 
1206
    /* Search derived class */
1288
	/* Search base classes */
1207
    if ( depth ) {
-
 
1208
	CLASS_TYPE ct = DEREF_ctype ( graph_head ( gr ) ) ;
1289
	br = DEREF_list(graph_tails(gr));
1209
	if ( IS_NULL_ctype ( cs ) || eq_ctype ( ct, cs ) ) {
1290
	while (!IS_NULL_list(br)) {
1210
	    NAMESPACE ns = DEREF_nspace ( ctype_member ( ct ) ) ;
-
 
1211
	    IDENTIFIER id = search_id ( ns, nm, 0, type ) ;
-
 
1212
	    if ( !IS_NULL_id ( id ) ) {
1291
		MEMBER_LOOKUP bmems;
1213
		DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
1292
		GRAPH gs = DEREF_graph(HEAD_list(br));
1214
		if ( ( ds & dspec_inherit ) && !( ds & dspec_alias ) ) {
1293
		search_base(gs, nm, &bmems, cs, type, depth + 1);
1215
		    /* Ignore inherited members */
1294
		if (!IS_NULL_list(bmems.ids)) {
1216
		    /* EMPTY */
-
 
1217
		} else {
-
 
1218
		    CONS_id ( id, res, res ) ;
1295
			res = APPEND_list(res, bmems.ids);
1219
		    CONS_graph ( gr, gres, gres ) ;
1296
			gres = APPEND_list(gres, bmems.bases);
1220
		    mems->ids = res ;
-
 
1221
		    mems->bases = gres ;
-
 
1222
		    return ;
-
 
1223
		}
1297
		}
1224
	    }
-
 
1225
	    cs = NULL_ctype ;
1298
		br = TAIL_list(br);
1226
	}
1299
	}
1227
    }
-
 
1228
 
-
 
1229
    /* Search base classes */
-
 
1230
    br = DEREF_list ( graph_tails ( gr ) ) ;
-
 
1231
    while ( !IS_NULL_list ( br ) ) {
-
 
1232
	MEMBER_LOOKUP bmems ;
-
 
1233
	GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
-
 
1234
	search_base ( gs, nm, &bmems, cs, type, depth + 1 ) ;
-
 
1235
	if ( !IS_NULL_list ( bmems.ids ) ) {
-
 
1236
	    res = APPEND_list ( res, bmems.ids ) ;
-
 
1237
	    gres = APPEND_list ( gres, bmems.bases ) ;
-
 
1238
	}
-
 
1239
	br = TAIL_list ( br ) ;
-
 
1240
    }
-
 
1241
    mems->ids = res ;
1300
	mems->ids = res;
1242
    mems->bases = gres ;
1301
	mems->bases = gres;
1243
    return ;
1302
	return;
1244
}
1303
}
1245
 
1304
 
1246
 
1305
 
1247
/*
1306
/*
1248
    SEARCH BASE CLASSES FOR A CLASS MEMBER
1307
    SEARCH BASE CLASSES FOR A CLASS MEMBER
1249
 
1308
 
1250
    This routine searches the base classes of the class namespace ns
1309
    This routine searches the base classes of the class namespace ns
1251
    for a member named nm.
1310
    for a member named nm.
1252
*/
1311
*/
1253
 
1312
 
1254
IDENTIFIER search_base_field
1313
IDENTIFIER
1255
    PROTO_N ( ( ns, nm, type, dominate ) )
-
 
1256
    PROTO_T ( NAMESPACE ns X HASHID nm X int type X int dominate )
1314
search_base_field(NAMESPACE ns, HASHID nm, int type, int dominate)
1257
{
1315
{
1258
    GRAPH gr ;
1316
	GRAPH gr;
1259
    IDENTIFIER id ;
1317
	IDENTIFIER id;
1260
    CLASS_TYPE ct ;
1318
	CLASS_TYPE ct;
1261
    MEMBER_LOOKUP mems ;
1319
	MEMBER_LOOKUP mems;
1262
    IDENTIFIER cid = DEREF_id ( nspace_name ( ns ) ) ;
1320
	IDENTIFIER cid = DEREF_id(nspace_name(ns));
1263
    TYPE t = DEREF_type ( id_class_name_etc_defn ( cid ) ) ;
1321
	TYPE t = DEREF_type(id_class_name_etc_defn(cid));
1264
    while ( IS_type_templ ( t ) ) {
1322
	while (IS_type_templ(t)) {
1265
	t = DEREF_type ( type_templ_defn ( t ) ) ;
1323
		t = DEREF_type(type_templ_defn(t));
1266
    }
1324
	}
1267
    ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
1325
	ct = DEREF_ctype(type_compound_defn(t));
1268
    gr = DEREF_graph ( ctype_base ( ct ) ) ;
1326
	gr = DEREF_graph(ctype_base(ct));
1269
    search_base ( gr, nm, &mems, NULL_ctype, type, 0 ) ;
1327
	search_base(gr, nm, &mems, NULL_ctype, type, 0);
1270
    id = resolve_member ( ns, nm, &mems, NULL_type, dominate ) ;
1328
	id = resolve_member(ns, nm, &mems, NULL_type, dominate);
1271
    return ( id ) ;
1329
	return (id);
1272
}
1330
}
1273
 
1331
 
1274
 
1332
 
1275
/*
1333
/*
1276
    SEARCH FOR A CLASS MEMBER
1334
    SEARCH FOR A CLASS MEMBER
Line 1278... Line 1336...
1278
    This routine searches the class namespace ns and its base classes
1336
    This routine searches the class namespace ns and its base classes
1279
    for a member named nm, which is returned if found.  Otherwise if
1337
    for a member named nm, which is returned if found.  Otherwise if
1280
    create is true then a dummy identifier is created and returned.
1338
    create is true then a dummy identifier is created and returned.
1281
    Otherwise the null identifier is returned.  If type is true then only
1339
    Otherwise the null identifier is returned.  If type is true then only
1282
    type and namespace names are considered.
1340
    type and namespace names are considered.
1283
*/
1341
*/
1284
 
1342
 
1285
IDENTIFIER search_field
1343
IDENTIFIER
1286
    PROTO_N ( ( ns, nm, create, type ) )
-
 
1287
    PROTO_T ( NAMESPACE ns X HASHID nm X int create X int type )
1344
search_field(NAMESPACE ns, HASHID nm, int create, int type)
1288
{
1345
{
1289
    /* Search main class */
1346
	/* Search main class */
1290
    IDENTIFIER id ;
1347
	IDENTIFIER id;
1291
    MEMBER mem = search_member ( ns, nm, 1 ) ;
1348
	MEMBER mem = search_member(ns, nm, 1);
1292
    if ( type ) {
1349
	if (type) {
1293
	id = type_member ( mem, type ) ;
1350
		id = type_member(mem, type);
1294
    } else {
-
 
1295
	id = DEREF_id ( member_id ( mem ) ) ;
-
 
1296
    }
-
 
1297
 
-
 
1298
    /* Search base classes */
-
 
1299
    if ( IS_NULL_id ( id ) ) {
-
 
1300
	id = search_base_field ( ns, nm, type, 1 ) ;
-
 
1301
	if ( !IS_NULL_id ( id ) ) {
-
 
1302
	    if ( type ) {
-
 
1303
		set_type_member ( mem, id ) ;
-
 
1304
	    } else {
-
 
1305
		set_member ( mem, id ) ;
-
 
1306
	    }
-
 
1307
	    if ( IS_hashid_destr ( nm ) ) {
-
 
1308
		/* Check destructor names */
-
 
1309
		report ( crt_loc, ERR_class_dtor_inherit ( nm, ns ) ) ;
-
 
1310
	    }
-
 
1311
	} else {
1351
	} else {
-
 
1352
		id = DEREF_id(member_id(mem));
-
 
1353
	}
-
 
1354
 
-
 
1355
	/* Search base classes */
-
 
1356
	if (IS_NULL_id(id)) {
-
 
1357
		id = search_base_field(ns, nm, type, 1);
-
 
1358
		if (!IS_NULL_id(id)) {
-
 
1359
			if (type) {
-
 
1360
				set_type_member(mem, id);
-
 
1361
			} else {
-
 
1362
				set_member(mem, id);
-
 
1363
			}
-
 
1364
			if (IS_hashid_destr(nm)) {
-
 
1365
				/* Check destructor names */
-
 
1366
				report(crt_loc, ERR_class_dtor_inherit(nm, ns));
-
 
1367
			}
-
 
1368
		} else {
1312
	    if ( create ) {
1369
			if (create) {
1313
		/* Create dummy identifier if necessary */
1370
				/* Create dummy identifier if necessary */
1314
		MAKE_id_undef ( nm, dspec_none, ns, crt_loc, id ) ;
1371
				MAKE_id_undef(nm, dspec_none, ns, crt_loc, id);
1315
	    }
1372
			}
1316
	    if ( IS_hashid_destr ( nm ) ) {
1373
			if (IS_hashid_destr(nm)) {
1317
		/* Check destructor names */
1374
				/* Check destructor names */
1318
		TYPE s = DEREF_type ( hashid_destr_type ( nm ) ) ;
1375
				TYPE s = DEREF_type(hashid_destr_type(nm));
1319
		IDENTIFIER tid = DEREF_id ( nspace_name ( ns ) ) ;
1376
				IDENTIFIER tid = DEREF_id(nspace_name(ns));
-
 
1377
				TYPE t =
1320
		TYPE t = DEREF_type ( id_class_name_etc_defn ( tid ) ) ;
1378
				    DEREF_type(id_class_name_etc_defn(tid));
1321
		if ( !eq_type ( s, t ) ) {
1379
				if (!eq_type(s, t)) {
-
 
1380
					report(crt_loc,
1322
		    report ( crt_loc, ERR_expr_pseudo_type ( t, s ) ) ;
1381
					       ERR_expr_pseudo_type(t, s));
1323
		}
1382
				}
1324
	    }
1383
			}
1325
	}
1384
		}
1326
    }
1385
	}
1327
    return ( id ) ;
1386
	return (id);
1328
}
1387
}
1329
 
1388
 
1330
 
1389
 
1331
/*
1390
/*
1332
    IS AN IDENTIFIER A MEMBER OF A CLASS?
1391
    IS AN IDENTIFIER A MEMBER OF A CLASS?
1333
 
1392
 
1334
    This routine checks whether the identifier id is a member of the class
1393
    This routine checks whether the identifier id is a member of the class
1335
    namespace ns or any base class of ns.  It returns the corresponding
1394
    namespace ns or any base class of ns.  It returns the corresponding
1336
    base class graph, or the null graph if id is not such a member.
1395
    base class graph, or the null graph if id is not such a member.
1337
*/
1396
*/
1338
 
1397
 
1339
GRAPH is_subfield
1398
GRAPH
1340
    PROTO_N ( ( ns, id ) )
-
 
1341
    PROTO_T ( NAMESPACE ns X IDENTIFIER id )
1399
is_subfield(NAMESPACE ns, IDENTIFIER id)
1342
{
1400
{
1343
    CLASS_TYPE ct = namespace_class ( ns ) ;
1401
	CLASS_TYPE ct = namespace_class(ns);
1344
    if ( !IS_NULL_ctype ( ct ) ) {
1402
	if (!IS_NULL_ctype(ct)) {
1345
	NAMESPACE cns = DEREF_nspace ( id_parent ( id ) ) ;
1403
		NAMESPACE cns = DEREF_nspace(id_parent(id));
1346
	if ( !IS_NULL_nspace ( cns ) && IS_nspace_ctype ( cns ) ) {
1404
		if (!IS_NULL_nspace(cns) && IS_nspace_ctype(cns)) {
1347
	    CLASS_TYPE cs = namespace_class ( cns ) ;
1405
			CLASS_TYPE cs = namespace_class(cns);
1348
	    GRAPH gr = find_base_class ( ct, cs, 0 ) ;
1406
			GRAPH gr = find_base_class(ct, cs, 0);
1349
	    return ( gr ) ;
1407
			return (gr);
1350
	}
1408
		}
1351
    }
1409
	}
1352
    return ( NULL_graph ) ;
1410
	return (NULL_graph);
1353
}
1411
}
1354
 
1412
 
1355
 
1413
 
1356
/*
1414
/*
1357
    SEARCH FOR A SUBFIELD
1415
    SEARCH FOR A SUBFIELD
1358
 
1416
 
1359
    This routine finds the member of a class corresponding to the member
1417
    This routine finds the member of a class corresponding to the member
1360
    id of the base class of ns indicated by gr.
1418
    id of the base class of ns indicated by gr.
1361
*/
1419
*/
1362
 
1420
 
1363
IDENTIFIER search_subfield
1421
IDENTIFIER
1364
    PROTO_N ( ( ns, gr, id ) )
-
 
1365
    PROTO_T ( NAMESPACE ns X GRAPH gr X IDENTIFIER id )
1422
search_subfield(NAMESPACE ns, GRAPH gr, IDENTIFIER id)
1366
{
1423
{
1367
    GRAPH gt = DEREF_graph ( graph_top ( gr ) ) ;
1424
	GRAPH gt = DEREF_graph(graph_top(gr));
1368
    if ( !EQ_graph ( gr, gt ) ) {
1425
	if (!EQ_graph(gr, gt)) {
1369
	int def = 0 ;
1426
		int def = 0;
1370
	IDENTIFIER pid ;
1427
		IDENTIFIER pid;
1371
	MEMBER_LOOKUP mems ;
1428
		MEMBER_LOOKUP mems;
1372
	TYPE form = find_form ( id, &def ) ;
1429
		TYPE form = find_form(id, &def);
1373
	HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1430
		HASHID nm = DEREF_hashid(id_name(id));
1374
	DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
1431
		DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1375
	if ( acc & dspec_alias ) {
1432
		if (acc & dspec_alias) {
1376
	    /* Ambiguous base class */
1433
			/* Ambiguous base class */
1377
	    CLASS_TYPE cs = DEREF_ctype ( graph_head ( gr ) ) ;
1434
			CLASS_TYPE cs = DEREF_ctype(graph_head(gr));
1378
	    search_base ( gt, nm, &mems, cs, 0, 1 ) ;
1435
			search_base(gt, nm, &mems, cs, 0, 1);
1379
	} else {
1436
		} else {
1380
	    /* Unambiguous base class */
1437
			/* Unambiguous base class */
1381
	    search_base ( gr, nm, &mems, NULL_ctype, 0, 1 ) ;
1438
			search_base(gr, nm, &mems, NULL_ctype, 0, 1);
-
 
1439
		}
-
 
1440
		pid = resolve_member(ns, nm, &mems, form, 1);
-
 
1441
		if (!IS_NULL_id(pid)) {
-
 
1442
			id = pid;
-
 
1443
		}
1382
	}
1444
	}
1383
	pid = resolve_member ( ns, nm, &mems, form, 1 ) ;
-
 
1384
	if ( !IS_NULL_id ( pid ) ) id = pid ;
-
 
1385
    }
-
 
1386
    return ( id ) ;
1445
	return (id);
1387
}
1446
}
1388
 
1447
 
1389
 
1448
 
1390
/*
1449
/*
1391
    PROCESS INHERITANCE FOR A CLASS
1450
    PROCESS INHERITANCE FOR A CLASS
1392
 
1451
 
1393
    This routine is called at the end of a class definition to handle
1452
    This routine is called at the end of a class definition to handle
1394
    any inheritance issues.  At present an inherited member is only
1453
    any inheritance issues.  At present an inherited member is only
1395
    recorded as it is looked up.  However the lists of all virtual
1454
    recorded as it is looked up.  However the lists of all virtual
1396
    functions and conversion functions on the class need to take account
1455
    functions and conversion functions on the class need to take account
1397
    of inheritance immediately.
1456
    of inheritance immediately.
1398
*/
1457
*/
1399
 
1458
 
1400
void inherit_class
1459
void
1401
    PROTO_Z ()
1460
inherit_class(void)
1402
{
1461
{
1403
    CLASS_TYPE ct = crt_class ;
1462
	CLASS_TYPE ct = crt_class;
1404
    NAMESPACE ns = crt_namespace ;
1463
	NAMESPACE ns = crt_namespace;
1405
    GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
1464
	GRAPH gr = DEREF_graph(ctype_base(ct));
1406
    LIST ( GRAPH ) bases = DEREF_list ( graph_tails ( gr ) ) ;
1465
	LIST(GRAPH)bases = DEREF_list(graph_tails(gr));
1407
    LIST ( IDENTIFIER ) pc = DEREF_list ( ctype_conv ( ct ) ) ;
1466
	LIST(IDENTIFIER)pc = DEREF_list(ctype_conv(ct));
1408
 
1467
 
1409
    /* Scan through base classes */
1468
	/* Scan through base classes */
1410
    while ( !IS_NULL_list ( bases ) ) {
1469
	while (!IS_NULL_list(bases)) {
1411
	GRAPH gs = DEREF_graph ( HEAD_list ( bases ) ) ;
1470
		GRAPH gs = DEREF_graph(HEAD_list(bases));
1412
	CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
1471
		CLASS_TYPE cs = DEREF_ctype(graph_head(gs));
1413
 
1472
 
1414
	/* Deal with conversion functions */
1473
		/* Deal with conversion functions */
1415
	LIST ( IDENTIFIER ) qc = DEREF_list ( ctype_conv ( cs ) ) ;
1474
		LIST(IDENTIFIER)qc = DEREF_list(ctype_conv(cs));
1416
	while ( !IS_NULL_list ( qc ) ) {
1475
		while (!IS_NULL_list(qc)) {
1417
	    /* Deal with each inherited conversion */
1476
			/* Deal with each inherited conversion */
1418
	    IDENTIFIER qid = DEREF_id ( HEAD_list ( qc ) ) ;
1477
			IDENTIFIER qid = DEREF_id(HEAD_list(qc));
1419
	    HASHID qnm = DEREF_hashid ( id_name ( qid ) ) ;
1478
			HASHID qnm = DEREF_hashid(id_name(qid));
1420
	    LIST ( IDENTIFIER ) r = pc ;
1479
			LIST(IDENTIFIER)r = pc;
1421
	    while ( !IS_NULL_list ( r ) ) {
1480
			while (!IS_NULL_list(r)) {
1422
		/* Check whether already declared */
1481
				/* Check whether already declared */
1423
		IDENTIFIER rid = DEREF_id ( HEAD_list ( r ) ) ;
1482
				IDENTIFIER rid = DEREF_id(HEAD_list(r));
1424
		HASHID rnm = DEREF_hashid ( id_name ( rid ) ) ;
1483
				HASHID rnm = DEREF_hashid(id_name(rid));
1425
		if ( EQ_hashid ( rnm, qnm ) ) break ;
1484
				if (EQ_hashid(rnm, qnm)) {
1426
		r = TAIL_list ( r ) ;
1485
					break;
1427
	    }
1486
				}
1428
	    if ( IS_NULL_list ( r ) ) {
-
 
1429
		/* Construct inherited member */
-
 
1430
		qid = search_field ( ns, qnm, 0, 0 ) ;
-
 
1431
		if ( !IS_NULL_id ( qid ) ) {
-
 
1432
		    if ( IS_id_ambig ( qid ) ) {
-
 
1433
			LIST ( IDENTIFIER ) qids ;
-
 
1434
			qids = DEREF_list ( id_ambig_ids ( qid ) ) ;
-
 
1435
			while ( !IS_NULL_list ( qids ) ) {
-
 
1436
			    qid = DEREF_id ( HEAD_list ( qids ) ) ;
-
 
1437
			    CONS_id ( qid, pc, pc ) ;
-
 
1438
			    qids = TAIL_list ( qids ) ;
1487
				r = TAIL_list(r);
1439
			}
1488
			}
-
 
1489
			if (IS_NULL_list(r)) {
-
 
1490
				/* Construct inherited member */
-
 
1491
				qid = search_field(ns, qnm, 0, 0);
-
 
1492
				if (!IS_NULL_id(qid)) {
-
 
1493
					if (IS_id_ambig(qid)) {
-
 
1494
						LIST(IDENTIFIER)qids;
-
 
1495
						qids = DEREF_list(id_ambig_ids(qid));
-
 
1496
						while (!IS_NULL_list(qids)) {
-
 
1497
							qid = DEREF_id(HEAD_list(qids));
-
 
1498
							CONS_id(qid, pc, pc);
-
 
1499
							qids = TAIL_list(qids);
-
 
1500
						}
1440
		    } else {
1501
					} else {
1441
			CONS_id ( qid, pc, pc ) ;
1502
						CONS_id(qid, pc, pc);
1442
		    }
1503
					}
-
 
1504
				}
-
 
1505
			}
-
 
1506
			qc = TAIL_list(qc);
1443
		}
1507
		}
1444
	    }
-
 
1445
	    qc = TAIL_list ( qc ) ;
-
 
1446
	}
-
 
1447
 
1508
 
1448
	/* Process next base class */
1509
		/* Process next base class */
1449
	bases = TAIL_list ( bases ) ;
1510
		bases = TAIL_list(bases);
1450
    }
1511
	}
1451
 
1512
 
1452
    /* Record modified information */
1513
	/* Record modified information */
1453
    COPY_list ( ctype_conv ( ct ), pc ) ;
1514
	COPY_list(ctype_conv(ct), pc);
1454
 
1515
 
1455
    /* Deal with virtual functions */
1516
	/* Deal with virtual functions */
1456
    end_virtual ( ct ) ;
1517
	end_virtual(ct);
1457
    return ;
1518
	return;
1458
}
1519
}