1 /*****************************************************************************/
5 /* Handle type casts */
9 /* (C) 2002 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
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 /*****************************************************************************/
47 /*****************************************************************************/
49 /*****************************************************************************/
53 int TypeCast (ExprDesc* lval)
54 /* Handle an explicit cast. The function returns true if the resulting
55 * expression is an lvalue and false if not.
60 type NewType[MAXTYPELEN];
64 /* Skip the left paren */
73 /* Read the expression we have to cast */
76 /* If the expression is a function, treat it as pointer to function.
77 * If the expression is an array, treat it as pointer to first element.
79 if (IsTypeFunc (lval->Type)) {
80 lval->Type = PointerTo (lval->Type);
81 } else if (IsTypeArray (lval->Type)) {
82 lval->Type = ArrayToPtr (lval->Type);
85 /* Remember the old type */
88 /* If we're casting to void, we're done. Note: This does also cover a cast
91 if (IsTypeVoid (NewType)) {
92 k = 0; /* Never an lvalue */
96 /* Don't allow casts from void to something else. */
97 if (IsTypeVoid (OldType)) {
98 Error ("Cannot cast from `void' to something else");
102 /* Get the sizes of the types. Since we've excluded void types, checking
103 * for known sizes makes sense here.
105 OldSize = CheckedSizeOf (OldType);
106 NewSize = CheckedSizeOf (NewType);
108 /* Is this a cast of something into an integer? */
109 if (IsClassInt (NewType)) {
114 /* We have an lvalue. If the new size is smaller than the new one,
115 * we don't need to do anything. The compiler will generate code
116 * to load only the portion of the value that is actually needed.
117 * This works only on a little endian architecture, but that's
119 * If both sizes are equal, do also leave the value alone.
120 * If the new size is larger, we must convert the value.
122 if (NewSize > OldSize) {
123 /* Load the value into the primary */
124 exprhs (CF_NONE, k, lval);
126 /* Emit typecast code */
127 g_typecast (TypeOf (OldType), TypeOf (NewType));
129 /* Value is now in primary */
130 lval->Flags = E_MEXPR;
136 /* We have an rvalue. Check for a constant. */
137 if (lval->Flags == E_MCONST) {
139 /* A cast of a constant to an integer. Be sure to handle sign
140 * extension correctly.
143 /* Get the current and new size of the value */
144 unsigned OldBits = OldSize * 8;
145 unsigned NewBits = NewSize * 8;
147 /* Check if the new datatype will have a smaller range */
148 if (NewBits <= OldBits) {
150 /* Cut the value to the new size */
151 lval->ConstVal &= (0xFFFFFFFFUL >> (32 - NewBits));
153 /* If the new type is signed, sign extend the value */
154 if (!IsSignUnsigned (NewType)) {
155 lval->ConstVal |= ((~0L) << NewBits);
160 /* Sign extend the value if needed */
161 if (!IsSignUnsigned (OldType) && !IsSignUnsigned (NewType)) {
162 if (lval->ConstVal & (0x01UL << (OldBits-1))) {
163 lval->ConstVal |= ((~0L) << OldBits);
170 /* The value is not a constant. If the sizes of the types are
171 * not equal, add conversion code. Be sure to convert chars
174 if (OldSize != NewSize) {
176 /* Load the value into the primary */
177 exprhs (CF_NONE, k, lval);
179 /* Emit typecast code. */
180 g_typecast (TypeOf (OldType), TypeOf (NewType) | CF_FORCECHAR);
182 /* Value is now in primary */
183 lval->Flags = E_MEXPR;
191 /* All other stuff is handled equally */
192 if (NewSize != OldSize) {
193 /* Load the value into the primary */
194 exprhs (CF_NONE, k, lval);
196 /* Emit typecast code */
197 g_typecast (TypeOf (OldType), TypeOf (NewType) | CF_FORCECHAR);
199 /* Value is now in primary */
200 lval->Flags = E_MEXPR;
206 /* The expression has always the new type */
207 ReplaceType (lval, NewType);