diff options
Diffstat (limited to 'gcc/cp/typeck.c')
-rw-r--r-- | gcc/cp/typeck.c | 240 |
1 files changed, 235 insertions, 5 deletions
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 40988c7c807..ac64d68a18e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1058,6 +1058,17 @@ comptypes (tree t1, tree t2, int strict) case COMPLEX_TYPE: return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)); + case VECTOR_TYPE: + /* This is a comparison of types. If both of them are opaque, + the types are identical as long as their size is equal; else + check if the underlying types are identical as well. */ + return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2) + && (targetm.vector_opaque_p (t1) + ? targetm.vector_opaque_p (t2) + : !targetm.vector_opaque_p (t2) + && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))); + break; + default: break; } @@ -1996,6 +2007,8 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name) routine directly because it expects the object to be of class type. */ ptrmem_type = TREE_TYPE (ptrmem); + /* APPLE LOCAL 2.95-ptmf-compatibility */ + if (!flag_apple_kext) my_friendly_assert (TYPE_PTRMEMFUNC_P (ptrmem_type), 20020804); member = lookup_member (ptrmem_type, member_name, /*protect=*/0, /*want_type=*/false); @@ -2278,7 +2291,10 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function))) { - tree idx, delta, e1, e2, e3, vtbl, basetype; + /* APPLE LOCAL begin 2.95-ptmf-compatibility */ + tree idx, delta, e1, e2, e3, vtbl = vtbl, basetype; + /* APPLE LOCAL 2.95-ptmf-compatibility turly 20020314 */ + tree delta2 = delta2; tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function)); tree instance_ptr = *instance_ptrptr; @@ -2310,6 +2326,17 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) /* Start by extracting all the information from the PMF itself. */ e3 = PFN_FROM_PTRMEMFUNC (function); delta = build_ptrmemfunc_access_expr (function, delta_identifier); + + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + if (flag_apple_kext) + { + idx = build_ptrmemfunc_access_expr (function, index_identifier); + idx = save_expr (default_conversion (idx)); + e1 = cp_build_binary_op (GE_EXPR, idx, integer_zero_node); + } + else + { + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ idx = build1 (NOP_EXPR, vtable_index_type, e3); switch (TARGET_PTRMEMFUNC_VBIT_LOCATION) { @@ -2327,6 +2354,19 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) abort (); } + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + } + /* DELTA2 is the amount by which to adjust the `this' pointer + to find the vtbl. */ + if (flag_apple_kext) + { + delta2 = build_ptrmemfunc_access_expr (function, + pfn_or_delta2_identifier); + delta2 = build_ptrmemfunc_access_expr (delta2, + delta2_identifier); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ + /* Convert down to the right base before using the instance. First use the type... */ basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)); @@ -2335,6 +2375,14 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1); if (instance_ptr == error_mark_node) return error_mark_node; + + /* APPLE LOCAL begin 2.95-ptmf-compatibility */ + if (flag_apple_kext) + /* Next extract the vtable pointer from the object. */ + vtbl = build (PLUS_EXPR,build_pointer_type (vtbl_ptr_type_node), + instance_ptr, cp_convert (ptrdiff_type_node, delta2)); + /* APPLE LOCAL end 2.95-ptmf-compatibility */ + /* ...and then the delta in the PMF. */ instance_ptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr), instance_ptr, delta); @@ -2342,11 +2390,28 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) /* Hand back the adjusted 'this' argument to our caller. */ *instance_ptrptr = instance_ptr; + /* APPLE LOCAL 2.95-ptmf-compatibility */ + if (!flag_apple_kext) /* Next extract the vtable pointer from the object. */ vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node), instance_ptr); vtbl = build_indirect_ref (vtbl, NULL); + /* APPLE LOCAL double destructor turly 20020301 */ +#ifdef ADJUST_VTABLE_INDEX + /* vptr hack already compensated for! */ + if (0) ADJUST_VTABLE_INDEX (idx, vtbl); +#endif + + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + /* 2.95-style indices are off by one. */ + if (flag_apple_kext) + { + idx = cp_build_binary_op (MINUS_EXPR, idx, integer_one_node); + idx = cp_build_binary_op (LSHIFT_EXPR, idx, integer_two_node); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ + /* Finally, extract the function pointer from the vtable. */ e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx)); e2 = build_indirect_ref (e2, NULL); @@ -3011,6 +3076,13 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, } else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1)) { + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + /* Shouldn't we use INDEX here rather than PFN? This seems to + work fine, though... */ + if (flag_apple_kext) + op0 = build_ptrmemfunc_access_expr (op0, index_identifier); + else + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier); op1 = cp_convert (TREE_TYPE (op0), integer_zero_node); result_type = TREE_TYPE (op0); @@ -4364,8 +4436,12 @@ tree build_compound_expr (tree lhs, tree rhs) { lhs = decl_constant_value (lhs); - lhs = convert_to_void (lhs, "left-hand operand of comma"); - + /* APPLE LOCAL begin AltiVec */ + lhs = convert_to_void (lhs, targetm.cast_expr_as_vector_init + ? NULL + : "left-hand operand of comma"); + /* APPLE LOCAL end AltiVec */ + if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; @@ -4409,6 +4485,13 @@ build_static_cast (tree type, tree expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; + /* APPLE LOCAL begin AltiVec */ + /* If we are casting to a vector type, treat the expression as a vector + initializer if this target supports it. */ + if (TREE_CODE (type) == VECTOR_TYPE && targetm.cast_expr_as_vector_init) + return vector_constructor_from_expr (expr, type); + /* APPLE LOCAL end AltiVec */ + if (processing_template_decl) { expr = build_min (STATIC_CAST_EXPR, type, expr); @@ -4598,6 +4681,13 @@ build_reinterpret_cast (tree type, tree expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; + /* APPLE LOCAL begin AltiVec */ + /* If we are casting to a vector type, treat the expression as a vector + initializer if this target supports it. */ + if (TREE_CODE (type) == VECTOR_TYPE && targetm.cast_expr_as_vector_init) + return vector_constructor_from_expr (expr, type); + /* APPLE LOCAL end AltiVec */ + if (processing_template_decl) { tree t = build_min (REINTERPRET_CAST_EXPR, type, expr); @@ -4675,6 +4765,14 @@ build_reinterpret_cast (tree type, tree expr) intype, type); return error_mark_node; } + + /* APPLE LOCAL begin don't sign-extend pointers cast to integers */ + if (TREE_CODE (type) == INTEGER_TYPE + && TREE_CODE (intype) == POINTER_TYPE + && TYPE_PRECISION (type) > TYPE_PRECISION (intype) + && TREE_UNSIGNED (type)) + expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 1), expr); + /* APPLE LOCAL end don't sign-extend pointers cast to integers */ return cp_convert (type, expr); } @@ -4760,6 +4858,13 @@ build_c_cast (tree type, tree expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; + /* APPLE LOCAL begin AltiVec */ + /* If we are casting to a vector type, treat the expression as a vector + initializer if this target supports it. */ + if (TREE_CODE (type) == VECTOR_TYPE && targetm.cast_expr_as_vector_init) + return vector_constructor_from_expr (expr, type); + /* APPLE LOCAL end AltiVec */ + if (processing_template_decl) { tree t = build_min (CAST_EXPR, type, @@ -4876,6 +4981,16 @@ build_c_cast (tree type, tree expr) value = decl_constant_value (value); + /* APPLE LOCAL begin don't sign-extend pointers cast to integers */ + if (TREE_CODE (type) == INTEGER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TYPE_PRECISION (type) > TYPE_PRECISION (otype) + && TREE_UNSIGNED (type)) + value = convert_force (c_common_type_for_size (POINTER_SIZE, 1), + value, + CONV_C_CAST); + /* APPLE LOCAL end don't sign-extend pointers cast to integers */ + ovalue = value; value = convert_force (type, value, CONV_C_CAST); @@ -5292,6 +5407,106 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn) tree delta_field; tree pfn_field; + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + { + /* Ooo-err, Missus. Cons up a 2.95-style ptmf struct given + gcc3-style inputs! Recall: + + struct ptmf2 { struct ptmf3 { + short __delta; __P __pfn; + short __index; ptrdiff_t __delta; + union { } + __P __pfn; + short __delta2; + } + } + + Won't this be fun. Much of this is snarfed from 2.95. + Note that the __delta2 val, if required, will always be __delta. */ + + tree subtype, pfn_or_delta2_field, idx, idx_field, delta2_field; + tree delta2 = integer_zero_node; + int ixval = 0; + int allconstant = 0, allsimple = 0; + + delta_field = TYPE_FIELDS (type); + idx_field = TREE_CHAIN (delta_field); + pfn_or_delta2_field = TREE_CHAIN (idx_field); + subtype = TREE_TYPE (pfn_or_delta2_field); + pfn_field = TYPE_FIELDS (subtype); + delta2_field = TREE_CHAIN (pfn_field); + + if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) + { + /* If the low bit of PFN is set, the virtual index is PFN >> 1. + Else it's nonvirtual. */ + allconstant = TREE_CONSTANT (pfn); + allsimple = !! initializer_constant_valid_p (pfn, TREE_TYPE (pfn)); + if (TREE_CODE (pfn) == INTEGER_CST && (TREE_INT_CST_LOW (pfn) & 1)) + { + /* It's a virtual function. PFN is the vt offset + 1. */ + + int vt_entry_sz = 4; + tree vt_entry_sz_tree = TYPE_SIZE_UNIT (vtable_entry_type); + if (TREE_CODE (vt_entry_sz_tree) == INTEGER_CST) + vt_entry_sz = TREE_INT_CST_LOW (vt_entry_sz_tree); + + ixval = (TREE_INT_CST_LOW (pfn) - 1); + ixval /= vt_entry_sz; + + /* Now add 2 for that spadgey VPTR index hack, plus one because + 2.95 indices are offset by 1. */ + ixval += 2 + 1; + + /* __delta2 is the same as __delta. */ + u = tree_cons (delta2_field, delta, NULL_TREE); + } + else + if (TREE_CODE (pfn) == INTEGER_CST && TREE_INT_CST_LOW (pfn) == 0) + { + /* NULL pfn. Just zero out everything. */ + ixval = 0; + pfn = integer_zero_node; + delta = integer_zero_node; + u = tree_cons (pfn_field, pfn, NULL_TREE); + } + else + { + ixval = -1; /* -1 ==> PFN is the pointer */ + u = tree_cons (pfn_field, pfn, NULL_TREE); + } + } + else /* Low bit of DELTA is set if we're virtual. */ + { + /* Don't know how to do this yet. Much like the above, probably. */ + abort (); + allconstant = TREE_CONSTANT (delta); + allsimple = !! initializer_constant_valid_p (delta, + TREE_TYPE (delta)); + + u = tree_cons (delta2_field, delta2, NULL_TREE); + } + + delta = convert_and_check (delta_type_node, delta); + idx = convert_and_check (delta_type_node, ssize_int (ixval)); + + allconstant = allconstant && TREE_CONSTANT (delta) && TREE_CONSTANT (idx); + allsimple = allsimple + && initializer_constant_valid_p (delta, TREE_TYPE (delta)) + && initializer_constant_valid_p (idx, TREE_TYPE (idx)); + + u = build (CONSTRUCTOR, subtype, NULL_TREE, u); + u = tree_cons (delta_field, delta, + tree_cons (idx_field, idx, + tree_cons (pfn_or_delta2_field, u, NULL_TREE))); + u = build (CONSTRUCTOR, type, NULL_TREE, u); + TREE_CONSTANT (u) = allconstant; + TREE_STATIC (u) = allconstant && allsimple; + return u; + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + /* Pull the FIELD_DECLs out of the type. */ pfn_field = TYPE_FIELDS (type); delta_field = TREE_CHAIN (pfn_field); @@ -5475,6 +5690,22 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn) tree pfn_from_ptrmemfunc (tree t) { + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + { + if (TREE_CODE (t) == PTRMEM_CST) + { + tree fn = PTRMEM_CST_MEMBER (t); + if (!DECL_VIRTUAL_P (fn)) + return convert (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)), + build_addr_func (fn)); + } + + t = build_ptrmemfunc_access_expr (t, pfn_or_delta2_identifier); + return build_ptrmemfunc_access_expr (t, pfn_identifier); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + if (TREE_CODE (t) == PTRMEM_CST) { tree delta; @@ -5562,8 +5793,7 @@ convert_for_assignment (tree type, tree rhs, coder = TREE_CODE (rhstype); if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE - && ((*targetm.vector_opaque_p) (type) - || (*targetm.vector_opaque_p) (rhstype))) + && vector_types_compatible_p (type, rhstype)) return convert (type, rhs); if (rhs == error_mark_node || rhstype == error_mark_node) |