static void expand_generic_desc PROTO((tree, tree, const char *));
static tree throw_bad_cast PROTO((void));
static tree throw_bad_typeid PROTO((void));
-
-tree type_info_type_node;
-tree tinfo_fn_id;
-tree tinfo_fn_type;
\f
void
init_rtti_processing ()
tree bad = throw_bad_typeid ();
bad = build_compound_expr
- (expr_tree_cons (NULL_TREE, bad, build_expr_list
+ (tree_cons (NULL_TREE, bad, build_expr_list
(NULL_TREE, cp_convert (type, integer_zero_node))));
exp = build (COND_EXPR, type, cond, exp, bad);
}
TREE_PUBLIC (tdecl) = 1;
DECL_EXTERNAL (tdecl) = 1;
DECL_ARTIFICIAL (tdecl) = 1;
- pushdecl_top_level (tdecl);
+ push_to_top_level ();
+ pushdecl (tdecl);
cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
+ pop_from_top_level ();
pop_obstacks ();
DECL_ARTIFICIAL (d) = 1;
DECL_NOT_REALLY_EXTERN (d) = 1;
SET_DECL_TINFO_FN_P (d);
- TREE_TYPE (name) = copy_to_permanent (type);
+ TREE_TYPE (name) = type;
pushdecl_top_level (d);
make_function_rtl (d);
return error_mark_node;
}
- if (! flag_rtti)
- error ("requesting typeid with -fno-rtti");
-
if (processing_template_decl)
return build_min_nt (TYPEID_EXPR, type);
{
tree retval;
tree result, td1, td2, td3, elems, expr2;
+ tree static_type, target_type, boff;
/* If we got here, we can't convert statically. Therefore,
dynamic_cast<D&>(b) (b an object) cannot succeed. */
td1 = get_tinfo_fn_dynamic (expr);
td1 = decay_conversion (td1);
- td2 = decay_conversion
- (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
- td3 = decay_conversion
- (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
+ target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+ static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
+ td2 = decay_conversion (get_tinfo_fn (target_type));
+ td3 = decay_conversion (get_tinfo_fn (static_type));
+
+ /* Determine how T and V are related. */
+ boff = get_dynamic_cast_base_type (static_type, target_type);
elems = tree_cons
(NULL_TREE, td1, tree_cons
(NULL_TREE, td2, tree_cons
- (NULL_TREE, build_int_2 (1, 0), tree_cons
+ (NULL_TREE, boff, tree_cons
(NULL_TREE, expr2, tree_cons
- (NULL_TREE, td3, tree_cons
+ (NULL_TREE, td3, tree_cons
(NULL_TREE, expr1, NULL_TREE))))));
- dcast_fn = get_identifier ("__dynamic_cast");
+ dcast_fn = get_identifier ("__dynamic_cast_2");
if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
else
tmp = tree_cons
(NULL_TREE, TREE_TYPE (td1), tree_cons
(NULL_TREE, TREE_TYPE (td1), tree_cons
- (NULL_TREE, integer_type_node, tree_cons
+ (NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, TREE_TYPE (td1), tree_cons
(NULL_TREE, ptr_type_node, void_list_node))))));
{
expr1 = throw_bad_cast ();
expr1 = build_compound_expr
- (expr_tree_cons (NULL_TREE, expr1,
+ (tree_cons (NULL_TREE, expr1,
build_expr_list (NULL_TREE, cp_convert (type, integer_zero_node))));
TREE_TYPE (expr1) = type;
result = save_expr (result);
}
}
+ cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype);
+ return error_mark_node;
+
fail:
cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
expr, exprtype, type);
return error_mark_node;
if (processing_template_decl)
- return build_min (DYNAMIC_CAST_EXPR, copy_to_permanent (type), expr);
+ return build_min (DYNAMIC_CAST_EXPR, type, expr);
return convert_from_reference (build_dynamic_cast_1 (type, expr));
}
Note: these constructors always return the address of the descriptor
info, since that is simplest for their mutual interaction. */
-extern tree const_string_type_node;
-
/* Build an initializer for a __si_type_info node. */
static void
tree name_string = combine_strings (build_string (strlen (name)+1, name));
type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
- expand_expr_stmt (get_typeid_1 (type));
+ finish_expr_stmt (get_typeid_1 (type));
t = decay_conversion (get_tinfo_var (type));
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
- expand_expr_stmt (fn);
+ finish_expr_stmt (fn);
}
/* Build an initializer for a __class_type_info node. */
base_info_type_node = make_lang_type (RECORD_TYPE);
/* Actually const __user_type_info * */
- fields [0] = build_lang_field_decl
+ fields [0] = build_lang_decl
(FIELD_DECL, NULL_TREE,
build_pointer_type (build_qualified_type
(type_info_type_node,
TYPE_QUAL_CONST)));
- fields [1] = build_lang_field_decl
+ fields [1] = build_lang_decl
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1;
DECL_FIELD_SIZE (fields[1]) = 29;
- fields [2] = build_lang_field_decl
+ fields [2] = build_lang_decl
(FIELD_DECL, NULL_TREE, boolean_type_node);
DECL_BIT_FIELD (fields[2]) = 1;
DECL_FIELD_SIZE (fields[2]) = 1;
/* Actually enum access */
- fields [3] = build_lang_field_decl
+ fields [3] = build_lang_decl
(FIELD_DECL, NULL_TREE, integer_type_node);
DECL_BIT_FIELD (fields[3]) = 1;
DECL_FIELD_SIZE (fields[3]) = 2;
{
tree binfo = TREE_VEC_ELT (binfos, i);
- expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
+ finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
if (TREE_VIA_VIRTUAL (binfo))
(NULL_TREE, isvir, tree_cons
(NULL_TREE, access, NULL_TREE)))));
TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
- elts = expr_tree_cons (NULL_TREE, elt, elts);
+ elts = tree_cons (NULL_TREE, elt, elts);
base_cnt++;
}
#if 0
offset = BINFO_OFFSET (vb);
isvir = build_int_2 (1, 0);
- base_list = expr_tree_cons (NULL_TREE, base, base_list);
- isvir_list = expr_tree_cons (NULL_TREE, isvir, isvir_list);
- acc_list = expr_tree_cons (NULL_TREE, access, acc_list);
- off_list = expr_tree_cons (NULL_TREE, offset, off_list);
+ base_list = tree_cons (NULL_TREE, base, base_list);
+ isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
+ acc_list = tree_cons (NULL_TREE, access, acc_list);
+ off_list = tree_cons (NULL_TREE, offset, off_list);
base_cnt++;
vb = TREE_CHAIN (vb);
mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
- expand_expr_stmt (fn);
+ finish_expr_stmt (fn);
}
/* Build an initializer for a __pointer_type_info node. */
tree name_string = combine_strings (build_string (strlen (name)+1, name));
type = TREE_TYPE (type);
- expand_expr_stmt (get_typeid_1 (type));
+ finish_expr_stmt (get_typeid_1 (type));
t = decay_conversion (get_tinfo_var (type));
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
- expand_expr_stmt (fn);
+ finish_expr_stmt (fn);
}
/* Build an initializer for a __attr_type_info node. */
tree name_string = combine_strings (build_string (strlen (name)+1, name));
tree attrval = build_int_2 (TYPE_QUALS (type), 0);
- expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
+ finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), tree_cons
- (NULL_TREE, attrval, expr_tree_cons (NULL_TREE, t, NULL_TREE))));
+ (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
fn = get_identifier ("__rtti_attr");
if (IDENTIFIER_GLOBAL_VALUE (fn))
mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
- expand_expr_stmt (fn);
+ finish_expr_stmt (fn);
}
/* Build an initializer for a type_info node that just has a name. */
mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
- expand_expr_stmt (fn);
+ finish_expr_stmt (fn);
}
/* Generate the code for a type_info initialization function.
{
tree type = TREE_TYPE (DECL_NAME (fndecl));
tree tmp, addr, tdecl;
+ tree compound_stmt;
+ tree if_stmt;
+ tree then_clause;
if (at_eof)
{
return;
}
+ /* Declare the static typeinfo variable. */
tdecl = get_tinfo_var (type);
DECL_EXTERNAL (tdecl) = 0;
TREE_STATIC (tdecl) = 1;
DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
- start_function (NULL_TREE, fndecl, NULL_TREE, 1);
+ /* Begin processing the function. */
+ start_function (NULL_TREE, fndecl, NULL_TREE,
+ SF_DEFAULT | SF_PRE_PARSED);
+ DECL_DEFER_OUTPUT (fndecl) = 1;
store_parm_decls ();
clear_last_expr ();
- push_momentary ();
+
+ /* Begin the body of the function. */
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
+
+ /* For convenience, we save away the address of the static
+ variable. */
+ addr = decay_conversion (tdecl);
/* If the first word of the array (the vtable) is non-zero, we've already
initialized the object, so don't do it again. */
- addr = decay_conversion (tdecl);
+ if_stmt = begin_if_stmt ();
tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
tmp = build_indirect_ref (tmp, 0);
tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
- expand_start_cond (tmp, 0);
+ finish_if_stmt_cond (tmp, if_stmt);
+ then_clause = begin_compound_stmt (/*has_no_scope=*/0);
if (TREE_CODE (type) == FUNCTION_TYPE)
expand_generic_desc (tdecl, type, "__rtti_func");
else
my_friendly_abort (252);
- expand_end_cond ();
+ finish_compound_stmt (/*has_no_scope=*/0, then_clause);
+ finish_then_clause (if_stmt);
+ finish_if_stmt ();
/* OK, now return the type_info object. */
tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
tmp = build_indirect_ref (tmp, 0);
- c_expand_return (tmp);
- finish_function (lineno, 0, 0);
+ finish_return_stmt (tmp);
+ /* Finish the function body. */
+ finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+ expand_body (finish_function (lineno, 0));
}