diff options
Diffstat (limited to 'contrib/gcc/cp/class.c')
-rw-r--r-- | contrib/gcc/cp/class.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index 82eede5..c1da654 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -401,6 +401,33 @@ convert_to_base (tree object, tree type, bool check_access) return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1); } +/* EXPR is an expression with class type. BASE is a base class (a + BINFO) of that class type. Returns EXPR, converted to the BASE + type. This function assumes that EXPR is the most derived class; + therefore virtual bases can be found at their static offsets. */ + +tree +convert_to_base_statically (tree expr, tree base) +{ + tree expr_type; + + expr_type = TREE_TYPE (expr); + if (!same_type_p (expr_type, BINFO_TYPE (base))) + { + tree pointer_type; + + pointer_type = build_pointer_type (expr_type); + expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1); + if (!integer_zerop (BINFO_OFFSET (base))) + expr = build (PLUS_EXPR, pointer_type, expr, + build_nop (pointer_type, BINFO_OFFSET (base))); + expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr); + expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr); + } + + return expr; +} + /* Virtual function things. */ @@ -6537,6 +6564,7 @@ build_self_reference () DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_ARTIFICIAL (value) = 1; + SET_DECL_SELF_REFERENCE_P (value); if (processing_template_decl) value = push_template_decl (value); |