1 /*****************************************************************************/
5 /* Handle type conversions */
9 /* (C) 2002-2008 Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
52 /*****************************************************************************/
54 /*****************************************************************************/
58 static void DoConversion (ExprDesc* Expr, const Type* NewType)
59 /* Emit code to convert the given expression to a new type. */
66 /* Remember the old type */
69 /* If we're converting to void, we're done. Note: This does also cover a
70 * conversion void -> void.
72 if (IsTypeVoid (NewType)) {
73 ED_MakeRVal (Expr); /* Never an lvalue */
77 /* Don't allow casts from void to something else. */
78 if (IsTypeVoid (OldType)) {
79 Error ("Cannot convert from `void' to something else");
83 /* Get the sizes of the types. Since we've excluded void types, checking
84 * for known sizes makes sense here.
86 OldSize = CheckedSizeOf (OldType);
87 NewSize = CheckedSizeOf (NewType);
90 if (ED_IsLVal (Expr)) {
92 /* We have an lvalue. If the new size is smaller than the new one,
93 * we don't need to do anything. The compiler will generate code
94 * to load only the portion of the value that is actually needed.
95 * This works only on a little endian architecture, but that's
97 * If both sizes are equal, do also leave the value alone.
98 * If the new size is larger, we must convert the value.
100 if (NewSize > OldSize) {
101 /* Load the value into the primary */
102 LoadExpr (CF_NONE, Expr);
104 /* Emit typecast code */
105 g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR);
107 /* Value is now in primary and an rvalue */
108 ED_MakeRValExpr (Expr);
111 } else if (ED_IsLocAbs (Expr)) {
113 /* A cast of a constant numeric value to another type. Be sure
114 * to handle sign extension correctly.
117 /* Get the current and new size of the value */
118 unsigned OldBits = OldSize * 8;
119 unsigned NewBits = NewSize * 8;
121 /* Check if the new datatype will have a smaller range. If it
122 * has a larger range, things are ok, since the value is
123 * internally already represented by a long.
125 if (NewBits <= OldBits) {
127 /* Cut the value to the new size */
128 Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits));
130 /* If the new type is signed, sign extend the value */
131 if (!IsSignUnsigned (NewType)) {
132 if (Expr->IVal & (0x01UL << (NewBits-1))) {
133 /* Beware: Use the safe shift routine here. */
134 Expr->IVal |= shl_l (~0UL, NewBits);
141 /* The value is not a constant. If the sizes of the types are
142 * not equal, add conversion code. Be sure to convert chars
145 if (OldSize != NewSize) {
147 /* Load the value into the primary */
148 LoadExpr (CF_NONE, Expr);
150 /* Emit typecast code. */
151 g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR);
153 /* Value is now a rvalue in the primary */
154 ED_MakeRValExpr (Expr);
159 /* The expression has always the new type */
160 ReplaceType (Expr, NewType);
165 void TypeConversion (ExprDesc* Expr, Type* NewType)
166 /* Do an automatic conversion of the given expression to the new type. Output
167 * warnings or errors where this automatic conversion is suspicious or
173 printf ("Expr:\n=======================================\n");
174 PrintExprDesc (stdout, Expr);
175 printf ("Type:\n=======================================\n");
176 PrintType (stdout, NewType);
178 PrintRawType (stdout, NewType);
181 /* First, do some type checking */
182 if (IsTypeVoid (NewType) || IsTypeVoid (Expr->Type)) {
183 /* If one of the sides are of type void, output a more apropriate
186 Error ("Illegal type");
189 /* If Expr is a function, convert it to pointer to function */
190 if (IsTypeFunc(Expr->Type)) {
191 Expr->Type = PointerTo (Expr->Type);
194 /* If both types are equal, no conversion is needed */
195 if (TypeCmp (Expr->Type, NewType) >= TC_EQUAL) {
196 /* We're already done */
200 /* Check for conversion problems */
201 if (IsClassInt (NewType)) {
203 /* Handle conversions to int type */
204 if (IsClassPtr (Expr->Type)) {
205 /* Pointer -> int conversion. Convert array to pointer */
206 if (IsTypeArray (Expr->Type)) {
207 Expr->Type = ArrayToPtr (Expr->Type);
209 Warning ("Converting pointer to integer without a cast");
210 } else if (!IsClassInt (Expr->Type) && !IsClassFloat (Expr->Type)) {
211 Error ("Incompatible types");
214 } else if (IsClassFloat (NewType)) {
216 if (!IsClassFloat (Expr->Type) && !IsClassInt (Expr->Type)) {
217 Error ("Incompatible types");
220 } else if (IsClassPtr (NewType)) {
222 /* Handle conversions to pointer type */
223 if (IsClassPtr (Expr->Type)) {
225 /* Convert array to pointer */
226 if (IsTypeArray (Expr->Type)) {
227 Expr->Type = ArrayToPtr (Expr->Type);
230 /* Pointer to pointer assignment is valid, if:
231 * - both point to the same types, or
232 * - the rhs pointer is a void pointer, or
233 * - the lhs pointer is a void pointer.
235 if (!IsTypeVoid (Indirect (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) {
236 /* Compare the types */
237 switch (TypeCmp (NewType, Expr->Type)) {
239 case TC_INCOMPATIBLE:
240 Error ("Incompatible pointer types");
244 Error ("Pointer types differ in type qualifiers");
253 } else if (IsClassInt (Expr->Type)) {
254 /* Int to pointer assignment is valid only for constant zero */
255 if (!ED_IsConstAbsInt (Expr) || Expr->IVal != 0) {
256 Warning ("Converting integer to pointer without a cast");
259 Error ("Incompatible types");
264 /* Invalid automatic conversion */
265 Error ("Incompatible types");
269 /* Do the actual conversion */
270 DoConversion (Expr, NewType);
275 void TypeCast (ExprDesc* Expr)
276 /* Handle an explicit cast. */
278 Type NewType[MAXTYPELEN];
280 /* Skip the left paren */
289 /* Read the expression we have to cast */
292 /* Convert functions and arrays to "pointer to" object */
293 Expr->Type = PtrConversion (Expr->Type);
295 /* Convert the value. */
296 DoConversion (Expr, NewType);