| 16875 | } |
| 16876 | |
| 16877 | void asCCompiler::CompileBooleanOperator(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType op) |
| 16878 | { |
| 16879 | // Both operands must be booleans |
| 16880 | asCDataType to; |
| 16881 | to.SetTokenType(ttBool); |
| 16882 | |
| 16883 | // Do the actual conversion |
| 16884 | int l = int(reservedVariables.GetLength()); |
| 16885 | rctx->bc.GetVarsUsed(reservedVariables); |
| 16886 | lctx->bc.GetVarsUsed(reservedVariables); |
| 16887 | |
| 16888 | // If turned on, allow the compiler to use either 'bool opImplConv()' or 'bool opConv()' on the type |
| 16889 | if (engine->ep.boolConversionMode == 1) |
| 16890 | ImplicitConversion(lctx, to, node, asIC_EXPLICIT_VAL_CAST); |
| 16891 | // else, allow value types to be converted to bool using 'bool opImplConv()' |
| 16892 | else if (lctx->type.dataType.GetTypeInfo() && (lctx->type.dataType.GetTypeInfo()->GetFlags() & asOBJ_VALUE)) |
| 16893 | ImplicitConversion(lctx, to, node, asIC_IMPLICIT_CONV); |
| 16894 | |
| 16895 | // The same goes for the right hand expression |
| 16896 | if (engine->ep.boolConversionMode == 1) |
| 16897 | ImplicitConversion(rctx, to, node, asIC_EXPLICIT_VAL_CAST); |
| 16898 | else if (rctx->type.dataType.GetTypeInfo() && (rctx->type.dataType.GetTypeInfo()->GetFlags() & asOBJ_VALUE)) |
| 16899 | ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV); |
| 16900 | |
| 16901 | reservedVariables.SetLength(l); |
| 16902 | |
| 16903 | // Verify that the conversion was successful |
| 16904 | if( !lctx->type.dataType.IsBooleanType() ) |
| 16905 | { |
| 16906 | asCString str; |
| 16907 | str.Format(TXT_NO_CONVERSION_s_TO_s, lctx->type.dataType.Format(outFunc->nameSpace).AddressOf(), "bool"); |
| 16908 | Error(str, node); |
| 16909 | // Force the conversion to allow compilation to proceed |
| 16910 | lctx->type.SetConstantB(asCDataType::CreatePrimitive(ttBool, true), true); |
| 16911 | } |
| 16912 | |
| 16913 | if( !rctx->type.dataType.IsBooleanType() ) |
| 16914 | { |
| 16915 | asCString str; |
| 16916 | str.Format(TXT_NO_CONVERSION_s_TO_s, rctx->type.dataType.Format(outFunc->nameSpace).AddressOf(), "bool"); |
| 16917 | Error(str, node); |
| 16918 | // Force the conversion to allow compilation to proceed |
| 16919 | rctx->type.SetConstantB(asCDataType::CreatePrimitive(ttBool, true), true); |
| 16920 | } |
| 16921 | |
| 16922 | bool isConstant = lctx->type.isConstant && rctx->type.isConstant; |
| 16923 | |
| 16924 | ctx->type.Set(asCDataType::CreatePrimitive(ttBool, true)); |
| 16925 | |
| 16926 | // What kind of operator is it? |
| 16927 | if( op == ttUnrecognizedToken ) |
| 16928 | op = node->tokenType; |
| 16929 | if( op == ttXor ) |
| 16930 | { |
| 16931 | if( !isConstant ) |
| 16932 | { |
| 16933 | // Must convert to temporary variable, because we are changing the value before comparison |
| 16934 | ConvertToTempVariableNotIn(lctx, rctx); |
nothing calls this directly
no test coverage detected