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 62... Line 92...
62
#include "template.h"
92
#include "template.h"
63
#include "tok.h"
93
#include "tok.h"
64
#include "token.h"
94
#include "token.h"
65
#include "typeid.h"
95
#include "typeid.h"
66
#include "ustring.h"
96
#include "ustring.h"
67
 
97
 
68
 
98
 
69
/*
99
/*
70
    STANDARD CLASS NAMES
100
    STANDARD CLASS NAMES
71
 
101
 
72
    These variables are used to hold the names of the various built-in
102
    These variables are used to hold the names of the various built-in
73
    class types.  They are defined here as the majority are concerned
103
    class types.  They are defined here as the majority are concerned
74
    with run-time type information.
104
    with run-time type information.
75
*/
105
*/
76
 
106
 
77
static CONST char *std_name = "std" ;
107
static CONST char *std_name = "std";
78
static NAMESPACE std_namespace = NULL_nspace ;
108
static NAMESPACE std_namespace = NULL_nspace;
79
 
109
 
80
 
110
 
81
/*
111
/*
82
    FIND THE STANDARD NAMESPACE
112
    FIND THE STANDARD NAMESPACE
83
 
113
 
84
    This routine returns the std namespace if this has been declared.
114
    This routine returns the std namespace if this has been declared.
85
*/
115
*/
86
 
116
 
87
static NAMESPACE find_std_namespace
117
static NAMESPACE
88
    PROTO_Z ()
118
find_std_namespace(void)
89
{
119
{
90
    NAMESPACE ns = std_namespace ;
120
	NAMESPACE ns = std_namespace;
91
    if ( IS_NULL_nspace ( ns ) ) {
121
	if (IS_NULL_nspace(ns)) {
92
	string s = ustrlit ( std_name ) ;
122
		string s = ustrlit(std_name);
93
	if ( s == NULL ) {
123
		if (s == NULL) {
94
	    /* Use global namespace if std_name is not given */
124
			/* Use global namespace if std_name is not given */
95
	    ns = global_namespace ;
125
			ns = global_namespace;
96
	} else {
126
		} else {
97
	    /* Look up 'std' in the global namespace */
127
			/* Look up 'std' in the global namespace */
98
	    unsigned long h = hash ( s ) ;
128
			unsigned long h = hash(s);
99
	    HASHID nm = lookup_name ( s, h, 0, lex_identifier ) ;
129
			HASHID nm = lookup_name(s, h, 0, lex_identifier);
100
	    MEMBER mem = search_member ( global_namespace, nm, 0 ) ;
130
			MEMBER mem = search_member(global_namespace, nm, 0);
101
	    IDENTIFIER id = type_member ( mem, 2 ) ;
131
			IDENTIFIER id = type_member(mem, 2);
102
	    if ( !IS_NULL_id ( id ) && IS_id_nspace_name_etc ( id ) ) {
132
			if (!IS_NULL_id(id) && IS_id_nspace_name_etc(id)) {
103
		ns = DEREF_nspace ( id_nspace_name_etc_defn ( id ) ) ;
133
				ns = DEREF_nspace(id_nspace_name_etc_defn(id));
104
	    }
134
			}
-
 
135
		}
-
 
136
		std_namespace = ns;
105
	}
137
	}
106
	std_namespace = ns ;
-
 
107
    }
-
 
108
    return ( ns ) ;
138
	return (ns);
109
}
139
}
110
 
140
 
111
 
141
 
112
/*
142
/*
113
    SET THE STANDARD NAMESPACE
143
    SET THE STANDARD NAMESPACE
114
 
144
 
115
    This routine sets the std namespace according to the identifier id.
145
    This routine sets the std namespace according to the identifier id.
116
    The null identifier is used to indicate the global namespace.
146
    The null identifier is used to indicate the global namespace.
117
*/
147
*/
118
 
148
 
119
void set_std_namespace
149
void
120
    PROTO_N ( ( id ) )
-
 
121
    PROTO_T ( IDENTIFIER id )
150
set_std_namespace(IDENTIFIER id)
122
{
151
{
123
    std_name = NULL ;
152
	std_name = NULL;
124
    std_namespace = NULL_nspace ;
153
	std_namespace = NULL_nspace;
125
    if ( !IS_NULL_id ( id ) ) {
154
	if (!IS_NULL_id(id)) {
126
	HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
155
		HASHID nm = DEREF_hashid(id_name(id));
127
	if ( IS_hashid_name_etc ( nm ) ) {
156
		if (IS_hashid_name_etc(nm)) {
128
	    string s = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
157
			string s = DEREF_string(hashid_name_etc_text(nm));
129
	    std_name = strlit ( s ) ;
158
			std_name = strlit(s);
130
	}
159
		}
131
    }
160
	}
132
    IGNORE find_std_namespace () ;
161
	IGNORE find_std_namespace();
133
    return ;
162
	return;
134
}
163
}
135
 
164
 
136
 
165
 
137
/*
166
/*
138
    LOOK UP A STANDARD CLASS TYPE
167
    LOOK UP A STANDARD CLASS TYPE
139
 
168
 
140
    This routine looks up the standard class named s in the std namespace.
169
    This routine looks up the standard class named s in the std namespace.
141
    The null type is returned if the type has not been declared and, in
170
    The null type is returned if the type has not been declared and, in
142
    addition, an error is reported if err is true.
171
    addition, an error is reported if err is true.
143
*/
172
*/
144
 
173
 
145
TYPE find_std_type
174
TYPE
146
    PROTO_N ( ( s, type, err ) )
-
 
147
    PROTO_T ( CONST char *s X int type X int err )
175
find_std_type(CONST char *s, int type, int err)
148
{
176
{
149
    string us = ustrlit ( s ) ;
177
	string us = ustrlit(s);
150
    unsigned long h = hash ( us ) ;
178
	unsigned long h = hash(us);
151
    HASHID nm = lookup_name ( us, h, 0, lex_identifier ) ;
179
	HASHID nm = lookup_name(us, h, 0, lex_identifier);
152
    NAMESPACE ns = find_std_namespace () ;
180
	NAMESPACE ns = find_std_namespace();
153
    if ( !IS_NULL_nspace ( ns ) ) {
181
	if (!IS_NULL_nspace(ns)) {
154
	IDENTIFIER id = search_id ( ns, nm, 0, type ) ;
182
		IDENTIFIER id = search_id(ns, nm, 0, type);
155
	if ( !IS_NULL_id ( id ) && IS_id_class_name_etc ( id ) ) {
183
		if (!IS_NULL_id(id) && IS_id_class_name_etc(id)) {
156
	    TYPE t = DEREF_type ( id_class_name_etc_defn ( id ) ) ;
184
			TYPE t = DEREF_type(id_class_name_etc_defn(id));
157
	    return ( t ) ;
185
			return (t);
-
 
186
		}
-
 
187
	}
-
 
188
	if (err) {
-
 
189
		us = ustrlit(std_name);
-
 
190
		report(crt_loc, ERR_lib_builtin(us, nm));
158
	}
191
	}
159
    }
-
 
160
    if ( err ) {
-
 
161
	us = ustrlit ( std_name ) ;
-
 
162
	report ( crt_loc, ERR_lib_builtin ( us, nm ) ) ;
-
 
163
    }
-
 
164
    return ( NULL_type ) ;
192
	return (NULL_type);
165
}
193
}
166
 
194
 
167
 
195
 
168
/*
196
/*
169
    RUN-TIME TYPE INFORMATION ROUTINES
197
    RUN-TIME TYPE INFORMATION ROUTINES
Line 182... Line 210...
182
    returned by the typeid operation.  The variables type_bad_cast and
210
    returned by the typeid operation.  The variables type_bad_cast and
183
    type_bad_typeid represent the types 'bad_cast' and 'bad_typeid'
211
    type_bad_typeid represent the types 'bad_cast' and 'bad_typeid'
184
    thrown by the dynamic_cast and typeid operators.
212
    thrown by the dynamic_cast and typeid operators.
185
*/
213
*/
186
 
214
 
187
static TYPE type_info_ref = NULL_type ;
215
static TYPE type_info_ref = NULL_type;
188
static TYPE type_bad_cast = NULL_type ;
216
static TYPE type_bad_cast = NULL_type;
189
static TYPE type_bad_typeid = NULL_type ;
217
static TYPE type_bad_typeid = NULL_type;
190
 
218
 
191
 
219
 
192
/*
220
/*
193
    GET THE TYPE_INFO TYPE
221
    GET THE TYPE_INFO TYPE
194
 
222
 
195
    This routine returns the type of the typeid operator.  An internal
223
    This routine returns the type of the typeid operator.  An internal
196
    error is reported if this has not been initialised.
224
    error is reported if this has not been initialised.
197
*/
225
*/
198
 
226
 
199
TYPE get_type_info
227
TYPE
200
    PROTO_N ( ( op, t, err ) )
-
 
201
    PROTO_T ( int op X TYPE t X int err )
228
get_type_info(int op, TYPE t, int err)
202
{
229
{
203
    TYPE r = NULL_type ;
230
	TYPE r = NULL_type;
204
    if ( op == lex_typeid ) {
231
	if (op == lex_typeid) {
205
	r = type_info_ref ;
232
		r = type_info_ref;
206
	if ( IS_NULL_type ( r ) ) {
233
		if (IS_NULL_type(r)) {
207
	    r = find_std_type ( "type_info", 1, err ) ;
234
			r = find_std_type("type_info", 1, err);
208
	    if ( IS_NULL_type ( r ) ) {
235
			if (IS_NULL_type(r)) {
209
		if ( err ) {
236
				if (err) {
210
		    r = type_error ;
237
					r = type_error;
-
 
238
				} else {
-
 
239
					CV_SPEC cv = (cv_lvalue | cv_const);
-
 
240
					MAKE_type_dummy(cv, TOK_typeid_type, r);
-
 
241
				}
-
 
242
			} else {
-
 
243
				/* Form 'lvalue const type_info' */
-
 
244
				r = qualify_type(r,(cv_lvalue | cv_const), 0);
-
 
245
				type_info_ref = r;
-
 
246
			}
-
 
247
		}
-
 
248
	} else {
-
 
249
		if (IS_type_compound(t)) {
-
 
250
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
-
 
251
			VIRTUAL vt = DEREF_virt(ctype_virt(ct));
-
 
252
			if (!IS_NULL_virt(vt)) {
-
 
253
				/* Form array of pointers to members */
-
 
254
				unsigned long m = DEREF_ulong(virt_no(vt));
-
 
255
				NAT n = make_nat_value(m + VIRTUAL_EXTRA);
-
 
256
				r = copy_typedef(NULL_id, type_func_void,
-
 
257
						 cv_none);
-
 
258
				MAKE_type_ptr_mem(cv_const, ct, r, r);
-
 
259
				MAKE_type_array(cv_lvalue, r, n, r);
-
 
260
			}
211
		} else {
261
		} else {
-
 
262
			if (is_templ_type(t)) {
-
 
263
				r = t;
-
 
264
			}
-
 
265
		}
-
 
266
		if (IS_NULL_type(r)) {
212
		    CV_SPEC cv = ( cv_lvalue | cv_const ) ;
267
			/* No virtual function table */
213
		    MAKE_type_dummy ( cv, TOK_typeid_type, r ) ;
268
			report(crt_loc, ERR_expr_typeid_vtable(op));
214
		}
269
		}
215
	    } else {
-
 
216
		/* Form 'lvalue const type_info' */
-
 
217
		r = qualify_type ( r, ( cv_lvalue | cv_const ), 0 ) ;
-
 
218
		type_info_ref = r ;
-
 
219
	    }
-
 
220
	}
-
 
221
    } else {
-
 
222
	if ( IS_type_compound ( t ) ) {
-
 
223
	    CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
-
 
224
	    VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
-
 
225
	    if ( !IS_NULL_virt ( vt ) ) {
-
 
226
		/* Form array of pointers to members */
-
 
227
		unsigned long m = DEREF_ulong ( virt_no ( vt ) ) ;
-
 
228
		NAT n = make_nat_value ( m + VIRTUAL_EXTRA ) ;
-
 
229
		r = copy_typedef ( NULL_id, type_func_void, cv_none ) ;
-
 
230
		MAKE_type_ptr_mem ( cv_const, ct, r, r ) ;
-
 
231
		MAKE_type_array ( cv_lvalue, r, n, r ) ;
-
 
232
	    }
-
 
233
	} else {
-
 
234
	    if ( is_templ_type ( t ) ) r = t ;
-
 
235
	}
-
 
236
	if ( IS_NULL_type ( r ) ) {
-
 
237
	    /* No virtual function table */
-
 
238
	    report ( crt_loc, ERR_expr_typeid_vtable ( op ) ) ;
-
 
239
	}
270
	}
240
    }
-
 
241
    return ( r ) ;
271
	return (r);
242
}
272
}
243
 
273
 
244
 
274
 
245
/*
275
/*
246
    THROW A STANDARD EXCEPTION
276
    THROW A STANDARD EXCEPTION
247
 
277
 
248
    This routine returns an expression corresponding to throwing the
278
    This routine returns an expression corresponding to throwing the
249
    'bad_cast' or 'bad_typeid' types (as indicated by s and pr).  An
279
    'bad_cast' or 'bad_typeid' types (as indicated by s and pr).  An
250
    error is reported if this type has not been declared.
280
    error is reported if this type has not been declared.
251
*/
281
*/
252
 
282
 
253
static EXP throw_bad_op
283
static EXP
254
    PROTO_N ( ( s, pr ) )
-
 
255
    PROTO_T ( CONST char *s X TYPE *pr )
284
throw_bad_op(CONST char *s, TYPE *pr)
256
{
285
{
257
    EXP e ;
286
	EXP e;
258
    TYPE r = *pr ;
287
	TYPE r = *pr;
259
    if ( IS_NULL_type ( r ) ) {
288
	if (IS_NULL_type(r)) {
260
	r = find_std_type ( s, 1, 1 ) ;
289
		r = find_std_type(s, 1, 1);
261
	if ( IS_NULL_type ( r ) ) return ( NULL_exp ) ;
290
		if (IS_NULL_type(r)) {
-
 
291
			return (NULL_exp);
-
 
292
		}
262
	*pr = r ;
293
		*pr = r;
263
    }
294
	}
264
    e = make_func_cast_exp ( r, NULL_list ( EXP ) ) ;
295
	e = make_func_cast_exp(r, NULL_list(EXP));
265
    e = make_throw_exp ( e, 0 ) ;
296
	e = make_throw_exp(e, 0);
266
    return ( e ) ;
297
	return (e);
267
}
298
}
268
 
299
 
269
 
300
 
270
/*
301
/*
271
    FIND A TYPEID ARGUMENT
302
    FIND A TYPEID ARGUMENT
272
 
303
 
Line 274... Line 305...
274
    the rule 'p [i]' -> '*p'.  Unfortunately '*( p + i )' which is otherwise
305
    the rule 'p [i]' -> '*p'.  Unfortunately '*( p + i )' which is otherwise
275
    identical to 'p [i]' is not treated in the same manner.  The result
306
    identical to 'p [i]' is not treated in the same manner.  The result
276
    is the address of a.
307
    is the address of a.
277
*/
308
*/
278
 
309
 
279
static EXP typeid_arg
310
static EXP
280
    PROTO_N ( ( op, a ) )
-
 
281
    PROTO_T ( int op X EXP a )
311
typeid_arg(int op, EXP a)
282
{
312
{
283
    while ( IS_exp_paren ( a ) ) {
313
	while (IS_exp_paren(a)) {
284
	/* Remove any brackets */
314
		/* Remove any brackets */
285
	a = DEREF_exp ( exp_paren_arg ( a ) ) ;
315
		a = DEREF_exp(exp_paren_arg(a));
286
    }
-
 
287
    if ( IS_exp_indir ( a ) ) {
-
 
288
	int i = DEREF_int ( exp_indir_index ( a ) ) ;
-
 
289
	a = DEREF_exp ( exp_indir_ptr ( a ) ) ;
-
 
290
	if ( i && IS_exp_add_ptr ( a ) ) {
-
 
291
	    OFFSET off = DEREF_off ( exp_add_ptr_off ( a ) ) ;
-
 
292
	    if ( !is_const_offset ( off, 2, 0 ) ) {
-
 
293
		report ( crt_loc, ERR_expr_typeid_index ( op ) ) ;
-
 
294
	    }
-
 
295
	    a = DEREF_exp ( exp_add_ptr_ptr ( a ) ) ;
-
 
296
	}
316
	}
-
 
317
	if (IS_exp_indir(a)) {
-
 
318
		int i = DEREF_int(exp_indir_index(a));
-
 
319
		a = DEREF_exp(exp_indir_ptr(a));
-
 
320
		if (i && IS_exp_add_ptr(a)) {
-
 
321
			OFFSET off = DEREF_off(exp_add_ptr_off(a));
-
 
322
			if (!is_const_offset(off, 2, 0)) {
-
 
323
				report(crt_loc, ERR_expr_typeid_index(op));
-
 
324
			}
-
 
325
			a = DEREF_exp(exp_add_ptr_ptr(a));
-
 
326
		}
297
    } else {
327
	} else {
298
	TYPE t = DEREF_type ( exp_type ( a ) ) ;
328
		TYPE t = DEREF_type(exp_type(a));
299
	MAKE_type_ptr ( cv_none, t, t ) ;
329
		MAKE_type_ptr(cv_none, t, t);
300
	MAKE_exp_address ( t, a, a ) ;
330
		MAKE_exp_address(t, a, a);
301
    }
331
	}
302
    return ( a ) ;
332
	return (a);
303
}
333
}
304
 
334
 
305
 
335
 
306
/*
336
/*
307
    CONSTRUCT A TYPEID EXPRESSION
337
    CONSTRUCT A TYPEID EXPRESSION
Line 310... Line 340...
310
    for an expression a.  n gives the number of side effects in a.  Note
340
    for an expression a.  n gives the number of side effects in a.  Note
311
    that suppress_usage is true during the evaluation of a and in this
341
    that suppress_usage is true during the evaluation of a and in this
312
    routine.  If it turns out that the expression is used (because it is
342
    routine.  If it turns out that the expression is used (because it is
313
    an lvalue of polymorphic type) then mark_used needs to be called
343
    an lvalue of polymorphic type) then mark_used needs to be called
314
    to mark any variable uses which have been missed.
344
    to mark any variable uses which have been missed.
315
*/
345
*/
316
 
346
 
317
EXP make_typeid_exp
347
EXP
318
    PROTO_N ( ( op, a, n ) )
-
 
319
    PROTO_T ( int op X EXP a X int n )
348
make_typeid_exp(int op, EXP a, int n)
320
{
349
{
321
    EXP e ;
350
	EXP e;
322
    TYPE t ;
351
	TYPE t;
323
    CV_SPEC cv ;
352
	CV_SPEC cv;
324
    a = convert_reference ( a, REF_NORMAL ) ;
353
	a = convert_reference(a, REF_NORMAL);
325
    a = convert_none ( a ) ;
354
	a = convert_none(a);
326
    a = convert_bitfield ( a ) ;
355
	a = convert_bitfield(a);
327
    t = DEREF_type ( exp_type ( a ) ) ;
356
	t = DEREF_type(exp_type(a));
328
    if ( is_templ_type ( t ) ) {
357
	if (is_templ_type(t)) {
329
	/* Allow for template types */
358
		/* Allow for template types */
330
	TYPE r = get_type_info ( op, t, 1 ) ;
359
		TYPE r = get_type_info(op, t, 1);
331
	MAKE_exp_op ( r, op, a, NULL_exp, e ) ;
360
		MAKE_exp_op(r, op, a, NULL_exp, e);
332
	return ( e ) ;
361
		return (e);
333
    }
362
	}
334
    cv = DEREF_cv ( type_qual ( t ) ) ;
363
	cv = DEREF_cv(type_qual(t));
335
    if ( ( cv & cv_lvalue ) && IS_type_compound ( t ) ) {
364
	if ((cv & cv_lvalue) && IS_type_compound(t)) {
336
	CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
365
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
337
	CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
366
		CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
338
	if ( ci & cinfo_polymorphic ) {
367
		if (ci & cinfo_polymorphic) {
339
	    /* lvalue of polymorphic type */
368
			/* lvalue of polymorphic type */
340
	    TYPE r = get_type_info ( op, t, 1 ) ;
369
			TYPE r = get_type_info(op, t, 1);
341
	    int use = suppress_usage ;
370
			int use = suppress_usage;
-
 
371
			if (use) {
342
	    if ( use ) suppress_usage-- ;
372
				suppress_usage--;
-
 
373
			}
343
	    a = typeid_arg ( op, a ) ;
374
			a = typeid_arg(op, a);
344
	    mark_used ( a ) ;
375
			mark_used(a);
345
	    if ( know_type ( a ) != 1 ) {
376
			if (know_type(a)!= 1) {
346
		/* Can throw 'bad_typeid' */
377
				/* Can throw 'bad_typeid' */
347
		EXP b = throw_bad_op ( "bad_typeid", &type_bad_typeid ) ;
378
				EXP b = throw_bad_op("bad_typeid",
-
 
379
						     &type_bad_typeid);
348
		t = DEREF_type ( exp_type ( a ) ) ;
380
				t = DEREF_type(exp_type(a));
349
		MAKE_exp_dummy ( t, a, LINK_NONE, NULL_off, 1, a ) ;
381
				MAKE_exp_dummy(t, a, LINK_NONE, NULL_off, 1, a);
350
		MAKE_exp_rtti ( r, a, b, op, e ) ;
382
				MAKE_exp_rtti(r, a, b, op, e);
351
		suppress_usage = use ;
383
				suppress_usage = use;
352
		return ( e ) ;
384
				return (e);
353
	    }
385
			}
354
	    suppress_usage = use ;
386
			suppress_usage = use;
-
 
387
		}
355
	}
388
	}
356
    }
389
	if (n) {
357
    if ( n ) report ( crt_loc, ERR_expr_typeid_side ( op ) ) ;
390
		report(crt_loc, ERR_expr_typeid_side(op));
-
 
391
	}
358
    free_exp ( a, 2 ) ;
392
	free_exp(a, 2);
359
    e = make_typeid_type ( op, t, 0 ) ;
393
	e = make_typeid_type(op, t, 0);
360
    return ( e ) ;
394
	return (e);
361
}
395
}
362
 
396
 
363
 
397
 
364
/*
398
/*
365
    CONSTRUCT A TYPEID TYPE EXPRESSION
399
    CONSTRUCT A TYPEID TYPE EXPRESSION
366
 
400
 
367
    This routine constructs the type identification expression 'op ( t )'
401
    This routine constructs the type identification expression 'op ( t )'
368
    for a type t.  The argument n gives the number of types defined in t.
402
    for a type t.  The argument n gives the number of types defined in t.
369
*/
403
*/
370
 
404
 
371
EXP make_typeid_type
405
EXP
372
    PROTO_N ( ( op, t, n ) )
-
 
373
    PROTO_T ( int op X TYPE t X int n )
406
make_typeid_type(int op, TYPE t, int n)
374
{
407
{
375
    EXP e ;
408
	EXP e;
376
    TYPE r ;
409
	TYPE r;
377
    if ( n ) report ( crt_loc, ERR_expr_typeid_typedef ( op ) ) ;
-
 
378
    if ( IS_type_ref ( t ) ) {
-
 
379
	/* Remove reference component */
-
 
380
	t = DEREF_type ( type_ref_sub ( t ) ) ;
-
 
381
    }
410
	if (n) {
382
    if ( IS_type_compound ( t ) ) {
-
 
383
	/* Check for incomplete class types */
-
 
384
	ERROR err = check_incomplete ( t ) ;
-
 
385
	if ( !IS_NULL_err ( err ) ) {
-
 
386
	    err = concat_error ( err, ERR_expr_typeid_incompl ( op ) ) ;
411
		report(crt_loc, ERR_expr_typeid_typedef(op));
387
	    report ( crt_loc, err ) ;
-
 
388
	}
412
	}
-
 
413
	if (IS_type_ref(t)) {
-
 
414
		/* Remove reference component */
-
 
415
		t = DEREF_type(type_ref_sub(t));
-
 
416
	}
-
 
417
	if (IS_type_compound(t)) {
-
 
418
		/* Check for incomplete class types */
-
 
419
		ERROR err = check_incomplete(t);
-
 
420
		if (!IS_NULL_err(err)) {
-
 
421
			err = concat_error(err, ERR_expr_typeid_incompl(op));
-
 
422
			report(crt_loc, err);
389
    }
423
		}
-
 
424
	}
390
    t = qualify_type ( t, cv_none, 0 ) ;
425
	t = qualify_type(t, cv_none, 0);
391
    r = get_type_info ( op, t, 1 ) ;
426
	r = get_type_info(op, t, 1);
392
    MAKE_exp_rtti_type ( r, t, op, e ) ;
427
	MAKE_exp_rtti_type(r, t, op, e);
393
    return ( e ) ;
428
	return (e);
394
}
429
}
395
 
430
 
396
 
431
 
397
/*
432
/*
398
    CONSTRUCT A TEMPLATE DEPENDENT DYNAMIC CAST EXPRESSION
433
    CONSTRUCT A TEMPLATE DEPENDENT DYNAMIC CAST EXPRESSION
399
 
434
 
400
    This routine constructs a template dependent dynamic cast of the
435
    This routine constructs a template dependent dynamic cast of the
401
    expression a to the type t.
436
    expression a to the type t.
402
*/
437
*/
403
 
438
 
404
static EXP dynamic_cast_templ
439
static EXP
405
    PROTO_N ( ( t, a ) )
-
 
406
    PROTO_T ( TYPE t X EXP a )
440
dynamic_cast_templ(TYPE t, EXP a)
407
{
441
{
408
    EXP e ;
442
	EXP e;
409
    MAKE_exp_op ( t, lex_dynamic_Hcast, a, NULL_exp, e ) ;
443
	MAKE_exp_op(t, lex_dynamic_Hcast, a, NULL_exp, e);
410
    return ( e ) ;
444
	return (e);
411
}
445
}
412
 
446
 
413
 
447
 
414
/*
448
/*
415
    CONSTRUCT A DYNAMIC CAST EXPRESSION
449
    CONSTRUCT A DYNAMIC CAST EXPRESSION
416
 
450
 
417
    This routine constructs the expression 'dynamic_cast < t > ( a )'.
451
    This routine constructs the expression 'dynamic_cast < t > ( a )'.
418
    The argument n gives the number of types defined in t.
452
    The argument n gives the number of types defined in t.
419
*/
453
*/
420
 
454
 
421
EXP make_dynamic_cast_exp
455
EXP
422
    PROTO_N ( ( t, a, n ) )
-
 
423
    PROTO_T ( TYPE t X EXP a X int n )
456
make_dynamic_cast_exp(TYPE t, EXP a, int n)
424
{
457
{
425
    TYPE s ;
458
	TYPE s;
426
    CV_SPEC cv ;
459
	CV_SPEC cv;
427
    int ok = 1 ;
460
	int ok = 1;
428
    int ptr = 0 ;
461
	int ptr = 0;
429
    unsigned qual ;
462
	unsigned qual;
430
    EXP e = NULL_exp ;
463
	EXP e = NULL_exp;
431
    TYPE p = NULL_type ;
464
	TYPE p = NULL_type;
432
    ERROR err = NULL_err ;
465
	ERROR err = NULL_err;
433
    CLASS_TYPE ct = NULL_ctype ;
466
	CLASS_TYPE ct = NULL_ctype;
434
    CLASS_TYPE cs = NULL_ctype ;
467
	CLASS_TYPE cs = NULL_ctype;
435
 
468
 
436
    /* Can't define types */
469
	/* Can't define types */
-
 
470
	if (n) {
437
    if ( n ) report ( crt_loc, ERR_expr_cast_dynam_typedef () ) ;
471
		report(crt_loc, ERR_expr_cast_dynam_typedef());
-
 
472
	}
438
 
473
 
439
    /* Do reference conversion */
474
	/* Do reference conversion */
440
    a = convert_reference ( a, REF_NORMAL ) ;
475
	a = convert_reference(a, REF_NORMAL);
441
    s = DEREF_type ( exp_type ( a ) ) ;
476
	s = DEREF_type(exp_type(a));
442
    cv = DEREF_cv ( type_qual ( s ) ) ;
477
	cv = DEREF_cv(type_qual(s));
443
 
478
 
444
    /* Check target type */
479
	/* Check target type */
445
    if ( IS_type_token ( t ) ) {
480
	if (IS_type_token(t)) {
446
	if ( is_templ_type ( t ) ) {
481
		if (is_templ_type(t)) {
447
	    e = dynamic_cast_templ ( t, a ) ;
482
			e = dynamic_cast_templ(t, a);
448
	    return ( e ) ;
483
			return (e);
449
	}
484
		}
450
	t = expand_type ( t, 1 ) ;
485
		t = expand_type(t, 1);
451
    }
486
	}
452
    if ( IS_type_ptr ( t ) ) {
487
	if (IS_type_ptr(t)) {
453
	/* Pointer types */
488
		/* Pointer types */
454
	p = DEREF_type ( type_ptr_sub ( t ) ) ;
489
		p = DEREF_type(type_ptr_sub(t));
455
	if ( IS_type_token ( p ) ) {
490
		if (IS_type_token(p)) {
456
	    if ( is_templ_type ( p ) ) {
491
			if (is_templ_type(p)) {
457
		e = dynamic_cast_templ ( t, a ) ;
492
				e = dynamic_cast_templ(t, a);
458
		return ( e ) ;
493
				return (e);
459
	    }
494
			}
460
	    p = expand_type ( p, 1 ) ;
495
			p = expand_type(p, 1);
461
	}
496
		}
462
	if ( IS_type_top_etc ( p ) ) {
497
		if (IS_type_top_etc(p)) {
463
	    /* 'void *' allowed */
498
			/* 'void *' allowed */
464
	    ptr = 2 ;
499
			ptr = 2;
465
	} else if ( IS_type_compound ( p ) ) {
500
		} else if (IS_type_compound(p)) {
466
	    ct = DEREF_ctype ( type_compound_defn ( p ) ) ;
501
			ct = DEREF_ctype(type_compound_defn(p));
467
	    err = check_incomplete ( p ) ;
502
			err = check_incomplete(p);
468
	    if ( !IS_NULL_err ( err ) ) ok = 0 ;
503
			if (!IS_NULL_err(err)) {
-
 
504
				ok = 0;
-
 
505
			}
469
	    ptr = 1 ;
506
			ptr = 1;
470
	} else {
507
		} else {
471
	    ok = 0 ;
508
			ok = 0;
472
	}
509
		}
473
    } else if ( IS_type_ref ( t ) ) {
510
	} else if (IS_type_ref(t)) {
474
	p = DEREF_type ( type_ref_sub ( t ) ) ;
511
		p = DEREF_type(type_ref_sub(t));
475
	if ( IS_type_token ( p ) ) {
512
		if (IS_type_token(p)) {
476
	    if ( is_templ_type ( p ) ) {
513
			if (is_templ_type(p)) {
477
		e = dynamic_cast_templ ( t, a ) ;
514
				e = dynamic_cast_templ(t, a);
478
		return ( e ) ;
515
				return (e);
479
	    }
516
			}
480
	    p = expand_type ( p, 1 ) ;
517
			p = expand_type(p, 1);
481
	}
518
		}
482
	if ( IS_type_compound ( p ) ) {
519
		if (IS_type_compound(p)) {
483
	    ct = DEREF_ctype ( type_compound_defn ( p ) ) ;
520
			ct = DEREF_ctype(type_compound_defn(p));
484
	    err = check_incomplete ( p ) ;
521
			err = check_incomplete(p);
485
	    if ( !IS_NULL_err ( err ) ) ok = 0 ;
522
			if (!IS_NULL_err(err)) {
-
 
523
				ok = 0;
-
 
524
			}
486
	} else {
525
		} else {
487
	    ok = 0 ;
526
			ok = 0;
488
	}
527
		}
489
    } else {
528
	} else {
490
	ok = 0 ;
529
		ok = 0;
491
    }
530
	}
492
    if ( !ok ) {
531
	if (!ok) {
493
	/* Invalid target type */
532
		/* Invalid target type */
494
	IGNORE convert_lvalue ( e ) ;
533
		IGNORE convert_lvalue(e);
495
	err = concat_error ( err, ERR_expr_cast_dynam_type ( t ) ) ;
534
		err = concat_error(err, ERR_expr_cast_dynam_type(t));
496
	report ( crt_loc, err ) ;
535
		report(crt_loc, err);
497
	e = make_error_exp ( 0 ) ;
536
		e = make_error_exp(0);
498
	return ( e ) ;
-
 
499
    }
-
 
500
 
-
 
501
    /* Check operand type */
-
 
502
    if ( is_templ_type ( s ) ) {
-
 
503
	e = dynamic_cast_templ ( t, a ) ;
-
 
504
	return ( e ) ;
537
		return (e);
505
    }
-
 
506
    if ( ptr ) {
-
 
507
	if ( cv & cv_lvalue ) {
-
 
508
	    a = convert_lvalue ( a ) ;
-
 
509
	}
-
 
510
	if ( IS_type_token ( s ) ) {
-
 
511
	    s = expand_type ( s, 1 ) ;
-
 
512
	}
538
	}
-
 
539
 
-
 
540
	/* Check operand type */
-
 
541
	if (is_templ_type(s)) {
-
 
542
		e = dynamic_cast_templ(t, a);
-
 
543
		return (e);
-
 
544
	}
-
 
545
	if (ptr) {
-
 
546
		if (cv & cv_lvalue) {
-
 
547
			a = convert_lvalue(a);
-
 
548
		}
-
 
549
		if (IS_type_token(s)) {
-
 
550
			s = expand_type(s, 1);
-
 
551
		}
513
	if ( IS_type_ptr ( s ) ) {
552
		if (IS_type_ptr(s)) {
514
	    /* Argument must be a pointer */
553
			/* Argument must be a pointer */
515
	    TYPE q = DEREF_type ( type_ptr_sub ( s ) ) ;
554
			TYPE q = DEREF_type(type_ptr_sub(s));
516
	    if ( IS_type_token ( q ) ) {
555
			if (IS_type_token(q)) {
517
		if ( is_templ_type ( q ) ) {
556
				if (is_templ_type(q)) {
518
		    e = dynamic_cast_templ ( t, a ) ;
557
					e = dynamic_cast_templ(t, a);
519
		    return ( e ) ;
558
					return (e);
-
 
559
				}
-
 
560
				q = expand_type(q, 1);
-
 
561
			}
-
 
562
			if (IS_type_compound(q)) {
-
 
563
				cs = DEREF_ctype(type_compound_defn(q));
-
 
564
				err = check_incomplete(q);
-
 
565
				if (!IS_NULL_err(err)) {
-
 
566
					ok = 0;
-
 
567
				}
-
 
568
			} else {
-
 
569
				ok = 0;
-
 
570
			}
-
 
571
		} else {
-
 
572
			ok = 0;
-
 
573
		}
-
 
574
		if (!ok) {
-
 
575
			err = concat_error(err, ERR_expr_cast_dynam_ptr(s));
-
 
576
			report(crt_loc, err);
-
 
577
			e = make_error_exp(0);
-
 
578
			return (e);
520
		}
579
		}
521
		q = expand_type ( q, 1 ) ;
-
 
522
	    }
-
 
523
	    if ( IS_type_compound ( q ) ) {
-
 
524
		cs = DEREF_ctype ( type_compound_defn ( q ) ) ;
-
 
525
		err = check_incomplete ( q ) ;
-
 
526
		if ( !IS_NULL_err ( err ) ) ok = 0 ;
-
 
527
	    } else {
-
 
528
		ok = 0 ;
-
 
529
	    }
-
 
530
	} else {
580
	} else {
531
	    ok = 0 ;
-
 
532
	}
-
 
533
	if ( !ok ) {
-
 
534
	    err = concat_error ( err, ERR_expr_cast_dynam_ptr ( s ) ) ;
-
 
535
	    report ( crt_loc, err ) ;
-
 
536
	    e = make_error_exp ( 0 ) ;
-
 
537
	    return ( e ) ;
-
 
538
	}
-
 
539
    } else {
-
 
540
	/* Reference types */
581
		/* Reference types */
541
	if ( cv & cv_lvalue ) {
582
		if (cv & cv_lvalue) {
542
	    /* Argument must be an lvalue */
583
			/* Argument must be an lvalue */
543
	    if ( IS_type_token ( s ) ) {
584
			if (IS_type_token(s)) {
544
		s = expand_type ( s, 1 ) ;
585
				s = expand_type(s, 1);
545
	    }
586
			}
546
	    if ( IS_type_compound ( s ) ) {
587
			if (IS_type_compound(s)) {
547
		cs = DEREF_ctype ( type_compound_defn ( s ) ) ;
588
				cs = DEREF_ctype(type_compound_defn(s));
548
		err = check_incomplete ( s ) ;
589
				err = check_incomplete(s);
549
		if ( !IS_NULL_err ( err ) ) ok = 0 ;
590
				if (!IS_NULL_err(err)) {
-
 
591
					ok = 0;
-
 
592
				}
550
	    } else {
593
			} else {
551
		ok = 0 ;
594
				ok = 0;
552
	    }
595
			}
553
	} else {
596
		} else {
554
	    err = ERR_basic_lval_not () ;
597
			err = ERR_basic_lval_not();
555
	    ok = 0 ;
598
			ok = 0;
-
 
599
		}
-
 
600
		if (!ok) {
-
 
601
			err = concat_error(err, ERR_expr_cast_dynam_ref(s));
-
 
602
			report(crt_loc, err);
-
 
603
			e = make_error_exp(1);
-
 
604
			return (e);
-
 
605
		}
-
 
606
 
-
 
607
		/* Convert to pointers */
-
 
608
		t = rvalue_type(p);
-
 
609
		MAKE_type_ptr(cv_none, t, t);
-
 
610
		s = rvalue_type(s);
-
 
611
		MAKE_type_ptr(cv_none, s, s);
-
 
612
		MAKE_exp_address(s, a, a);
556
	}
613
	}
557
	if ( !ok ) {
-
 
558
	    err = concat_error ( err, ERR_expr_cast_dynam_ref ( s ) ) ;
-
 
559
	    report ( crt_loc, err ) ;
-
 
560
	    e = make_error_exp ( 1 ) ;
-
 
561
	    return ( e ) ;
-
 
562
	}
-
 
563
 
-
 
564
	/* Convert to pointers */
-
 
565
	t = rvalue_type ( p ) ;
-
 
566
	MAKE_type_ptr ( cv_none, t, t ) ;
-
 
567
	s = rvalue_type ( s ) ;
-
 
568
	MAKE_type_ptr ( cv_none, s, s ) ;
-
 
569
	MAKE_exp_address ( s, a, a ) ;
-
 
570
    }
-
 
571
 
614
 
572
    /* Check for qualification conversions */
615
	/* Check for qualification conversions */
573
    qual = check_qualifier ( t, s, 0 ) ;
616
	qual = check_qualifier(t, s, 0);
574
    if ( qual == QUAL_OK ) {
617
	if (qual == QUAL_OK) {
575
	/* Exact match */
618
		/* Exact match */
576
	e = a ;
619
		e = a;
577
    } else {
-
 
578
	if ( IS_exp_null ( a ) ) {
-
 
579
	    /* Null pointer conversion */
-
 
580
	    e = make_null_exp ( t ) ;
-
 
581
	} else if ( qual & QUAL_SIMILAR ) {
-
 
582
	    /* Qualification conversion */
-
 
583
	    MAKE_exp_cast ( t, CONV_QUAL, a, e ) ;
-
 
584
	} else {
620
	} else {
-
 
621
		if (IS_exp_null(a)) {
-
 
622
			/* Null pointer conversion */
-
 
623
			e = make_null_exp(t);
-
 
624
		} else if (qual & QUAL_SIMILAR) {
-
 
625
			/* Qualification conversion */
-
 
626
			MAKE_exp_cast(t, CONV_QUAL, a, e);
-
 
627
		} else {
585
	    /* Check for base class conversions */
628
			/* Check for base class conversions */
586
	    if ( ptr != 2 ) {
629
			if (ptr != 2) {
587
		GRAPH gr = find_base_class ( cs, ct, 1 ) ;
630
				GRAPH gr = find_base_class(cs, ct, 1);
588
		if ( !IS_NULL_graph ( gr ) ) {
631
				if (!IS_NULL_graph(gr)) {
589
		    /* Base class conversion */
632
					/* Base class conversion */
590
		    OFFSET off ;
633
					OFFSET off;
591
		    err = check_ambig_base ( gr ) ;
634
					err = check_ambig_base(gr);
592
		    if ( !IS_NULL_err ( err ) ) {
635
					if (!IS_NULL_err(err)) {
-
 
636
						ERROR err2 =
593
			ERROR err2 = ERR_conv_ptr_ambiguous () ;
637
						    ERR_conv_ptr_ambiguous();
594
			err = concat_error ( err, err2 ) ;
638
						err = concat_error(err, err2);
595
			err2 = ERR_expr_cast_dynam_bad () ;
639
						err2 = ERR_expr_cast_dynam_bad();
596
			err = concat_error ( err, err2 ) ;
640
						err = concat_error(err, err2);
597
			report ( crt_loc, err ) ;
641
						report(crt_loc, err);
598
		    }
642
					}
599
		    check_base_access ( gr ) ;
643
					check_base_access(gr);
600
		    off = DEREF_off ( graph_off ( gr ) ) ;
644
					off = DEREF_off(graph_off(gr));
601
		    e = make_base_cast ( t, a, off ) ;
645
					e = make_base_cast(t, a, off);
-
 
646
				}
-
 
647
			}
-
 
648
 
-
 
649
			/* Otherwise cs must be polymorphic */
-
 
650
			if (IS_NULL_exp(e)) {
-
 
651
				CLASS_INFO ci = DEREF_cinfo(ctype_info(cs));
-
 
652
				if (ci & cinfo_polymorphic) {
-
 
653
					if (ptr == 2) {
-
 
654
						/* Conversion to 'void *' */
-
 
655
						MAKE_exp_cast(t, CONV_PTR_VOID,
-
 
656
							      a, e);
-
 
657
					} else {
-
 
658
						/* Dynamic cast */
-
 
659
						EXP b = NULL_exp;
-
 
660
						if (ptr == 0) {
-
 
661
							/* Can throw 'bad_cast'
-
 
662
							 * for references */
-
 
663
							b = throw_bad_op("bad_cast", &type_bad_cast);
-
 
664
						}
-
 
665
						MAKE_exp_dummy(s, a, LINK_NONE,
-
 
666
							       NULL_off, 0, a);
-
 
667
						MAKE_exp_dyn_cast(t, a, b, e);
-
 
668
					}
-
 
669
				} else {
-
 
670
					err = ERR_expr_cast_dynam_poly(cs);
-
 
671
					report(crt_loc, err);
-
 
672
					e = make_error_exp(0);
-
 
673
					return (e);
-
 
674
				}
-
 
675
			}
602
		}
676
		}
603
	    }
-
 
604
 
677
 
605
	    /* Otherwise cs must be polymorphic */
678
		/* Check for casting away const-ness */
606
	    if ( IS_NULL_exp ( e ) ) {
-
 
607
		CLASS_INFO ci = DEREF_cinfo ( ctype_info ( cs ) ) ;
-
 
608
		if ( ci & cinfo_polymorphic ) {
-
 
609
		    if ( ptr == 2 ) {
679
		if (qual != QUAL_OK) {
610
			/* Conversion to 'void *' */
680
			err = NULL_err;
611
			MAKE_exp_cast ( t, CONV_PTR_VOID, a, e ) ;
681
			cast_away_const(qual, &err, CAST_DYNAMIC);
612
		    } else {
-
 
613
			/* Dynamic cast */
-
 
614
			EXP b = NULL_exp ;
682
			if (!IS_NULL_err(err)) {
615
			if ( ptr == 0 ) {
683
				err = concat_error(err,
616
			    /* Can throw 'bad_cast' for references */
684
						   ERR_expr_cast_dynam_bad());
617
			    b = throw_bad_op ( "bad_cast", &type_bad_cast ) ;
685
				report(crt_loc, err);
618
			}
686
			}
619
			MAKE_exp_dummy ( s, a, LINK_NONE, NULL_off, 0, a ) ;
-
 
620
			MAKE_exp_dyn_cast ( t, a, b, e ) ;
-
 
621
		    }
-
 
622
		} else {
-
 
623
		    err = ERR_expr_cast_dynam_poly ( cs ) ;
-
 
624
		    report ( crt_loc, err ) ;
-
 
625
		    e = make_error_exp ( 0 ) ;
-
 
626
		    return ( e ) ;
-
 
627
		}
687
		}
628
	    }
-
 
629
	}
688
	}
630
 
-
 
631
	/* Check for casting away const-ness */
-
 
632
	if ( qual != QUAL_OK ) {
689
	if (ptr == 0) {
633
	    err = NULL_err ;
-
 
634
	    cast_away_const ( qual, &err, CAST_DYNAMIC ) ;
-
 
635
	    if ( !IS_NULL_err ( err ) ) {
690
		/* Take indirection for references */
636
		err = concat_error ( err, ERR_expr_cast_dynam_bad () ) ;
-
 
637
		report ( crt_loc, err ) ;
691
		MAKE_exp_indir(p, e, e);
638
	    }
-
 
639
	}
692
	}
640
    }
-
 
641
    if ( ptr == 0 ) {
-
 
642
	/* Take indirection for references */
-
 
643
	MAKE_exp_indir ( p, e, e ) ;
-
 
644
    }
-
 
645
    return ( e ) ;
693
	return (e);
646
}
694
}
647
 
695
 
648
 
696
 
649
#endif /* LANGUAGE_CPP */
697
#endif /* LANGUAGE_CPP */