| 16187 | } |
| 16188 | |
| 16189 | void asCCompiler::CompileBitwiseOperator(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType op) |
| 16190 | { |
| 16191 | // TODO: If a constant is only using 32bits, then a 32bit operation is preferred |
| 16192 | |
| 16193 | if( op == ttUnrecognizedToken ) |
| 16194 | op = node->tokenType; |
| 16195 | if( op == ttAmp || op == ttAndAssign || |
| 16196 | op == ttBitOr || op == ttOrAssign || |
| 16197 | op == ttBitXor || op == ttXorAssign ) |
| 16198 | { |
| 16199 | // Also do not permit float/double to be implicitly converted to integer in this case |
| 16200 | // as the user may think the result is a bitwise operation on the float value but it's not |
| 16201 | if (lctx->type.dataType.IsFloatType() || lctx->type.dataType.IsDoubleType()) |
| 16202 | { |
| 16203 | asCString str; |
| 16204 | str.Format(TXT_ILLEGAL_OPERATION_ON_s, lctx->type.dataType.Format(outFunc->nameSpace).AddressOf()); |
| 16205 | Error(str, node); |
| 16206 | |
| 16207 | // Set an integer value and allow the compiler to continue |
| 16208 | ctx->type.SetConstantDW(asCDataType::CreatePrimitive(ttInt, true), 0); |
| 16209 | return; |
| 16210 | } |
| 16211 | if (rctx->type.dataType.IsFloatType() || rctx->type.dataType.IsDoubleType()) |
| 16212 | { |
| 16213 | asCString str; |
| 16214 | str.Format(TXT_ILLEGAL_OPERATION_ON_s, rctx->type.dataType.Format(outFunc->nameSpace).AddressOf()); |
| 16215 | Error(str, node); |
| 16216 | |
| 16217 | // Set an integer value and allow the compiler to continue |
| 16218 | ctx->type.SetConstantDW(asCDataType::CreatePrimitive(ttInt, true), 0); |
| 16219 | return; |
| 16220 | } |
| 16221 | |
| 16222 | // Convert left hand operand to integer if it's not already one |
| 16223 | asCDataType to; |
| 16224 | if( lctx->type.dataType.GetSizeInMemoryDWords() == 2 || |
| 16225 | rctx->type.dataType.GetSizeInMemoryDWords() == 2 ) |
| 16226 | to.SetTokenType(ttInt64); |
| 16227 | else |
| 16228 | to.SetTokenType(ttInt); |
| 16229 | |
| 16230 | // Do the actual conversion (keep sign/unsigned if possible) |
| 16231 | int l = int(reservedVariables.GetLength()); |
| 16232 | rctx->bc.GetVarsUsed(reservedVariables); |
| 16233 | if( lctx->type.dataType.IsUnsignedType() ) |
| 16234 | to.SetTokenType( to.GetSizeOnStackDWords() == 1 ? ttUInt : ttUInt64 ); |
| 16235 | else |
| 16236 | to.SetTokenType( to.GetSizeOnStackDWords() == 1 ? ttInt : ttInt64 ); |
| 16237 | ImplicitConversion(lctx, to, node, asIC_IMPLICIT_CONV, true); |
| 16238 | reservedVariables.SetLength(l); |
| 16239 | |
| 16240 | // Verify that the conversion was successful |
| 16241 | if( lctx->type.dataType != to ) |
| 16242 | { |
| 16243 | asCString str; |
| 16244 | str.Format(TXT_NO_CONVERSION_s_TO_s, lctx->type.dataType.Format(outFunc->nameSpace).AddressOf(), to.Format(outFunc->nameSpace).AddressOf()); |
| 16245 | Error(str, node); |
| 16246 |
nothing calls this directly
no test coverage detected