if (!objc_is_public (datum, component))
return error_mark_node;
+ /* Detect Objective-C property syntax object.property. */
+ if (c_dialect_objc ()
+ && (ref = objc_maybe_build_component_ref (datum, component)))
+ return ref;
+
/* See if there is a field or component with name COMPONENT. */
if (code == RECORD_TYPE || code == UNION_TYPE)
arrays that are not lvalues (for example, members of structures returned
by functions).
+ For vector types, allow vector[i] but not i[vector], and create
+ *(((type*)&vectortype) + i) for the expression.
+
LOC is the location to use for the returned expression. */
tree
return error_mark_node;
if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
- && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
+ && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
+ /* Allow vector[index] but not index[vector]. */
+ && TREE_CODE (TREE_TYPE (array)) != VECTOR_TYPE)
{
tree temp;
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
{
- error_at (loc, "subscripted value is neither array nor pointer");
+ error_at (loc,
+ "subscripted value is neither array nor pointer nor vector");
+
return error_mark_node;
}
temp = array;
index = default_conversion (index);
gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
+
+ /* For vector[index], convert the vector to a
+ pointer of the underlying type. */
+ if (TREE_CODE (TREE_TYPE (array)) == VECTOR_TYPE)
+ {
+ tree type = TREE_TYPE (array);
+ tree type1;
+
+ if (TREE_CODE (index) == INTEGER_CST)
+ if (!host_integerp (index, 1)
+ || ((unsigned HOST_WIDE_INT) tree_low_cst (index, 1)
+ >= TYPE_VECTOR_SUBPARTS (TREE_TYPE (array))))
+ warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
+
+ c_common_mark_addressable_vec (array);
+ type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
+ type = build_pointer_type (type);
+ type1 = build_pointer_type (TREE_TYPE (array));
+ array = build1 (ADDR_EXPR, type1, array);
+ array = convert (type, array);
+ }
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{
build_constructor (return_type, 0),
false);
else
- rhs = fold_convert_loc (loc, return_type, integer_zero_node);
+ rhs = build_zero_cst (return_type);
return require_complete_type (build2 (COMPOUND_EXPR, return_type,
trap, rhs));
if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
return error_mark_node;
- if (!lvalue_or_else (lhs, lv_assign))
+ /* For ObjC properties, defer this check. */
+ if (!objc_is_property_ref (lhs) && !lvalue_or_else (lhs, lv_assign))
return error_mark_node;
if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
rhs_origtype = NULL_TREE;
}
+ if (c_dialect_objc ())
+ {
+ /* Check if we are modifying an Objective-C property reference;
+ if so, we need to generate setter calls. */
+ result = objc_maybe_build_modify_expr (lhs, newrhs);
+ if (result)
+ return result;
+
+ /* Else, do the check that we postponed for Objective-C. */
+ if (!lvalue_or_else (lhs, lv_assign))
+ return error_mark_node;
+ }
+
/* Give an error for storing in something that is 'const'. */
if (TYPE_READONLY (lhstype)
Also set SHORT_SHIFT if shifting rightward. */
case RSHIFT_EXPR:
- if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
+ if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
+ && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
&& code1 == INTEGER_TYPE)
{
if (TREE_CODE (op1) == INTEGER_CST)
/* Use the type of the value to be shifted. */
result_type = type0;
- /* Convert the shift-count to an integer, regardless of size
- of value being shifted. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ /* Convert the non vector shift-count to an integer, regardless
+ of size of value being shifted. */
+ if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
+ && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
op1 = convert (integer_type_node, op1);
/* Avoid converting op1 to result_type later. */
converted = 1;
break;
case LSHIFT_EXPR:
- if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
+ if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
+ && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
&& code1 == INTEGER_TYPE)
{
if (TREE_CODE (op1) == INTEGER_CST)
/* Use the type of the value to be shifted. */
result_type = type0;
- /* Convert the shift-count to an integer, regardless of size
- of value being shifted. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ /* Convert the non vector shift-count to an integer, regardless
+ of size of value being shifted. */
+ if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
+ && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
op1 = convert (integer_type_node, op1);
/* Avoid converting op1 to result_type later. */
converted = 1;