Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /trunk/src/producers/common/construct/member.c – Rev 2 and 7

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 73... Line 103...
73
 
103
 
74
    This routine forms the address of the expression e.  If e is not an
104
    This routine forms the address of the expression e.  If e is not an
75
    lvalue then a temporary is introduced and its address is returned.
105
    lvalue then a temporary is introduced and its address is returned.
76
*/
106
*/
77
 
107
 
78
static EXP member_address
108
static EXP
79
    PROTO_N ( ( e ) )
-
 
80
    PROTO_T ( EXP e )
109
member_address(EXP e)
81
{
110
{
82
    TYPE t = DEREF_type ( exp_type ( e ) ) ;
111
	TYPE t = DEREF_type(exp_type(e));
83
    CV_SPEC qual = DEREF_cv ( type_qual ( t ) ) ;
112
	CV_SPEC qual = DEREF_cv(type_qual(t));
84
    if ( qual & cv_lvalue ) {
113
	if (qual & cv_lvalue) {
85
	t = rvalue_type ( t ) ;
114
		t = rvalue_type(t);
86
    } else {
115
	} else {
87
	ERROR err = NULL_err ;
116
		ERROR err = NULL_err;
88
	e = make_temporary ( t, e, NULL_exp, 0, &err ) ;
117
		e = make_temporary(t, e, NULL_exp, 0, &err);
89
	if ( !IS_NULL_err ( err ) ) report ( crt_loc, err ) ;
118
		if (!IS_NULL_err(err)) {
-
 
119
			report(crt_loc, err);
90
    }
120
		}
-
 
121
	}
91
    MAKE_type_ptr ( cv_none, t, t ) ;
122
	MAKE_type_ptr(cv_none, t, t);
92
    MAKE_exp_address ( t, e, e ) ;
123
	MAKE_exp_address(t, e, e);
93
    return ( e ) ;
124
	return (e);
94
}
125
}
95
 
126
 
96
 
127
 
97
/*
128
/*
98
    BEGIN A FIELD SELECTOR EXPRESSION
129
    BEGIN A FIELD SELECTOR EXPRESSION
Line 104... Line 135...
104
    explicit destructor notation can apply to any type.  Note that '->'
135
    explicit destructor notation can apply to any type.  Note that '->'
105
    can be overloaded (albeit in a different way to most other operations)
136
    can be overloaded (albeit in a different way to most other operations)
106
    but '.' can't.
137
    but '.' can't.
107
*/
138
*/
108
 
139
 
109
EXP begin_field_exp
140
EXP
110
    PROTO_N ( ( op, a, pt, pns ) )
-
 
111
    PROTO_T ( int op X EXP a X TYPE *pt X NAMESPACE *pns )
141
begin_field_exp(int op, EXP a, TYPE *pt, NAMESPACE *pns)
112
{
142
{
113
    TYPE t, s ;
143
	TYPE t, s;
114
    unsigned c ;
144
	unsigned c;
115
    int ptr = 0 ;
145
	int ptr = 0;
116
    unsigned tag ;
146
	unsigned tag;
117
 
147
 
118
    /* Do operand conversion */
148
	/* Do operand conversion */
119
    if ( op == lex_arrow ) {
149
	if (op == lex_arrow) {
120
	/* Check for overloading with '->' */
150
		/* Check for overloading with '->' */
121
#if LANGUAGE_CPP
151
#if LANGUAGE_CPP
122
	int go = 1 ;
152
		int go = 1;
123
	LIST ( TYPE ) prev = NULL_list ( TYPE ) ;
153
		LIST(TYPE) prev = NULL_list(TYPE);
124
	do {
154
		do {
125
	    /* Perform reference conversions */
155
			/* Perform reference conversions */
126
	    a = convert_reference ( a, REF_NORMAL ) ;
156
			a = convert_reference(a, REF_NORMAL);
127
	    t = DEREF_type ( exp_type ( a ) ) ;
157
			t = DEREF_type(exp_type(a));
128
	    c = type_category ( &t ) ;
158
			c = type_category(&t);
129
	    if ( overload_depth ) break ;
159
			if (overload_depth) {
130
	    if ( IS_TYPE_TEMPL ( c ) ) {
-
 
131
		/* Template parameter type */
-
 
132
		EXP e ;
-
 
133
		MAKE_exp_op ( t, op, a, a, e ) ;
-
 
134
		cache_lookup = 0 ;
-
 
135
		*pns = NULL_nspace ;
-
 
136
		*pt = t ;
-
 
137
		return ( e ) ;
-
 
138
	    }
-
 
139
	    if ( IS_TYPE_OVERLOAD ( c ) ) {
-
 
140
		EXP e = unary_overload ( lex_arrow, a ) ;
-
 
141
		if ( IS_NULL_exp ( e ) ) {
-
 
142
		    /* '->' isn't overloaded */
-
 
143
		    go = 0 ;
-
 
144
		} else {
-
 
145
		    /* '->' is overloaded, try again */
-
 
146
		    LIST ( TYPE ) p = prev ;
-
 
147
		    while ( !IS_NULL_list ( p ) ) {
-
 
148
			/* Check for cycles */
-
 
149
			s = DEREF_type ( HEAD_list ( p ) ) ;
-
 
150
			if ( eq_type ( s, t ) ) {
-
 
151
			    ERROR err = ERR_over_match_oper_arrow () ;
-
 
152
			    report ( crt_loc, err ) ;
-
 
153
			    go = 0 ;
-
 
154
			    break ;
160
				break;
155
			}
161
			}
-
 
162
			if (IS_TYPE_TEMPL(c)) {
-
 
163
				/* Template parameter type */
-
 
164
				EXP e;
-
 
165
				MAKE_exp_op(t, op, a, a, e);
-
 
166
				cache_lookup = 0;
-
 
167
				*pns = NULL_nspace;
-
 
168
				*pt = t;
-
 
169
				return (e);
-
 
170
			}
-
 
171
			if (IS_TYPE_OVERLOAD(c)) {
-
 
172
				EXP e = unary_overload(lex_arrow, a);
-
 
173
				if (IS_NULL_exp(e)) {
-
 
174
					/* '->' isn't overloaded */
-
 
175
					go = 0;
-
 
176
				} else {
-
 
177
					/* '->' is overloaded, try again */
-
 
178
					LIST(TYPE) p = prev;
-
 
179
					while (!IS_NULL_list(p)) {
-
 
180
						/* Check for cycles */
-
 
181
						s = DEREF_type(HEAD_list(p));
-
 
182
						if (eq_type(s, t)) {
-
 
183
							ERROR err = ERR_over_match_oper_arrow();
-
 
184
							report(crt_loc, err);
-
 
185
							go = 0;
-
 
186
							break;
-
 
187
						}
156
			p = TAIL_list ( p ) ;
188
						p = TAIL_list(p);
157
		    }
189
					}
158
		    CONS_type ( t, prev, prev ) ;
190
					CONS_type(t, prev, prev);
159
		    a = e ;
191
					a = e;
160
		}
192
				}
161
	    } else {
193
			} else {
162
		/* '->' can't be overloaded */
194
				/* '->' can't be overloaded */
163
		go = 0 ;
195
				go = 0;
164
	    }
196
			}
165
	} while ( go ) ;
197
		} while (go);
166
	DESTROY_list ( prev, SIZE_type ) ;
198
		DESTROY_list(prev, SIZE_type);
167
#else
199
#else
168
	/* Perform reference conversions */
200
		/* Perform reference conversions */
169
	a = convert_reference ( a, REF_NORMAL ) ;
201
		a = convert_reference(a, REF_NORMAL);
170
	t = DEREF_type ( exp_type ( a ) ) ;
202
		t = DEREF_type(exp_type(a));
171
	c = type_category ( &t ) ;
203
		c = type_category(&t);
172
#endif
204
#endif
173
 
205
 
174
	/* Do lvalue conversions if necessary */
206
		/* Do lvalue conversions if necessary */
175
	if ( IS_TYPE_ADDRESS ( c ) ) {
207
		if (IS_TYPE_ADDRESS(c)) {
176
	    a = convert_lvalue ( a ) ;
208
			a = convert_lvalue(a);
177
	    t = DEREF_type ( exp_type ( a ) ) ;
209
			t = DEREF_type(exp_type(a));
178
	}
210
		}
179
    } else {
211
	} else {
180
	/* For '.' just do reference conversions */
212
		/* For '.' just do reference conversions */
181
	a = convert_reference ( a, REF_NORMAL ) ;
213
		a = convert_reference(a, REF_NORMAL);
182
	t = DEREF_type ( exp_type ( a ) ) ;
214
		t = DEREF_type(exp_type(a));
183
#if LANGUAGE_CPP
215
#if LANGUAGE_CPP
184
	c = type_category ( &t ) ;
216
		c = type_category(&t);
185
	if ( IS_TYPE_TEMPL ( c ) ) {
217
		if (IS_TYPE_TEMPL(c)) {
186
	    /* Template parameter type */
218
			/* Template parameter type */
187
	    EXP e ;
219
			EXP e;
188
	    MAKE_exp_op ( t, op, a, a, e ) ;
220
			MAKE_exp_op(t, op, a, a, e);
189
	    cache_lookup = 0 ;
221
			cache_lookup = 0;
190
	    *pns = NULL_nspace ;
222
			*pns = NULL_nspace;
191
	    *pt = t ;
223
			*pt = t;
192
	    return ( e ) ;
224
			return (e);
193
	}
225
		}
194
#endif
226
#endif
195
    }
-
 
196
 
-
 
197
    /* Check operand type */
-
 
198
    tag = TAG_type ( t ) ;
-
 
199
    if ( tag == type_token_tag ) {
-
 
200
	t = expand_type ( t, 0 ) ;
-
 
201
	tag = TAG_type ( t ) ;
-
 
202
    }
-
 
203
    if ( tag == type_ptr_tag ) {
-
 
204
	s = DEREF_type ( type_ptr_sub ( t ) ) ;
-
 
205
	tag = TAG_type ( s ) ;
-
 
206
	if ( tag == type_token_tag ) {
-
 
207
	    if ( op == lex_arrow && is_templ_type ( s ) ) {
-
 
208
		/* Template parameter type */
-
 
209
		EXP e ;
-
 
210
		MAKE_exp_op ( s, op, a, a, e ) ;
-
 
211
		cache_lookup = 0 ;
-
 
212
		*pns = NULL_nspace ;
-
 
213
		*pt = s ;
-
 
214
		return ( e ) ;
-
 
215
	    }
-
 
216
	    s = expand_type ( s, 0 ) ;
-
 
217
	    tag = TAG_type ( s ) ;
-
 
218
	}
-
 
219
	ptr = 1 ;
-
 
220
    } else {
-
 
221
	s = t ;
-
 
222
    }
-
 
223
    if ( tag == type_compound_tag ) {
-
 
224
	/* Operand is a class or a pointer to a class */
-
 
225
	ERROR err ;
-
 
226
	CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( s ) ) ;
-
 
227
	NAMESPACE ns = DEREF_nspace ( ctype_member ( ct ) ) ;
-
 
228
 
-
 
229
	/* Check that the correct operator has been used */
-
 
230
	if ( op == lex_arrow ) {
-
 
231
	    if ( !ptr ) report ( crt_loc, ERR_expr_ref_arrow_dot ( t ) ) ;
-
 
232
	} else {
-
 
233
	    if ( ptr ) report ( crt_loc, ERR_expr_ref_dot_arrow ( t ) ) ;
-
 
234
	}
-
 
235
 
-
 
236
	/* Check that the class is complete */
-
 
237
	err = check_incomplete ( s ) ;
-
 
238
	cache_lookup = 0 ;
-
 
239
	if ( !IS_NULL_err ( err ) ) {
-
 
240
	    /* Incomplete class */
-
 
241
	    BASE_TYPE key = find_class_key ( ct ) ;
-
 
242
	    err = concat_error ( err, ERR_expr_ref_incompl ( op, key ) ) ;
-
 
243
	    report ( crt_loc, err ) ;
-
 
244
	    ns = NULL_nspace ;
-
 
245
	    s = type_error ;
-
 
246
	} else {
-
 
247
	    /* Complete class */
-
 
248
	    add_namespace ( ns ) ;
-
 
249
	}
-
 
250
	*pns = ns ;
-
 
251
	*pt = s ;
-
 
252
 
-
 
253
	/* Check for null pointers */
-
 
254
	if ( IS_exp_null ( a ) && ptr ) {
-
 
255
	    report ( crt_loc, ERR_expr_unary_op_indir_null ( op ) ) ;
-
 
256
	}
227
	}
257
 
228
 
-
 
229
	/* Check operand type */
-
 
230
	tag = TAG_type(t);
-
 
231
	if (tag == type_token_tag) {
-
 
232
		t = expand_type(t, 0);
-
 
233
		tag = TAG_type(t);
-
 
234
	}
-
 
235
	if (tag == type_ptr_tag) {
-
 
236
		s = DEREF_type(type_ptr_sub(t));
-
 
237
		tag = TAG_type(s);
-
 
238
		if (tag == type_token_tag) {
-
 
239
			if (op == lex_arrow && is_templ_type(s)) {
-
 
240
				/* Template parameter type */
-
 
241
				EXP e;
-
 
242
				MAKE_exp_op(s, op, a, a, e);
-
 
243
				cache_lookup = 0;
-
 
244
				*pns = NULL_nspace;
-
 
245
				*pt = s;
-
 
246
				return (e);
-
 
247
			}
-
 
248
			s = expand_type(s, 0);
-
 
249
			tag = TAG_type(s);
-
 
250
		}
-
 
251
		ptr = 1;
-
 
252
	} else {
-
 
253
		s = t;
-
 
254
	}
-
 
255
	if (tag == type_compound_tag) {
-
 
256
		/* Operand is a class or a pointer to a class */
-
 
257
		ERROR err;
-
 
258
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(s));
-
 
259
		NAMESPACE ns = DEREF_nspace(ctype_member(ct));
-
 
260
 
-
 
261
		/* Check that the correct operator has been used */
-
 
262
		if (op == lex_arrow) {
-
 
263
			if (!ptr) {
-
 
264
				report(crt_loc, ERR_expr_ref_arrow_dot(t));
-
 
265
			}
-
 
266
		} else {
-
 
267
			if (ptr) {
-
 
268
				report(crt_loc, ERR_expr_ref_dot_arrow(t));
-
 
269
			}
-
 
270
		}
-
 
271
 
-
 
272
		/* Check that the class is complete */
-
 
273
		err = check_incomplete(s);
-
 
274
		cache_lookup = 0;
-
 
275
		if (!IS_NULL_err(err)) {
-
 
276
			/* Incomplete class */
-
 
277
			BASE_TYPE key = find_class_key(ct);
-
 
278
			err = concat_error(err, ERR_expr_ref_incompl(op, key));
-
 
279
			report(crt_loc, err);
-
 
280
			ns = NULL_nspace;
-
 
281
			s = type_error;
258
    } else {
282
		} else {
-
 
283
			/* Complete class */
-
 
284
			add_namespace(ns);
-
 
285
		}
-
 
286
		*pns = ns;
-
 
287
		*pt = s;
-
 
288
 
-
 
289
		/* Check for null pointers */
-
 
290
		if (IS_exp_null(a) && ptr) {
-
 
291
			report(crt_loc, ERR_expr_unary_op_indir_null(op));
-
 
292
		}
-
 
293
	} else {
259
	/* Bad operand type */
294
		/* Bad operand type */
260
	if ( !IS_type_error ( s ) ) {
295
		if (!IS_type_error(s)) {
261
	    if ( op == lex_arrow ) {
296
			if (op == lex_arrow) {
262
		if ( !ptr ) {
297
				if (!ptr) {
263
		    string key = find_vocab ( lex_class ) ;
298
					string key = find_vocab(lex_class);
-
 
299
					report(crt_loc,
264
		    report ( crt_loc, ERR_expr_ref_arrow_op ( t, key ) ) ;
300
					       ERR_expr_ref_arrow_op(t, key));
265
		    s = type_error ;
301
					s = type_error;
-
 
302
				}
-
 
303
			} else {
-
 
304
				s = t;
-
 
305
			}
266
		}
306
		}
267
	    } else {
307
		cache_lookup = 0;
268
		s = t ;
308
		*pns = NULL_nspace;
269
	    }
309
		*pt = s;
270
	}
310
	}
271
	cache_lookup = 0 ;
-
 
272
	*pns = NULL_nspace ;
-
 
273
	*pt = s ;
-
 
274
    }
-
 
275
    return ( a ) ;
311
	return (a);
276
}
312
}
277
 
313
 
278
 
314
 
279
/*
315
/*
280
    CREATE A FIELD SELECTOR EXPRESSION
316
    CREATE A FIELD SELECTOR EXPRESSION
281
 
317
 
282
    This routine completes the field selector expression constructed by
318
    This routine completes the field selector expression constructed by
283
    begin_field_exp.  The a arguments is the outputs of this routine,
319
    begin_field_exp.  The a arguments is the outputs of this routine,
284
    ns represents the class namespace of the type of a, op indicated which
320
    ns represents the class namespace of the type of a, op indicated which
285
    selector is being used, and fld indicates the field being selected.
321
    selector is being used, and fld indicates the field being selected.
286
*/
322
*/
287
 
323
 
288
static EXP apply_field_op
324
static EXP
289
    PROTO_N ( ( op, a, ns, fld, templ ) )
-
 
290
    PROTO_T ( int op X EXP a X NAMESPACE ns X IDENTIFIER fld X int templ )
325
apply_field_op(int op, EXP a, NAMESPACE ns, IDENTIFIER fld, int templ)
291
{
326
{
292
    EXP e ;
327
	EXP e;
293
    GRAPH gr ;
328
	GRAPH gr;
294
    HASHID nm ;
329
	HASHID nm;
295
    TYPE t, s ;
330
	TYPE t, s;
296
    string key ;
331
	string key;
297
    CV_SPEC qual ;
332
	CV_SPEC qual;
298
    ERROR err = NULL_err ;
333
	ERROR err = NULL_err;
299
    LIST ( TOKEN ) args = NULL_list ( TOKEN ) ;
334
	LIST(TOKEN) args = NULL_list(TOKEN);
300
 
335
 
301
    /* Find the type of a */
336
	/* Find the type of a */
302
    s = DEREF_type ( exp_type ( a ) ) ;
337
	s = DEREF_type(exp_type(a));
303
    qual = find_cv_qual ( s ) ;
338
	qual = find_cv_qual(s);
-
 
339
 
-
 
340
	/* Check for template members */
-
 
341
	if (templ && IS_id_undef(fld)) {
-
 
342
		TYPE form = DEREF_type(id_undef_form(fld));
-
 
343
		if (!IS_NULL_type(form) && IS_type_token(form)) {
-
 
344
			fld = DEREF_id(type_token_tok(form));
-
 
345
			args = DEREF_list(type_token_args(form));
-
 
346
			templ = 2;
-
 
347
		}
-
 
348
	}
-
 
349
 
-
 
350
	/* Check that fld is a member of ns */
-
 
351
	gr = is_subfield(ns, fld);
-
 
352
	if (!IS_NULL_graph(gr)) {
-
 
353
		IDENTIFIER orig = fld;
-
 
354
		fld = search_subfield(ns, gr, orig);
-
 
355
		if (templ == 2) {
-
 
356
			/* Apply template arguments */
-
 
357
			fld = apply_template(fld, args, 0, 0);
-
 
358
		}
-
 
359
		switch (TAG_id(fld)) {
-
 
360
		case id_stat_member_tag:
-
 
361
			/* Static data members */
-
 
362
			e = make_id_exp(fld);
-
 
363
			e = join_exp(a, e);
-
 
364
			return (e);
-
 
365
		case id_mem_func_tag:
-
 
366
		case id_stat_mem_func_tag:
-
 
367
			/* Member functions */
-
 
368
			if (!templ) {
-
 
369
				IDENTIFIER tid = find_template(fld, 0);
-
 
370
				if (!IS_NULL_id(tid)) {
-
 
371
					/* Should have 'template' prefix */
-
 
372
					report(crt_loc,
-
 
373
					       ERR_temp_names_mem(fld));
-
 
374
				}
-
 
375
			}
304
 
376
 
305
    /* Check for template members */
-
 
306
    if ( templ && IS_id_undef ( fld ) ) {
-
 
307
	TYPE form = DEREF_type ( id_undef_form ( fld ) ) ;
-
 
308
	if ( !IS_NULL_type ( form ) && IS_type_token ( form ) ) {
-
 
309
	    fld = DEREF_id ( type_token_tok ( form ) ) ;
-
 
310
	    args = DEREF_list ( type_token_args ( form ) ) ;
-
 
311
	    templ = 2 ;
-
 
312
	}
-
 
313
    }
-
 
314
 
-
 
315
    /* Check that fld is a member of ns */
-
 
316
    gr = is_subfield ( ns, fld ) ;
-
 
317
    if ( !IS_NULL_graph ( gr ) ) {
-
 
318
	IDENTIFIER orig = fld ;
-
 
319
	fld = search_subfield ( ns, gr, orig ) ;
-
 
320
	if ( templ == 2 ) {
-
 
321
	    /* Apply template arguments */
-
 
322
	    fld = apply_template ( fld, args, 0, 0 ) ;
-
 
323
	}
-
 
324
	switch ( TAG_id ( fld ) ) {
-
 
325
 
-
 
326
	    case id_stat_member_tag : {
-
 
327
		/* Static data members */
-
 
328
		e = make_id_exp ( fld ) ;
-
 
329
		e = join_exp ( a, e ) ;
-
 
330
		return ( e ) ;
-
 
331
	    }
-
 
332
 
-
 
333
	    case id_mem_func_tag :
-
 
334
	    case id_stat_mem_func_tag : {
-
 
335
		/* Member functions */
-
 
336
		if ( !templ ) {
-
 
337
		    IDENTIFIER tid = find_template ( fld, 0 ) ;
-
 
338
		    if ( !IS_NULL_id ( tid ) ) {
-
 
339
			/* Should have 'template' prefix */
-
 
340
			report ( crt_loc, ERR_temp_names_mem ( fld ) ) ;
-
 
341
		    }
-
 
342
		}
-
 
343
 
-
 
344
		/* Form '*a' for pointers */
377
			/* Form '*a' for pointers */
345
		if ( IS_type_ptr ( s ) ) {
378
			if (IS_type_ptr(s)) {
346
		    s = DEREF_type ( type_ptr_sub ( s ) ) ;
379
				s = DEREF_type(type_ptr_sub(s));
347
		    s = lvalue_type ( s ) ;
380
				s = lvalue_type(s);
348
		    MAKE_exp_indir ( s, a, a ) ;
381
				MAKE_exp_indir(s, a, a);
349
		}
382
			}
350
 
-
 
351
		/* Construct the result */
-
 
352
		e = make_id_exp ( fld ) ;
-
 
353
		t = DEREF_type ( exp_type ( e ) ) ;
-
 
354
		MAKE_exp_call ( t, e, a, gr, e ) ;
-
 
355
		return ( e ) ;
-
 
356
	    }
-
 
357
 
-
 
358
	    case id_member_tag : {
-
 
359
		/* Non-static data members */
-
 
360
		TYPE p ;
-
 
361
		OFFSET off ;
-
 
362
		int virt = 0 ;
-
 
363
 
383
 
364
		/* Allow for pointer types */
384
			/* Construct the result */
365
		if ( IS_type_ptr ( s ) ) {
385
			e = make_id_exp(fld);
366
		    /* Form '*a' for pointers */
-
 
367
		    s = DEREF_type ( type_ptr_sub ( s ) ) ;
386
			t = DEREF_type(exp_type(e));
368
		    qual = DEREF_cv ( type_qual ( s ) ) ;
387
			MAKE_exp_call(t, e, a, gr, e);
369
		    qual |= cv_lvalue ;
388
			return (e);
370
		} else {
389
		case id_member_tag: {
371
		    /* Form '&a' for non-pointers */
390
			/* Non-static data members */
-
 
391
			TYPE p;
372
		    a = member_address ( a ) ;
392
			OFFSET off;
373
		}
393
			int virt = 0;
374
 
394
 
375
		/* Find result type */
395
			/* Allow for pointer types */
376
		use_id ( fld, 0 ) ;
396
			if (IS_type_ptr(s)) {
377
		t = DEREF_type ( id_member_type ( fld ) ) ;
397
				/* Form '*a' for pointers */
378
		if ( !IS_type_ref ( t ) ) {
398
				s = DEREF_type(type_ptr_sub(s));
379
		    CV_SPEC cv = find_cv_qual ( t ) ;
399
				qual = DEREF_cv(type_qual(s));
380
		    cv &= cv_qual ;
400
				qual |= cv_lvalue;
381
		    if ( qual & cv_const ) {
401
			} else {
382
			DECL_SPEC ds = DEREF_dspec ( id_storage ( fld ) ) ;
-
 
383
			if ( !( ds & dspec_mutable ) ) {
-
 
384
			    /* 'mutable' cancels out 'const' */
402
				/* Form '&a' for non-pointers */
385
			    cv |= cv_const ;
403
				a = member_address(a);
386
			}
404
			}
-
 
405
 
-
 
406
			/* Find result type */
-
 
407
			use_id(fld, 0);
-
 
408
			t = DEREF_type(id_member_type(fld));
-
 
409
			if (!IS_type_ref(t)) {
-
 
410
				CV_SPEC cv = find_cv_qual(t);
-
 
411
				cv &= cv_qual;
-
 
412
				if (qual & cv_const) {
-
 
413
					DECL_SPEC ds =
-
 
414
					    DEREF_dspec(id_storage(fld));
-
 
415
					if (!(ds & dspec_mutable)) {
-
 
416
						/* 'mutable' cancels out
-
 
417
						 * 'const' */
-
 
418
						cv |= cv_const;
387
		    }
419
					}
-
 
420
				}
388
		    if ( qual & cv_volatile ) {
421
				if (qual & cv_volatile) {
389
			cv |= cv_volatile ;
422
					cv |= cv_volatile;
390
		    }
423
				}
391
		    t = qualify_type ( t, cv, 0 ) ;
424
				t = qualify_type(t, cv, 0);
-
 
425
			}
-
 
426
 
-
 
427
			/* Check for virtual base members */
-
 
428
			gr = DEREF_graph(id_member_base(fld));
-
 
429
			if (!IS_NULL_graph(gr)) {
-
 
430
				DECL_SPEC acc = DEREF_dspec(graph_access(gr));
-
 
431
				if (acc & dspec_mutable) {
-
 
432
					/* Contained in virtual base */
-
 
433
					if (know_type(a) != 1) {
-
 
434
						virt = 1;
-
 
435
					}
-
 
436
				}
-
 
437
			}
-
 
438
 
-
 
439
			/* Form the result */
-
 
440
			off = DEREF_off(id_member_off(fld));
-
 
441
			MAKE_type_ptr(cv_none, t, p);
-
 
442
			MAKE_exp_add_ptr(p, a, off, virt, e);
-
 
443
			if (qual & cv_lvalue) {
-
 
444
				/* The result is an lvalue if s is */
-
 
445
				t = lvalue_type(t);
-
 
446
				MAKE_exp_indir(t, e, e);
-
 
447
			} else {
-
 
448
				MAKE_exp_contents(t, e, e);
-
 
449
			}
-
 
450
			return (e);
-
 
451
		}
-
 
452
		case id_enumerator_tag: {
-
 
453
			/* Enumerator members */
-
 
454
			NAT n;
-
 
455
			unsigned etag;
-
 
456
			use_id(fld, 0);
-
 
457
			e = DEREF_exp(id_enumerator_value(fld));
-
 
458
			DECONS_exp_int_lit(t, n, etag, e);
-
 
459
			MAKE_exp_int_lit(t, n, etag, e);
-
 
460
			e = join_exp(a, e);
-
 
461
			return (e);
392
		}
462
		}
393
 
-
 
-
 
463
		case id_ambig_tag:
394
		/* Check for virtual base members */
464
			/* Ambiguous members */
395
		gr = DEREF_graph ( id_member_base ( fld ) ) ;
465
			IGNORE report_ambiguous(fld, 0, 1, 0);
396
		if ( !IS_NULL_graph ( gr ) ) {
466
			e = make_error_exp(1);
397
		    DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
467
			e = join_exp(a, e);
398
		    if ( acc & dspec_mutable ) {
468
			return (e);
399
			/* Contained in virtual base */
469
		case id_class_name_tag:
400
			if ( know_type ( a ) != 1 ) virt = 1 ;
470
		case id_class_alias_tag:
401
		    }
471
		case id_enum_name_tag:
402
		}
-
 
403
 
-
 
404
		/* Form the result */
472
		case id_enum_alias_tag:
405
		off = DEREF_off ( id_member_off ( fld ) ) ;
473
		case id_type_alias_tag:
406
		MAKE_type_ptr ( cv_none, t, p ) ;
474
			/* Type members */
407
		MAKE_exp_add_ptr ( p, a, off, virt, e ) ;
475
			err = ERR_expr_ref_type(fld);
-
 
476
			break;
408
		if ( qual & cv_lvalue ) {
477
		case id_undef_tag:
409
		    /* The result is an lvalue if s is */
478
			/* Undefined members */
410
		    t = lvalue_type ( t ) ;
479
			nm = DEREF_hashid(id_name(fld));
411
		    MAKE_exp_indir ( t, e, e ) ;
480
			err = ERR_lookup_qual_undef(nm, ns);
412
		} else {
481
			break;
413
		    MAKE_exp_contents ( t, e, e ) ;
-
 
414
		}
482
		}
415
		return ( e ) ;
-
 
416
	    }
-
 
417
 
-
 
418
	    case id_enumerator_tag : {
-
 
419
		/* Enumerator members */
-
 
420
		NAT n ;
-
 
421
		unsigned etag ;
-
 
422
		use_id ( fld, 0 ) ;
-
 
423
		e = DEREF_exp ( id_enumerator_value ( fld ) ) ;
-
 
424
		DECONS_exp_int_lit ( t, n, etag, e ) ;
-
 
425
		MAKE_exp_int_lit ( t, n, etag, e ) ;
-
 
426
		e = join_exp ( a, e ) ;
-
 
427
		return ( e ) ;
-
 
428
	    }
-
 
429
 
-
 
430
	    case id_ambig_tag : {
-
 
431
		/* Ambiguous members */
-
 
432
		IGNORE report_ambiguous ( fld, 0, 1, 0 ) ;
-
 
433
		e = make_error_exp ( 1 ) ;
-
 
434
		e = join_exp ( a, e ) ;
-
 
435
		return ( e ) ;
-
 
436
	    }
-
 
437
 
-
 
438
	    case id_class_name_tag :
-
 
439
	    case id_class_alias_tag :
-
 
440
	    case id_enum_name_tag :
-
 
441
	    case id_enum_alias_tag :
-
 
442
	    case id_type_alias_tag : {
-
 
443
		/* Type members */
-
 
444
		err = ERR_expr_ref_type ( fld ) ;
-
 
445
		break ;
-
 
446
	    }
-
 
447
 
-
 
448
	    case id_undef_tag : {
-
 
449
		/* Undefined members */
-
 
450
		nm = DEREF_hashid ( id_name ( fld ) ) ;
-
 
451
		err = ERR_lookup_qual_undef ( nm, ns ) ;
-
 
452
		break ;
-
 
453
	    }
-
 
454
	}
483
	}
455
    }
-
 
456
 
484
 
457
    /* Report any errors */
485
	/* Report any errors */
458
    nm = DEREF_hashid ( id_name ( fld ) ) ;
486
	nm = DEREF_hashid(id_name(fld));
459
    if ( IS_hashid_destr ( nm ) ) {
487
	if (IS_hashid_destr(nm)) {
460
	/* Pseudo-destructor call */
488
		/* Pseudo-destructor call */
461
	destroy_error ( err, 1 ) ;
489
		destroy_error(err, 1);
462
	return ( NULL_exp ) ;
490
		return (NULL_exp);
463
    }
491
	}
464
    key = find_vocab ( lex_class ) ;
492
	key = find_vocab(lex_class);
-
 
493
	if (IS_NULL_err(err)) {
465
    if ( IS_NULL_err ( err ) ) err = ERR_lookup_qual_bad ( fld, ns ) ;
494
		err = ERR_lookup_qual_bad(fld, ns);
-
 
495
	}
466
    err = concat_error ( err, ERR_expr_ref_select ( op, key ) ) ;
496
	err = concat_error(err, ERR_expr_ref_select(op, key));
467
    report ( crt_loc, err ) ;
497
	report(crt_loc, err);
468
    e = make_error_exp ( 1 ) ;
498
	e = make_error_exp(1);
469
    e = join_exp ( a, e ) ;
499
	e = join_exp(a, e);
470
    return ( e ) ;
500
	return (e);
471
}
501
}
472
 
502
 
473
 
503
 
474
/*
504
/*
475
    COMPLETE A FIELD SELECTOR EXPRESSION
505
    COMPLETE A FIELD SELECTOR EXPRESSION
476
 
506
 
477
    This routine gives the main interface to apply_field_op, allowing for
507
    This routine gives the main interface to apply_field_op, allowing for
478
    the error case and adjusting the name look-up stack.  a is the return
508
    the error case and adjusting the name look-up stack.  a is the return
479
    value from begin_field_exp, while t is the returned base type.  The
509
    value from begin_field_exp, while t is the returned base type.  The
480
    field identifier is given by fld, this being prefixed by template if
510
    field identifier is given by fld, this being prefixed by template if
481
    templ is true.
511
    templ is true.
482
*/
512
*/
483
 
513
 
484
EXP end_field_exp
514
EXP
485
    PROTO_N ( ( op, a, t, ns, fld, templ ) )
-
 
486
    PROTO_T ( int op X EXP a X TYPE t X NAMESPACE ns X
515
end_field_exp(int op, EXP a, TYPE t, NAMESPACE ns, IDENTIFIER fld, int templ)
487
	      IDENTIFIER fld X int templ )
-
 
488
{
516
{
489
    EXP e ;
517
	EXP e;
490
    QUALIFIER cq = crt_id_qualifier ;
518
	QUALIFIER cq = crt_id_qualifier;
491
    if ( cq == qual_full || cq == qual_top ) {
519
	if (cq == qual_full || cq == qual_top) {
492
	/* Bad field selector */
520
		/* Bad field selector */
493
	report ( crt_loc, ERR_expr_ref_qual ( cq, fld ) ) ;
521
		report(crt_loc, ERR_expr_ref_qual(cq, fld));
494
    }
522
	}
495
    if ( !IS_NULL_nspace ( ns ) ) {
523
	if (!IS_NULL_nspace(ns)) {
496
	/* Class types */
524
		/* Class types */
497
	remove_namespace () ;
525
		remove_namespace();
498
	cache_lookup = old_cache_lookup ;
526
		cache_lookup = old_cache_lookup;
499
	if ( cq != qual_none ) templ = 1 ;
527
		if (cq != qual_none) {
500
	e = apply_field_op ( op, a, ns, fld, templ ) ;
-
 
501
	if ( !IS_NULL_exp ( e ) ) return ( e ) ;
-
 
502
    } else {
528
			templ = 1;
503
	cache_lookup = old_cache_lookup ;
-
 
504
    }
529
		}
505
 
-
 
506
    if ( IS_exp_op ( a ) ) {
-
 
507
	/* Template parameter types */
-
 
508
	EXP b ;
-
 
509
	if ( cq == qual_none ) fld = underlying_id ( fld ) ;
-
 
510
	MAKE_exp_member ( t, fld, qual_nested, b ) ;
530
		e = apply_field_op(op, a, ns, fld, templ);
511
	COPY_exp ( exp_op_arg2 ( a ), b ) ;
-
 
512
	e = a ;
-
 
513
    } else {
-
 
514
	/* Other types */
-
 
515
	if ( !IS_type_error ( t ) ) {
531
		if (!IS_NULL_exp(e)) {
516
	    HASHID nm = DEREF_hashid ( id_name ( fld ) ) ;
-
 
517
	    if ( IS_hashid_destr ( nm ) ) {
-
 
518
		/* Allow for pseudo-destructor call */
-
 
519
		TYPE fn = type_func_void ;
-
 
520
		TYPE r = DEREF_type ( hashid_destr_type ( nm ) ) ;
-
 
521
		TYPE s = expand_type ( r, 2 ) ;
-
 
522
		if ( !EQ_type ( s, r ) ) {
-
 
523
		    nm = lookup_destr ( s, NULL_id ) ;
-
 
524
		    fld = DEREF_id ( hashid_id ( nm ) ) ;
-
 
525
		    t = expand_type ( t, 2 ) ;
-
 
526
		    r = s ;
532
			return (e);
527
		}
533
		}
-
 
534
	} else {
528
		/* NOT YET IMPLEMENTED - scalar type */
535
		cache_lookup = old_cache_lookup;
-
 
536
	}
-
 
537
 
529
		if ( !eq_type_unqual ( t, r ) && !IS_type_error ( r ) ) {
538
	if (IS_exp_op(a)) {
530
		    /* Destructor types should match */
539
		/* Template parameter types */
-
 
540
		EXP b;
-
 
541
		if (cq == qual_none) {
531
		    report ( crt_loc, ERR_expr_pseudo_obj ( nm, t ) ) ;
542
			fld = underlying_id(fld);
532
		}
543
		}
-
 
544
		MAKE_exp_member(t, fld, qual_nested, b);
-
 
545
		COPY_exp(exp_op_arg2(a), b);
-
 
546
		e = a;
-
 
547
	} else {
-
 
548
		/* Other types */
-
 
549
		if (!IS_type_error(t)) {
-
 
550
			HASHID nm = DEREF_hashid(id_name(fld));
-
 
551
			if (IS_hashid_destr(nm)) {
-
 
552
				/* Allow for pseudo-destructor call */
-
 
553
				TYPE fn = type_func_void;
-
 
554
				TYPE r = DEREF_type(hashid_destr_type(nm));
-
 
555
				TYPE s = expand_type(r, 2);
-
 
556
				if (!EQ_type(s, r)) {
-
 
557
					nm = lookup_destr(s, NULL_id);
-
 
558
					fld = DEREF_id(hashid_id(nm));
-
 
559
					t = expand_type(t, 2);
-
 
560
					r = s;
-
 
561
				}
-
 
562
				/* NOT YET IMPLEMENTED - scalar type */
-
 
563
				if (!eq_type_unqual(t, r) &&
-
 
564
				    !IS_type_error(r)) {
-
 
565
					/* Destructor types should match */
-
 
566
					report(crt_loc,
-
 
567
					       ERR_expr_pseudo_obj(nm, t));
-
 
568
				}
533
		MAKE_exp_undeclared ( fn, fld, cq, e ) ;
569
				MAKE_exp_undeclared(fn, fld, cq, e);
534
		MAKE_exp_call ( fn, e, a, NULL_graph, e ) ;
570
				MAKE_exp_call(fn, e, a, NULL_graph, e);
535
	    } else {
571
			} else {
536
		/* Anything else is illegal */
572
				/* Anything else is illegal */
537
		string key = find_vocab ( lex_class ) ;
573
				string key = find_vocab(lex_class);
538
		TYPE s = DEREF_type ( exp_type ( a ) ) ;
574
				TYPE s = DEREF_type(exp_type(a));
539
		if ( op == lex_arrow ) {
575
				if (op == lex_arrow) {
-
 
576
					report(crt_loc,
540
		    report ( crt_loc, ERR_expr_ref_arrow_op ( s, key ) ) ;
577
					       ERR_expr_ref_arrow_op(s, key));
-
 
578
				} else {
-
 
579
					report(crt_loc,
-
 
580
					       ERR_expr_ref_dot_op(s, key));
-
 
581
				}
-
 
582
				e = make_error_exp(1);
-
 
583
			}
541
		} else {
584
		} else {
542
		    report ( crt_loc, ERR_expr_ref_dot_op ( s, key ) ) ;
585
			e = make_error_exp(1);
543
		}
586
		}
544
		e = make_error_exp ( 1 ) ;
-
 
545
	    }
-
 
546
	} else {
-
 
547
	    e = make_error_exp ( 1 ) ;
-
 
548
	}
587
	}
549
    }
-
 
550
    return ( e ) ;
588
	return (e);
551
}
589
}
552
 
590
 
553
 
591
 
554
/*
592
/*
555
    CONSTRUCT A FIELD SELECTOR EXPRESSION
593
    CONSTRUCT A FIELD SELECTOR EXPRESSION
556
 
594
 
557
    This routine is an alternative interface to the field selector
595
    This routine is an alternative interface to the field selector
558
    expression routines used in the instantiation of template functions.
596
    expression routines used in the instantiation of template functions.
559
    It constructs 'a.b' or 'a->b' depending on op, where b is an
597
    It constructs 'a.b' or 'a->b' depending on op, where b is an
560
    identifier expression giving the member name.
598
    identifier expression giving the member name.
561
*/
599
*/
562
 
600
 
563
EXP make_field_exp
601
EXP
564
    PROTO_N ( ( op, a, b ) )
-
 
565
    PROTO_T ( int op X EXP a X EXP b )
602
make_field_exp(int op, EXP a, EXP b)
566
{
603
{
567
    TYPE t = NULL_type ;
604
	TYPE t = NULL_type;
568
    NAMESPACE ns = NULL_nspace ;
605
	NAMESPACE ns = NULL_nspace;
569
    QUALIFIER cq = crt_id_qualifier ;
606
	QUALIFIER cq = crt_id_qualifier;
570
    EXP e = begin_field_exp ( op, a, &t, &ns ) ;
607
	EXP e = begin_field_exp(op, a, &t, &ns);
571
    IDENTIFIER fld = DEREF_id ( exp_member_id ( b ) ) ;
608
	IDENTIFIER fld = DEREF_id(exp_member_id(b));
572
    QUALIFIER qual = DEREF_qual ( exp_member_qual ( b ) ) ;
609
	QUALIFIER qual = DEREF_qual(exp_member_qual(b));
573
    crt_id_qualifier = qual ;
610
	crt_id_qualifier = qual;
574
    if ( !IS_NULL_nspace ( ns ) ) {
611
	if (!IS_NULL_nspace(ns)) {
575
	/* Rescan field for class namespaces */
612
		/* Rescan field for class namespaces */
576
	fld = rescan_id ( fld, qual, 0 ) ;
613
		fld = rescan_id(fld, qual, 0);
577
    }
614
	}
578
    e = end_field_exp ( op, e, t, ns, fld, 1 ) ;
615
	e = end_field_exp(op, e, t, ns, fld, 1);
579
    crt_id_qualifier = cq ;
616
	crt_id_qualifier = cq;
580
    return ( e ) ;
617
	return (e);
581
}
618
}
582
 
619
 
583
 
620
 
584
/*
621
/*
585
    CONSTRUCT A MEMBER SELECTOR EXPRESSION
622
    CONSTRUCT A MEMBER SELECTOR EXPRESSION
586
 
623
 
587
    This routine constructs the member selector expressions 'a.*b' and
624
    This routine constructs the member selector expressions 'a.*b' and
588
    'a->*b' (as indicated by op).  Note that '->*' can be overloaded but
625
    'a->*b' (as indicated by op).  Note that '->*' can be overloaded but
589
    '.*' can't.
626
    '.*' can't.
655
	}
783
	}
656
    }
-
 
657
 
784
 
658
    /* Check first operand type */
785
	/* Construct the result */
659
    if ( IS_type_ptr ( ta ) ) {
786
	if (IS_type_func(tbr)) {
660
	a = convert_lvalue ( a ) ;
787
		/* Member functions */
661
	ta = DEREF_type ( exp_type ( a ) ) ;
-
 
662
	tap = DEREF_type ( type_ptr_sub ( ta ) ) ;
-
 
663
	qual = DEREF_cv ( type_qual ( tap ) ) ;
-
 
664
	qual |= cv_lvalue ;
-
 
665
	is_ptr = 1 ;
788
		if (is_ptr) {
666
    } else {
-
 
667
	tap = ta ;
789
			ta = lvalue_type(ta);
668
	qual = DEREF_cv ( type_qual ( ta ) ) ;
790
			MAKE_exp_indir(ta, a, a);
669
	is_ptr = 0 ;
-
 
670
    }
791
		}
671
    if ( IS_type_compound ( tap ) ) {
-
 
672
	ERROR err ;
-
 
673
	ca = DEREF_ctype ( type_compound_defn ( tap ) ) ;
-
 
674
	if ( eq_ctype ( ca, cb ) ) {
792
		MAKE_exp_call(tbr, b, a, NULL_graph, e);
675
	    /* Equal base types */
-
 
676
	    /* EMPTY */
-
 
677
	} else {
793
	} else {
678
	    GRAPH gr = find_base_class ( ca, cb, 1 ) ;
-
 
679
	    if ( !IS_NULL_graph ( gr ) ) {
-
 
680
		/* cb is a base class of ca */
794
		/* Data members */
681
		OFFSET off ;
795
		OFFSET off;
682
		err = check_ambig_base ( gr ) ;
796
		CV_SPEC cv1 = (qual & cv_qual);
683
		if ( !IS_NULL_err ( err ) ) {
797
		if (cv1) {
-
 
798
			/* The result type inherits both qualifiers */
684
		    ERROR err2 = ERR_expr_mptr_oper_ambig ( op ) ;
799
			CV_SPEC cv2 = DEREF_cv(type_qual(tbr));
-
 
800
			tbr = qualify_type(tbr,(cv1 | cv2), 0);
-
 
801
		}
-
 
802
		if (!is_ptr) {
685
		    err = concat_error ( err, err2 ) ;
803
			/* For non-pointers construct '&a' */
686
		    report ( crt_loc, err ) ;
804
			a = member_address(a);
687
		}
805
		}
688
		check_base_access ( gr ) ;
806
		MAKE_off_ptr_mem(b, off);
-
 
807
		MAKE_type_ptr(cv_none, tbr, tbp);
689
		off = DEREF_off ( graph_off ( gr ) ) ;
808
		MAKE_exp_add_ptr(tbp, a, off, 0, e);
690
		tap = make_class_type ( cb ) ;
809
		if (qual & cv_lvalue) {
691
		MAKE_type_ptr ( cv_none, tap, ta ) ;
810
			/* The result is an lvalue if tap is */
692
		if ( is_ptr ) {
811
			tbr = lvalue_type(tbr);
693
		    a = make_base_cast ( ta, a, off ) ;
812
			MAKE_exp_indir(tbr, e, e);
694
		} else {
813
		} else {
695
		    a = member_address ( a ) ;
-
 
696
		    a = make_base_cast ( ta, a, off ) ;
-
 
697
		    ta = lvalue_type ( tap ) ;
-
 
698
		    MAKE_exp_indir ( ta, a, a ) ;
814
			MAKE_exp_contents(tbr, e, e);
699
		}
815
		}
700
	    } else {
-
 
701
		/* cb is not a base class of ca */
-
 
702
		goto error_lab ;
-
 
703
	    }
-
 
704
	}
-
 
705
	err = check_incomplete ( tap ) ;
-
 
706
	if ( !IS_NULL_err ( err ) ) {
-
 
707
	    /* Class should be complete */
-
 
708
	    err = concat_error ( err, ERR_expr_mptr_oper_compl ( op ) ) ;
-
 
709
	    report ( crt_loc, err ) ;
-
 
710
	}
-
 
711
    } else {
-
 
712
	/* Invalid base type */
-
 
713
	if ( !IS_type_error ( tap ) ) {
-
 
714
	    error_lab : {
-
 
715
		ERROR err ;
-
 
716
		IDENTIFIER cid = DEREF_id ( ctype_name ( cb ) ) ;
-
 
717
		if ( op == lex_arrow_Hstar ) {
-
 
718
		    err = ERR_expr_mptr_oper_arrow_op ( cid, ta ) ;
-
 
719
		} else {
-
 
720
		    err = ERR_expr_mptr_oper_dot_op ( cid, ta ) ;
-
 
721
		}
-
 
722
		report ( crt_loc, err ) ;
-
 
723
	    }
-
 
724
	}
-
 
725
	e = make_error_exp ( 1 ) ;
-
 
726
	return ( e ) ;
-
 
727
    }
-
 
728
 
-
 
729
    /* Correct base type */
-
 
730
    if ( op == lex_arrow_Hstar ) {
-
 
731
	if ( !is_ptr ) {
-
 
732
	    report ( crt_loc, ERR_expr_mptr_oper_arrow_dot ( ta ) ) ;
-
 
733
	}
-
 
734
    } else {
-
 
735
	if ( is_ptr ) {
-
 
736
	    report ( crt_loc, ERR_expr_mptr_oper_dot_arrow ( ta ) ) ;
-
 
737
	}
-
 
738
    }
-
 
739
 
-
 
740
    /* Check for null pointers */
-
 
741
    if ( IS_exp_null ( a ) && is_ptr ) {
-
 
742
	report ( crt_loc, ERR_expr_unary_op_indir_null ( op ) ) ;
-
 
743
    }
-
 
744
    if ( IS_exp_null ( b ) ) {
-
 
745
	report ( crt_loc, ERR_expr_mptr_oper_null ( op ) ) ;
-
 
746
    }
-
 
747
 
-
 
748
    /* Construct the result */
-
 
749
    if ( IS_type_func ( tbr ) ) {
-
 
750
	/* Member functions */
-
 
751
	if ( is_ptr ) {
-
 
752
	    ta = lvalue_type ( ta ) ;
-
 
753
	    MAKE_exp_indir ( ta, a, a ) ;
-
 
754
	}
816
	}
755
	MAKE_exp_call ( tbr, b, a, NULL_graph, e ) ;
-
 
756
    } else {
-
 
757
	/* Data members */
-
 
758
	OFFSET off ;
-
 
759
	CV_SPEC cv1 = ( qual & cv_qual ) ;
-
 
760
	if ( cv1 ) {
-
 
761
	    /* The result type inherits both qualifiers */
-
 
762
	    CV_SPEC cv2 = DEREF_cv ( type_qual ( tbr ) ) ;
-
 
763
	    tbr = qualify_type ( tbr, ( cv1 | cv2 ), 0 ) ;
-
 
764
	}
-
 
765
	if ( !is_ptr ) {
-
 
766
	    /* For non-pointers construct '&a' */
-
 
767
	    a = member_address ( a ) ;
-
 
768
	}
-
 
769
	MAKE_off_ptr_mem ( b, off ) ;
-
 
770
	MAKE_type_ptr ( cv_none, tbr, tbp ) ;
-
 
771
	MAKE_exp_add_ptr ( tbp, a, off, 0, e ) ;
-
 
772
	if ( qual & cv_lvalue ) {
-
 
773
	    /* The result is an lvalue if tap is */
-
 
774
	    tbr = lvalue_type ( tbr ) ;
-
 
775
	    MAKE_exp_indir ( tbr, e, e ) ;
-
 
776
	} else {
-
 
777
	    MAKE_exp_contents ( tbr, e, e ) ;
-
 
778
	}
-
 
779
    }
-
 
780
    return ( e ) ;
817
	return (e);
781
}
818
}
782
 
819
 
783
#endif
820
#endif
784
 
821
 
785
 
822
 
Line 788... Line 825...
788
 
825
 
789
    This routine looks up the member fld.  In a member function definition
826
    This routine looks up the member fld.  In a member function definition
790
    the routine returns 'this->fld' for non-static data members and the
827
    the routine returns 'this->fld' for non-static data members and the
791
    parameter corresponding to 'this' for non-static function members,
828
    parameter corresponding to 'this' for non-static function members,
792
    otherwise the null expression is returned.
829
    otherwise the null expression is returned.
793
*/
830
*/
794
 
831
 
795
EXP make_this_field
832
EXP
796
    PROTO_N ( ( fld ) )
-
 
797
    PROTO_T ( IDENTIFIER fld )
833
make_this_field(IDENTIFIER fld)
798
{
834
{
799
    IDENTIFIER fn = crt_func_id ;
835
	IDENTIFIER fn = crt_func_id;
800
    if ( in_function_defn && IS_id_mem_func ( fn ) ) {
836
	if (in_function_defn && IS_id_mem_func(fn)) {
801
	NAMESPACE ns = DEREF_nspace ( id_parent ( fn ) ) ;
837
		NAMESPACE ns = DEREF_nspace(id_parent(fn));
802
	GRAPH gr = is_subfield ( ns, fld ) ;
838
		GRAPH gr = is_subfield(ns, fld);
803
	if ( !IS_NULL_graph ( gr ) ) {
839
		if (!IS_NULL_graph(gr)) {
804
	    switch ( TAG_id ( fld ) ) {
840
			switch (TAG_id(fld)) {
805
		case id_member_tag :
841
			case id_member_tag:
806
		case id_mem_func_tag : {
842
			case id_mem_func_tag: {
807
		    EXP e ;
843
				EXP e;
808
		    TYPE t ;
844
				TYPE t;
809
		    IDENTIFIER id = this_param ( fn, 1 ) ;
845
				IDENTIFIER id = this_param(fn, 1);
810
		    if ( in_default_arg ) {
846
				if (in_default_arg) {
811
			/* Can't use in default argument */
847
					/* Can't use in default argument */
-
 
848
					ERROR err =
812
			ERROR err = ERR_dcl_fct_default_param ( fld ) ;
849
					    ERR_dcl_fct_default_param(fld);
813
			report ( crt_loc, err ) ;
850
					report(crt_loc, err);
814
		    }
851
				}
815
		    e = DEREF_exp ( id_parameter_init ( id ) ) ;
852
				e = DEREF_exp(id_parameter_init(id));
816
		    t = DEREF_type ( exp_type ( e ) ) ;
853
				t = DEREF_type(exp_type(e));
817
		    MAKE_exp_copy ( t, e, e ) ;
854
				MAKE_exp_copy(t, e, e);
818
		    e = apply_field_op ( lex_arrow, e, ns, fld, 1 ) ;
855
				e = apply_field_op(lex_arrow, e, ns, fld, 1);
819
		    return ( e ) ;
856
				return (e);
820
		}
857
			}
821
	    }
858
			}
822
	}
859
		}
823
    }
860
	}
824
    return ( NULL_exp ) ;
861
	return (NULL_exp);
825
}
862
}
826
 
863
 
827
 
864
 
828
/*
865
/*
829
    DECOMPOSE A BITFIELD OFFSET
866
    DECOMPOSE A BITFIELD OFFSET
830
 
867
 
831
    This routine decomposes the bitfield member offset off into its member
868
    This routine decomposes the bitfield member offset off into its member
832
    component, which is returned, and its base class component, which is
869
    component, which is returned, and its base class component, which is
833
    assigned to off.
870
    assigned to off.
834
*/
871
*/
835
 
872
 
836
OFFSET decons_bitf_off
873
OFFSET
837
    PROTO_N ( ( off ) )
-
 
838
    PROTO_T ( OFFSET *off )
874
decons_bitf_off(OFFSET *off)
839
{
875
{
840
    OFFSET off1 = *off ;
876
	OFFSET off1 = *off;
841
    if ( !IS_NULL_off ( off1 ) && IS_off_plus ( off1 ) ) {
877
	if (!IS_NULL_off(off1) && IS_off_plus(off1)) {
842
	*off = DEREF_off ( off_plus_arg1 ( off1 ) ) ;
878
		*off = DEREF_off(off_plus_arg1(off1));
843
	off1 = DEREF_off ( off_plus_arg2 ( off1 ) ) ;
879
		off1 = DEREF_off(off_plus_arg2(off1));
844
    } else {
880
	} else {
845
	*off = NULL_off ;
881
		*off = NULL_off;
846
    }
882
	}
847
    return ( off1 ) ;
883
	return (off1);
848
}
884
}
849
 
885
 
850
 
886
 
851
/*
887
/*
852
    DECOMPOSE A BITFIELD EXPRESSION
888
    DECOMPOSE A BITFIELD EXPRESSION
853
 
889
 
854
    This routine decomposes the lvalue bitfield expression e into its
890
    This routine decomposes the lvalue bitfield expression e into its
855
    bitfield member offset, which is returned, and its class pointer
891
    bitfield member offset, which is returned, and its class pointer
856
    component, which is assigned to e.
892
    component, which is assigned to e.
857
*/
893
*/
858
 
894
 
859
OFFSET decons_bitf_exp
895
OFFSET
860
    PROTO_N ( ( e ) )
-
 
861
    PROTO_T ( EXP *e )
896
decons_bitf_exp(EXP *e)
862
{
897
{
863
    EXP a = *e ;
898
	EXP a = *e;
864
    OFFSET off = NULL_off ;
899
	OFFSET off = NULL_off;
865
    switch ( TAG_exp ( a ) ) {
-
 
866
 
900
 
-
 
901
	switch (TAG_exp(a)) {
867
	case exp_indir_tag : {
902
	case exp_indir_tag: {
868
	    /* Simple field access */
903
		/* Simple field access */
869
	    a = DEREF_exp ( exp_indir_ptr ( a ) ) ;
904
		a = DEREF_exp(exp_indir_ptr(a));
870
	    if ( IS_exp_add_ptr ( a ) ) {
905
		if (IS_exp_add_ptr(a)) {
871
		TYPE t ;
906
			TYPE t;
872
		int virt ;
907
			int virt;
873
		OFFSET off1 ;
908
			OFFSET off1;
874
		DECONS_exp_add_ptr ( t, a, off1, virt, a ) ;
909
			DECONS_exp_add_ptr(t, a, off1, virt, a);
875
		UNUSED ( t ) ;
910
			UNUSED(t);
876
		t = DEREF_type ( exp_type ( a ) ) ;
911
			t = DEREF_type(exp_type(a));
877
		off = decons_bitf_off ( &off1 ) ;
912
			off = decons_bitf_off(&off1);
878
		if ( !IS_NULL_off ( off1 ) ) {
913
			if (!IS_NULL_off(off1)) {
879
		    MAKE_exp_add_ptr ( t, a, off1, virt, a ) ;
914
				MAKE_exp_add_ptr(t, a, off1, virt, a);
880
		}
915
			}
881
		if ( IS_exp_address ( a ) ) {
916
			if (IS_exp_address(a)) {
882
		    a = DEREF_exp ( exp_address_arg ( a ) ) ;
917
				a = DEREF_exp(exp_address_arg(a));
-
 
918
			} else {
-
 
919
				if (IS_type_ptr(t)) {
-
 
920
					t = DEREF_type(type_ptr_sub(t));
-
 
921
				}
-
 
922
				t = lvalue_type(t);
-
 
923
				MAKE_exp_indir(t, a, a);
-
 
924
			}
-
 
925
			*e = a;
-
 
926
		}
-
 
927
		break;
-
 
928
	}
-
 
929
	case exp_comma_tag: {
-
 
930
		/* Comma expression */
-
 
931
		TYPE t = DEREF_type(exp_type(a));
-
 
932
		LIST(EXP) p = DEREF_list(exp_comma_args(a));
-
 
933
		LIST(EXP) q = NULL_list(EXP);
-
 
934
		while (!IS_NULL_list(p)) {
-
 
935
			EXP b = DEREF_exp(HEAD_list(p));
-
 
936
			p = TAIL_list(p);
-
 
937
			if (IS_NULL_list(p)) {
-
 
938
				off = decons_bitf_exp(&b);
-
 
939
				t = DEREF_type(exp_type(b));
-
 
940
			}
-
 
941
			CONS_exp(b, q, q);
-
 
942
		}
-
 
943
		q = REVERSE_list(q);
-
 
944
		MAKE_exp_comma(t, q, a);
-
 
945
		*e = a;
-
 
946
		break;
-
 
947
	}
-
 
948
	case exp_if_stmt_tag: {
-
 
949
		/* Conditional expression */
-
 
950
		TYPE t;
-
 
951
		EXP c = DEREF_exp(exp_if_stmt_cond(a));
-
 
952
		EXP b1 = DEREF_exp(exp_if_stmt_true_code(a));
-
 
953
		EXP b2 = DEREF_exp(exp_if_stmt_false_code(a));
-
 
954
		OFFSET off1 = decons_bitf_exp(&b1);
-
 
955
		OFFSET off2 = decons_bitf_exp(&b2);
-
 
956
		if (eq_offset(off1, off2, 0)) {
-
 
957
			off = off1;
883
		} else {
958
		} else {
884
		    if ( IS_type_ptr ( t ) ) {
959
			/* NOT YET IMPLEMENTED */
885
			t = DEREF_type ( type_ptr_sub ( t ) ) ;
-
 
886
		    }
960
			off = off1;
887
		    t = lvalue_type ( t ) ;
-
 
888
		    MAKE_exp_indir ( t, a, a ) ;
-
 
889
		}
961
		}
-
 
962
		t = DEREF_type(exp_type(b1));
-
 
963
		MAKE_exp_if_stmt(t, c, b1, b2, NULL_id, a);
890
		*e = a ;
964
		*e = a;
891
	    }
-
 
892
	    break ;
965
		break;
893
	}
966
	}
894
 
-
 
895
	case exp_comma_tag : {
-
 
896
	    /* Comma expression */
-
 
897
	    TYPE t = DEREF_type ( exp_type ( a ) ) ;
-
 
898
	    LIST ( EXP ) p = DEREF_list ( exp_comma_args ( a ) ) ;
-
 
899
	    LIST ( EXP ) q = NULL_list ( EXP ) ;
-
 
900
	    while ( !IS_NULL_list ( p ) ) {
-
 
901
		EXP b = DEREF_exp ( HEAD_list ( p ) ) ;
-
 
902
		p = TAIL_list ( p ) ;
-
 
903
		if ( IS_NULL_list ( p ) ) {
-
 
904
		    off = decons_bitf_exp ( &b ) ;
-
 
905
		    t = DEREF_type ( exp_type ( b ) ) ;
-
 
906
		}
-
 
907
		CONS_exp ( b, q, q ) ;
-
 
908
	    }
-
 
909
	    q = REVERSE_list ( q ) ;
-
 
910
	    MAKE_exp_comma ( t, q, a ) ;
-
 
911
	    *e = a ;
-
 
912
	    break ;
-
 
913
	}
-
 
914
 
-
 
915
	case exp_if_stmt_tag : {
-
 
916
	    /* Conditional expression */
-
 
917
	    TYPE t ;
-
 
918
	    EXP c = DEREF_exp ( exp_if_stmt_cond ( a ) ) ;
-
 
919
	    EXP b1 = DEREF_exp ( exp_if_stmt_true_code ( a ) ) ;
-
 
920
	    EXP b2 = DEREF_exp ( exp_if_stmt_false_code ( a ) ) ;
-
 
921
	    OFFSET off1 = decons_bitf_exp ( &b1 ) ;
-
 
922
	    OFFSET off2 = decons_bitf_exp ( &b2 ) ;
-
 
923
	    if ( eq_offset ( off1, off2, 0 ) ) {
-
 
924
		off = off1 ;
-
 
925
	    } else {
-
 
926
		/* NOT YET IMPLEMENTED */
-
 
927
		off = off1 ;
-
 
928
	    }
-
 
929
	    t = DEREF_type ( exp_type ( b1 ) ) ;
-
 
930
	    MAKE_exp_if_stmt ( t, c, b1, b2, NULL_id, a ) ;
-
 
931
	    *e = a ;
-
 
932
	    break ;
-
 
933
	}
967
	}
934
    }
-
 
935
    return ( off ) ;
968
	return (off);
936
}
969
}
937
 
970
 
938
 
971
 
939
/*
972
/*
940
    SET MEMBER OFFSET LOOK-UP NAMESPACE
973
    SET MEMBER OFFSET LOOK-UP NAMESPACE
941
 
974
 
942
    This routine sets the look-up namespace to that for the class type t.
975
    This routine sets the look-up namespace to that for the class type t.
943
    If t is not a class type then the null namespace is returned.
976
    If t is not a class type then the null namespace is returned.
944
*/
977
*/
945
 
978
 
946
NAMESPACE offset_nspace
979
NAMESPACE
947
    PROTO_N ( ( t ) )
-
 
948
    PROTO_T ( TYPE t )
980
offset_nspace(TYPE t)
949
{
981
{
950
    NAMESPACE ns ;
982
	NAMESPACE ns;
951
    if ( IS_type_compound ( t ) ) {
983
	if (IS_type_compound(t)) {
952
	CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
984
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
953
	complete_class ( ct, 1 ) ;
985
		complete_class(ct, 1);
954
	ns = DEREF_nspace ( ctype_member ( ct ) ) ;
986
		ns = DEREF_nspace(ctype_member(ct));
955
	cache_lookup = 0 ;
987
		cache_lookup = 0;
956
	add_namespace ( ns ) ;
988
		add_namespace(ns);
957
    } else {
989
	} else {
958
	ns = NULL_nspace ;
990
		ns = NULL_nspace;
959
	cache_lookup = 0 ;
991
		cache_lookup = 0;
960
    }
992
	}
961
    return ( ns ) ;
993
	return (ns);
962
}
994
}
963
 
995
 
964
 
996
 
965
/*
997
/*
966
    FIND A MEMBER OFFSET
998
    FIND A MEMBER OFFSET
967
 
999
 
968
    This routine finds the offset of the member id of the class type t.
1000
    This routine finds the offset of the member id of the class type t.
969
    ns gives the namespace associated with t.  The member type is
1001
    ns gives the namespace associated with t.  The member type is
970
    returned via pt.  id must denote a simple, non-virtual data member.
1002
    returned via pt.  id must denote a simple, non-virtual data member.
971
*/
1003
*/
972
 
1004
 
973
OFFSET offset_member
1005
OFFSET
974
    PROTO_N ( ( t, id, pt, ns, adjust ) )
-
 
975
    PROTO_T ( TYPE t X IDENTIFIER id X TYPE *pt X NAMESPACE ns X int adjust )
1006
offset_member(TYPE t, IDENTIFIER id, TYPE *pt, NAMESPACE ns, int adjust)
976
{
1007
{
977
    if ( !IS_NULL_nspace ( ns ) ) {
1008
	if (!IS_NULL_nspace(ns)) {
978
	GRAPH gr ;
1009
		GRAPH gr;
979
	if ( adjust ) {
1010
		if (adjust) {
980
	    remove_namespace () ;
1011
			remove_namespace();
981
	    cache_lookup = old_cache_lookup ;
1012
			cache_lookup = old_cache_lookup;
982
	}
-
 
983
	gr = is_subfield ( ns, id ) ;
-
 
984
	if ( !IS_NULL_graph ( gr ) ) {
-
 
985
	    IDENTIFIER fld = search_subfield ( ns, gr, id ) ;
-
 
986
	    switch ( TAG_id ( fld ) ) {
-
 
987
		case id_member_tag : {
-
 
988
		    /* Data members */
-
 
989
		    TYPE s = DEREF_type ( id_member_type ( fld ) ) ;
-
 
990
		    OFFSET off = DEREF_off ( id_member_off ( fld ) ) ;
-
 
991
		    gr = DEREF_graph ( id_member_base ( fld ) ) ;
-
 
992
		    if ( !IS_NULL_graph ( gr ) ) {
-
 
993
			/* Check for virtual bases */
-
 
994
			DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
-
 
995
			if ( acc & dspec_mutable ) goto default_lab ;
-
 
996
		    }
-
 
997
		    use_id ( fld, 0 ) ;
-
 
998
		    *pt = s ;
-
 
999
		    return ( off ) ;
-
 
1000
		}
-
 
1001
		case id_ambig_tag : {
-
 
1002
		    /* Ambiguous members */
-
 
1003
		    IGNORE report_ambiguous ( fld, 0, 1, 0 ) ;
-
 
1004
		    break ;
-
 
1005
		}
1013
		}
-
 
1014
		gr = is_subfield(ns, id);
-
 
1015
		if (!IS_NULL_graph(gr)) {
-
 
1016
			IDENTIFIER fld = search_subfield(ns, gr, id);
-
 
1017
			switch (TAG_id(fld)) {
-
 
1018
			case id_member_tag: {
-
 
1019
				/* Data members */
-
 
1020
				TYPE s = DEREF_type(id_member_type(fld));
-
 
1021
				OFFSET off = DEREF_off(id_member_off(fld));
-
 
1022
				gr = DEREF_graph(id_member_base(fld));
-
 
1023
				if (!IS_NULL_graph(gr)) {
-
 
1024
					/* Check for virtual bases */
-
 
1025
					DECL_SPEC acc =
-
 
1026
					    DEREF_dspec(graph_access(gr));
-
 
1027
					if (acc & dspec_mutable) {
-
 
1028
						goto default_lab;
-
 
1029
					}
-
 
1030
				}
-
 
1031
				use_id(fld, 0);
-
 
1032
				*pt = s;
-
 
1033
				return (off);
-
 
1034
			}
-
 
1035
			case id_ambig_tag:
-
 
1036
				/* Ambiguous members */
-
 
1037
				IGNORE report_ambiguous(fld, 0, 1, 0);
-
 
1038
				break;
1006
		case id_undef_tag : {
1039
			case id_undef_tag: {
1007
		    /* Undefined members */
1040
				/* Undefined members */
1008
		    HASHID nm = DEREF_hashid ( id_name ( fld ) ) ;
1041
				HASHID nm = DEREF_hashid(id_name(fld));
1009
		    report ( crt_loc, ERR_lookup_qual_undef ( nm, ns ) ) ;
1042
				report(crt_loc, ERR_lookup_qual_undef(nm, ns));
-
 
1043
				break;
-
 
1044
			}
-
 
1045
			default:
-
 
1046
default_lab: {
-
 
1047
		     /* Other members */
-
 
1048
		     ERROR err = ERR_expr_const_off_mem(fld);
-
 
1049
		     err = concat_error(err, ERR_token_mem_off());
-
 
1050
		     report(crt_loc, err);
1010
		    break ;
1051
		     break;
-
 
1052
	     }
-
 
1053
			}
-
 
1054
		} else {
-
 
1055
			/* id is not a member of ns */
-
 
1056
			report(crt_loc, ERR_lookup_qual_bad(id, ns));
1011
		}
1057
		}
1012
		default :
-
 
1013
		default_lab : {
-
 
1014
		    /* Other members */
-
 
1015
		    ERROR err = ERR_expr_const_off_mem ( fld ) ;
-
 
1016
		    err = concat_error ( err, ERR_token_mem_off () ) ;
-
 
1017
		    report ( crt_loc, err ) ;
-
 
1018
		    break ;
-
 
1019
		}
-
 
1020
	    }
-
 
1021
	} else {
1058
	} else {
1022
	    /* id is not a member of ns */
-
 
1023
	    report ( crt_loc, ERR_lookup_qual_bad ( id, ns ) ) ;
-
 
1024
	}
-
 
1025
    } else {
-
 
1026
	if ( !IS_type_error ( t ) ) {
1059
		if (!IS_type_error(t)) {
1027
	    /* t is not a class type */
1060
			/* t is not a class type */
1028
	    string key = find_vocab ( lex_class ) ;
1061
			string key = find_vocab(lex_class);
1029
	    report ( crt_loc, ERR_expr_ref_dot_op ( t, key ) ) ;
1062
			report(crt_loc, ERR_expr_ref_dot_op(t, key));
1030
	}
1063
		}
1031
	cache_lookup = old_cache_lookup ;
1064
		cache_lookup = old_cache_lookup;
1032
    }
1065
	}
1033
    *pt = type_error ;
1066
	*pt = type_error;
1034
    return ( NULL_off ) ;
1067
	return (NULL_off);
1035
}
1068
}
1036
 
1069
 
1037
 
1070
 
1038
/*
1071
/*
1039
    FIND AN INDEX OFFSET
1072
    FIND AN INDEX OFFSET
1040
 
1073
 
1041
    This routine finds the offset of the eth member of the array type t.
1074
    This routine finds the offset of the eth member of the array type t.
1042
    The member type is returned via pt.  e must denote an integer constant
1075
    The member type is returned via pt.  e must denote an integer constant
1043
    expression.
1076
    expression.
1044
*/
1077
*/
1045
 
1078
 
1046
OFFSET offset_index
1079
OFFSET
1047
    PROTO_N ( ( t, e, pt ) )
-
 
1048
    PROTO_T ( TYPE t X EXP e X TYPE *pt )
1080
offset_index(TYPE t, EXP e, TYPE *pt)
1049
{
1081
{
1050
    if ( IS_type_array ( t ) ) {
1082
	if (IS_type_array(t)) {
1051
	OFFSET off ;
1083
		OFFSET off;
1052
	ERROR err = NULL_err ;
1084
		ERROR err = NULL_err;
1053
	TYPE s = DEREF_type ( type_array_sub ( t ) ) ;
1085
		TYPE s = DEREF_type(type_array_sub(t));
1054
	IGNORE make_nat_exp ( e, &err ) ;
1086
		IGNORE make_nat_exp(e, &err);
1055
	if ( !IS_NULL_err ( err ) ) {
1087
		if (!IS_NULL_err(err)) {
1056
	    err = concat_error ( err, ERR_expr_const_off_dim () ) ;
1088
			err = concat_error(err, ERR_expr_const_off_dim());
1057
	    err = concat_error ( err, ERR_token_mem_off () ) ;
1089
			err = concat_error(err, ERR_token_mem_off());
1058
	    report ( crt_loc, err ) ;
1090
			report(crt_loc, err);
1059
	}
1091
		}
1060
	check_bounds ( lex_array_Hop, t, e ) ;
1092
		check_bounds(lex_array_Hop, t, e);
1061
	off = make_off_mult ( s, e, 0 ) ;
1093
		off = make_off_mult(s, e, 0);
1062
	*pt = s ;
1094
		*pt = s;
1063
	return ( off ) ;
1095
		return (off);
1064
    }
1096
	}
1065
    if ( !IS_type_error ( t ) ) {
1097
	if (!IS_type_error(t)) {
1066
	ERROR err = ERR_expr_const_off_array ( t ) ;
1098
		ERROR err = ERR_expr_const_off_array(t);
1067
	err = concat_error ( err, ERR_token_mem_off () ) ;
1099
		err = concat_error(err, ERR_token_mem_off());
1068
	report ( crt_loc, err ) ;
1100
		report(crt_loc, err);
1069
    }
1101
	}
1070
    *pt = type_error ;
1102
	*pt = type_error;
1071
    return ( NULL_off ) ;
1103
	return (NULL_off);
1072
}
1104
}
1073
 
1105
 
1074
 
1106
 
1075
/*
1107
/*
1076
    ADD TWO OFFSETS
1108
    ADD TWO OFFSETS
1077
 
1109
 
1078
    This routine adds the two offsets a and b, either of which may be
1110
    This routine adds the two offsets a and b, either of which may be
1079
    null.
1111
    null.
1080
*/
1112
*/
1081
 
1113
 
1082
OFFSET offset_add
1114
OFFSET
1083
    PROTO_N ( ( a, b ) )
-
 
1084
    PROTO_T ( OFFSET a X OFFSET b )
1115
offset_add(OFFSET a, OFFSET b)
1085
{
1116
{
1086
    OFFSET off ;
1117
	OFFSET off;
1087
    if ( is_zero_offset ( a ) ) return ( b ) ;
1118
	if (is_zero_offset(a)) {
-
 
1119
		return (b);
-
 
1120
	}
1088
    if ( is_zero_offset ( b ) ) return ( a ) ;
1121
	if (is_zero_offset(b)) {
-
 
1122
		return (a);
-
 
1123
	}
1089
    MAKE_off_plus ( a, b, off ) ;
1124
	MAKE_off_plus(a, b, off);
1090
    return ( off ) ;
1125
	return (off);
1091
}
1126
}