return error_mark_node;
}
- if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
+ if (!COMPLETE_TYPE_P (type_info_type_node))
{
error ("must #include <typeinfo> before using typeid");
return error_mark_node;
if (type == error_mark_node)
return error_mark_node;
- if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
+ if (!COMPLETE_TYPE_P (type_info_type_node))
{
error ("must #include <typeinfo> before using typeid");
return error_mark_node;
FORMAT_VBASE_NAME (name, t);
field = lookup_field (parent, get_identifier (name), 0, 0);
- offset = size_binop (FLOOR_DIV_EXPR,
- DECL_FIELD_BITPOS (field),
+ offset = size_binop (FLOOR_DIV_EXPR, bit_position (field),
bitsize_int (BITS_PER_UNIT));
offset = convert (sizetype, offset);
}
{
enum tree_code tc = TREE_CODE (type);
tree exprtype;
- enum tree_code ec;
tree dcast_fn;
tree old_expr = expr;
+ char* errstr = NULL;
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
-
- exprtype = TREE_TYPE (expr);
- assert (exprtype != NULL_TREE);
- ec = TREE_CODE (exprtype);
-
+ /* T shall be a pointer or reference to a complete class type, or
+ `pointer to cv void''. */
switch (tc)
{
case POINTER_TYPE:
- if (ec == REFERENCE_TYPE)
- {
- expr = convert_from_reference (expr);
- exprtype = TREE_TYPE (expr);
- ec = TREE_CODE (exprtype);
- }
- if (ec != POINTER_TYPE)
- goto fail;
- if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
- goto fail;
- if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
- goto fail;
- if (!at_least_as_qualified_p (TREE_TYPE (type),
- TREE_TYPE (exprtype)))
- goto fail;
- if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
+ if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
break;
- /* else fall through */
case REFERENCE_TYPE:
- if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
- goto fail;
- if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
- goto fail;
+ if (! IS_AGGR_TYPE (TREE_TYPE (type)))
+ {
+ errstr = "target is not pointer or reference to class";
+ goto fail;
+ }
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
+ {
+ errstr = "target is not pointer or reference to complete type";
+ goto fail;
+ }
break;
- /* else fall through */
+
default:
+ errstr = "target is not pointer or reference";
goto fail;
}
- /* Apply trivial conversion T -> T& for dereferenced ptrs. */
- if (ec == RECORD_TYPE)
+ if (TREE_CODE (expr) == OFFSET_REF)
+ expr = resolve_offset_ref (expr);
+
+ exprtype = TREE_TYPE (expr);
+ assert (exprtype != NULL_TREE);
+
+ if (tc == POINTER_TYPE)
+ expr = convert_from_reference (expr);
+ else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
{
+ /* Apply trivial conversion T -> T& for dereferenced ptrs. */
exprtype = build_reference_type (exprtype);
expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
LOOKUP_NORMAL, NULL_TREE);
- ec = REFERENCE_TYPE;
}
- if (tc == REFERENCE_TYPE)
+ exprtype = TREE_TYPE (expr);
+
+ if (tc == POINTER_TYPE)
+ {
+ /* If T is a pointer type, v shall be an rvalue of a pointer to
+ complete class type, and the result is an rvalue of type T. */
+
+ if (TREE_CODE (exprtype) != POINTER_TYPE)
+ {
+ errstr = "source is not a pointer";
+ goto fail;
+ }
+ if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
+ {
+ errstr = "source is not a pointer to class";
+ goto fail;
+ }
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
+ {
+ errstr = "source is a pointer to incomplete type";
+ goto fail;
+ }
+ }
+ else
+ {
+ /* T is a reference type, v shall be an lvalue of a complete class
+ type, and the result is an lvalue of the type referred to by T. */
+
+ if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
+ {
+ errstr = "source is not of class type";
+ goto fail;
+ }
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
+ {
+ errstr = "source is of incomplete class type";
+ goto fail;
+ }
+
+ }
+
+ /* The dynamic_cast operator shall not cast away constness. */
+ if (!at_least_as_qualified_p (TREE_TYPE (type),
+ TREE_TYPE (exprtype)))
{
- if (ec != REFERENCE_TYPE)
- goto fail;
- if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
- goto fail;
- if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
- goto fail;
- if (!at_least_as_qualified_p (TREE_TYPE (type),
- TREE_TYPE (exprtype)))
- goto fail;
+ errstr = "conversion casts away constness";
+ goto fail;
}
/* If *type is an unambiguous accessible base class of *exprtype,
/* If we got here, we can't convert statically. Therefore,
dynamic_cast<D&>(b) (b an object) cannot succeed. */
- if (ec == REFERENCE_TYPE)
+ if (tc == REFERENCE_TYPE)
{
if (TREE_CODE (old_expr) == VAR_DECL
&& TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
tree expr2 = build_headof (expr1);
tree td1 = expr;
- if (ec == POINTER_TYPE)
+ if (tc == POINTER_TYPE)
td1 = build_indirect_ref (td1, NULL_PTR);
td1 = get_tinfo_decl_dynamic (td1);
{
tree tmp;
tree tinfo_ptr;
- tree ns = global_namespace;
+ tree ns = new_abi_rtti_p () ? abi_node : global_namespace;
const char *name;
- push_nested_namespace (ns);
+ push_nested_namespace (ns);
if (!new_abi_rtti_p ())
{
tinfo_ptr = build_pointer_type (tinfo_decl_type);
}
else
{
- if (flag_honor_std)
- {
- push_namespace (get_identifier ("std"));
- ns = current_namespace;
- }
tinfo_ptr = xref_tag (class_type_node,
get_identifier ("__class_type_info"),
1);
return ifnonnull (expr, result);
}
}
-
- cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype);
- return error_mark_node;
+ else
+ errstr = "source type is not polymorphic";
fail:
- cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
- expr, exprtype, type);
+ cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T' (%s)",
+ expr, exprtype, type, errstr);
return error_mark_node;
}
init = tree_cons (NULL_TREE, decay_conversion (name_string), init);
- init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse(init));
+ init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
init = tree_cons (NULL_TREE, init, NULL_TREE);
break;
case UNION_TYPE:
case RECORD_TYPE:
- if (!TYPE_SIZE (target_type))
+ if (!COMPLETE_TYPE_P (target_type))
{
/* FIXME: incomplete type. Awaiting specification. */
return NULL_TREE;
array_domain = build_index_type (build_int_2 (num_bases, 0));
base_array = build_array_type (base_desc_type_node, array_domain);
- if (flag_honor_std)
- push_namespace (get_identifier ("std"));
+ push_nested_namespace (abi_node);
desc = create_pseudo_type_info
("__vmi_class_type_info", num_bases,
build_lang_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
- if (flag_honor_std)
- pop_namespace ();
+ pop_nested_namespace (abi_node);
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
return desc;
if (bltn_desc_type_node)
return;
- if (flag_honor_std)
- push_namespace (get_identifier ("std"));
+ push_nested_namespace (abi_node);
ptr_type_info = build_pointer_type
(build_qualified_type
/* Pointer to member data type_info. Add pointer to the class, pointer
to the member's type info and qualifications flags. */
ptmd_desc_type_node = create_pseudo_type_info
- ("__ptr_to_member_type_info", 0,
+ ("__pointer_to_member_type_info", 0,
build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
NULL);
- if (flag_honor_std)
- pop_namespace ();
+ pop_nested_namespace (abi_node);
}
/* Emit the type_info descriptors which are guaranteed to be in the runtime
int ix;
tree bltn_type, dtor;
- if (flag_honor_std)
- push_namespace (get_identifier ("std"));
+ push_nested_namespace (abi_node);
bltn_type = xref_tag (class_type_node,
get_identifier ("__fundamental_type_info"), 1);
- if (flag_honor_std)
- pop_namespace ();
- if (!TYPE_SIZE (bltn_type))
+ pop_nested_namespace (abi_node);
+ if (!COMPLETE_TYPE_P (bltn_type))
return;
dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
if (DECL_EXTERNAL (dtor))