Next: Associating types with identifiers
Up: The C type system
Previous: Conversions
Constraints on operators
Many of the subsections of Section 6.3 of the standard describe constraints
on the types of operands that a given operator can have.
This section formalizes those constraints, defining each C operator by an
INDICATION.
The constraints are described by a set of OPERators, each with a
specific type signature.
Each INDICATION is associated with a comma-separated list of the
OPERators that satisfy the standard's constraints on that C operator.
INDICATION
Subscript_Indication: Subscript_Op, Array_Subscript_Op, IndexString;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
Distinct subscripting operations are defined for each array type and
each pointer type other than TypeIs_VoidPointer.
The second operand is specified to be a TypeIs_unsigned_long, although
the standard specifies that it has integral type.
Any integral type can be converted to TypeIs_unsigned_long by means of
implicit conversions, so this specification is equivalent to that of the
standard.
The main reason for using TypeIs_unsigned_long is that OIL does not
permit sets as operand specifications within a class definition, but a
secondary reason is that this approach reduces the total number of
operators in the compiler's database.
INDICATION
Plus_Plus_Indication: Increment_Op, Ptr_Inc_Op;
Minus_Minus_Indication: Decrement_Op, Ptr_Dec_Op;
OPER
Increment_Op, Decrement_Op(TypeIs_Arithmetic): TypeIs_Arithmetic;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
INDICATION
Star_Indication: Ptr_Deref_Op, DerefString;
Amper_Indication: Ptr_Ref_Op;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
INDICATION
Plus_Indication: Plus_Op;
Minus_Indication: Minus_Op;
Tilde_Indication: Bitwise_Not_Op;
Bang_Indication: Logical_Not_Op;
Sizeof_Indication: Sizeof_op;
Cast_Indication: Cast_Op, Cast_IntegraltoPtr, Cast_VoidPtrtoPtr,
Cast_VoidVoid, CScalartoVoid;
SET TypeIs_CastResult = TypeIs_Scalar;
OPER
Plus_Op, Minus_Op(TypeIs_ArithPromoted): TypeIs_ArithPromoted;
Bitwise_Not_Op (TypeIs_IntegralPromoted): TypeIs_IntegralPromoted;
Logical_Not_Op (TypeIs_Scalar): TypeIs_int;
/* FIXME: sizeof is more constrained than this. Also, it has different
semantics in that the operand is not evaluated. May need another kind
of operator.
*/
Sizeof_op (TypeIs_void): TypeIs_int;
Cast_Op (TypeIs_Scalar): TypeIs_CastResult;
Cast_VoidVoid (TypeIs_void): TypeIs_void;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
By defining TypeIs_CastResult as being equal to TypeIs_Scalar and
then using these two set identifiers in defining Cast_Op, the
specification defines a cast from every element of TypeIs_Scalar to
every other element of TypeIs_Scalar.
If Cast_Op were defined with the signature (TypeIs_Scalar):
TypeIs_Scalar then the operand and result would be constrained to be
identical.
The definition of Cast_Op allows any pointer type to be cast
to any integral type:
There is an implicit conversion from any pointer type to
TypeIs_VoidPointer, which is an element of TypeIs_Scalar, and
every integral type is an element of TypeIs_CastResult.
Distinct cast operators are defined for each pointer
type other than TypeIs_VoidPointer to handle casts from
arbitrary integers and from TypeIs_VoidPointer to that pointer type.
The operand of the former is specified to be a TypeIs_unsigned_long,
although the standard specifies that it has integral type.
Any integral type can be converted to TypeIs_unsigned_long by means of
implicit conversions, so this specification is equivalent to that of the
standard.
The main reason for using TypeIs_unsigned_long is that OIL does not
permit sets as operand specifications within a class definition, but a
secondary reason is that this approach reduces the total number of
operators in the compiler's database.
The implicit conversion from any pointer type to TypeIs_VoidPointer,
combined with Cast_VoidPtrtoPtr, allows any pointer type to be cast to
any other pointer type.
(This includes pointers to function types.)
INDICATION
Star_Indication: MulOp;
Slash_Indication: DivOp;
Percent_Indication: ModOp;
Plus_Indication: AddOp,
Void_Ptr_Add_Op, Void_Ptr_Rev_Add_Op,
Ptr_Add_Op, Ptr_Rev_Add_Op;
Minus_Indication: SubOp,
Void_Ptr_Sub_Op, Ptr_Sub_Op, Ptr_Ptr_Sub_Op;
OPER
MulOp, DivOp,
AddOp, SubOp (TypeIs_Arithmetic, TypeIs_Arithmetic): TypeIs_Arithmetic;
ModOp (TypeIs_Integral, TypeIs_Integral): TypeIs_Integral;
Void_Ptr_Add_Op,
Void_Ptr_Sub_Op(TypeIs_VoidPointer, TypeIs_unsigned_long): TypeIs_VoidPointer;
Void_Ptr_Rev_Add_Op
(TypeIs_unsigned_long, TypeIs_VoidPointer): TypeIs_VoidPointer;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
INDICATION
Less_Less_Indication: Bit_Shift_Left_Op;
Greater_Greater_Indication: Bit_Shift_Right_Op;
Less_Indication: LessThan_Op, Ptr_LT_Op;
Greater_Indication: Greater_Op, Ptr_GT_Op;
Less_Equal_Indication: LessThan_Equal_Op, Ptr_LTE_Op;
Greater_Equal_Indication: Greater_Equal_Op, Ptr_GTE_Op;
SET TypeIs_ShiftCount = TypeIs_IntegralPromoted;
OPER
Bit_Shift_Right_Op,
Bit_Shift_Left_Op
(TypeIs_IntegralPromoted, TypeIs_ShiftCount): TypeIs_IntegralPromoted;
Greater_Op, LessThan_Op, Greater_Equal_Op,
LessThan_Equal_Op(TypeIs_Scalar, TypeIs_Scalar): TypeIs_int;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
INDICATION
Equal_Equal_Indication: Equality_Op, Ptr_Eq_Op;
Bang_Equal_Indication: Not_Equal_Op, Ptr_NEq_Op;
OPER
Equality_Op, Not_Equal_Op(TypeIs_Scalar, TypeIs_Scalar): TypeIs_int;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
INDICATION
Amper_Indication: Bitwise_And_Op;
Caret_Indication: Bitwise_XOr_Op;
Bar_Indication: Bitwise_Or_Op;
Amper_Amper_Indication: Logical_And_Op;
Bar_Bar_Indication: Logical_Or_Op;
Conditional_Indication: Arith_Cond_Op, Void_Cond_Op, Ptr_Cond_Op;
SET TypeIs_RHS_Scalar = TypeIs_Scalar;
OPER
Bitwise_And_Op, Bitwise_XOr_Op,
Bitwise_Or_Op(TypeIs_Integral, TypeIs_Integral): TypeIs_Integral;
Logical_And_Op,
Logical_Or_Op(TypeIs_Scalar, TypeIs_RHS_Scalar): TypeIs_int;
Arith_Cond_Op(TypeIs_Scalar,TypeIs_Arithmetic,TypeIs_Arithmetic): TypeIs_Arithmetic;
Void_Cond_Op (TypeIs_Scalar,TypeIs_Void,TypeIs_Void): TypeIs_Void;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
FIXME: The standard allows balancing of two compatible struct or union
types. The best way to handle this is probably to have a common type that
all such types can be coerced to, followed by more stringent testing.
INDICATION
Equal_Indication:
Assign_Op, Ptr_Assign_Op, Enum_Assign_Op,
Struct_Assign_Op, Union_Assign_Op, Ptr_Void_Assign_Op,
Ptr_Void_Void_Assign_Op;
SET TypeIs_RHS_Arithmetic = TypeIs_Arithmetic;
OPER
Assign_Op(TypeIs_Arithmetic, TypeIs_RHS_Arithmetic): TypeIs_Arithmetic;
Ptr_Void_Void_Assign_Op
(TypeIs_VoidPointer, TypeIs_VoidPointer): TypeIs_VoidPointer;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
INDICATION
Star_Equal_Indication: Mult_Eq_Op;
Slash_Equal_Indication: Div_Eq_Op;
Percent_Equal_Indication: Mod_Eq_Op;
Plus_Equal_Indication: Plus_Eq_Op, Ptr_Plus_Eq_Op;
Minus_Equal_Indication: Minus_Eq_Op, Ptr_Minus_Eq_Op;
Less_Less_Equal_Indication: Bitwise_Shift_Left_Eq_Op;
Greater_Greater_Equal_Indication: Bitwise_Shift_Right_Eq_Op;
Amper_Equal_Indication: Bitwise_And_Eq_Op;
Caret_Equal_Indication: Bitwise_XOr_Eq_Op;
Bar_Equal_Indication: Bitwise_Or_Eq_Op;
SET TypeIs_RHS_Integral = TypeIs_Integral;
OPER
Mult_Eq_Op, Div_Eq_Op, Plus_Eq_Op,
Minus_Eq_Op( TypeIs_Arithmetic, TypeIs_RHS_Arithmetic ) : TypeIs_Arithmetic;
Mod_Eq_Op, Bitwise_Shift_Left_Eq_Op, Bitwise_Shift_Right_Eq_Op,
Bitwise_And_Eq_Op, Bitwise_XOr_Eq_Op,
Bitwise_Or_Eq_Op( TypeIs_Integral, TypeIs_RHS_Integral ) : TypeIs_Integral;
This macro is defined in definitions 19, 20, 21, 22, 23, 24, 25, 26, 27, and 28.
This macro is invoked in definition 4.
Next: Associating types with identifiers
Up: The C type system
Previous: Conversions
2008-08-30