| 8295 | } |
| 8296 | |
| 8297 | asUINT asCCompiler::ImplicitConvObjectToObject(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode, bool allowObjectConstruct) |
| 8298 | { |
| 8299 | // First try a ref cast |
| 8300 | asUINT cost = ImplicitConvObjectRef(ctx, to, node, convType, generateCode); |
| 8301 | |
| 8302 | // If the desired type is an asOBJ_ASHANDLE then we'll assume it is allowed to implicitly |
| 8303 | // construct the object through any of the available constructors (except those marked as explicit) |
| 8304 | if( to.GetTypeInfo() && (to.GetTypeInfo()->flags & asOBJ_ASHANDLE) && to.GetTypeInfo() != ctx->type.dataType.GetTypeInfo() && allowObjectConstruct ) |
| 8305 | { |
| 8306 | asCArray<int> funcs; |
| 8307 | funcs = CastToObjectType(to.GetTypeInfo())->beh.constructors; |
| 8308 | |
| 8309 | // Don't allow use of explicit constructors/factories in implicit conversions |
| 8310 | if (convType == asIC_IMPLICIT_CONV) |
| 8311 | { |
| 8312 | for (asUINT n = 0; n < funcs.GetLength(); n++) |
| 8313 | { |
| 8314 | asCScriptFunction* desc = builder->GetFunctionDescription(funcs[n]); |
| 8315 | if (desc->IsExplicit()) |
| 8316 | funcs.RemoveIndex(n--); |
| 8317 | } |
| 8318 | } |
| 8319 | |
| 8320 | asCArray<asCExprContext *> args; |
| 8321 | args.PushLast(ctx); |
| 8322 | |
| 8323 | cost = asCC_TO_OBJECT_CONV + MatchFunctions(funcs, args, node, 0, 0, 0, false, true, false); |
| 8324 | |
| 8325 | // Did we find a matching constructor? |
| 8326 | if( funcs.GetLength() == 1 ) |
| 8327 | { |
| 8328 | if( generateCode ) |
| 8329 | { |
| 8330 | // If the ASHANDLE receives a variable type parameter, then we need to |
| 8331 | // make sure the expression is treated as a handle and not as a value |
| 8332 | asCScriptFunction *func = engine->scriptFunctions[funcs[0]]; |
| 8333 | if( func->parameterTypes[0].GetTokenType() == ttQuestion ) |
| 8334 | { |
| 8335 | if( !ctx->type.isExplicitHandle ) |
| 8336 | { |
| 8337 | asCDataType toHandle = ctx->type.dataType; |
| 8338 | toHandle.MakeHandle(true); |
| 8339 | toHandle.MakeReference(true); |
| 8340 | toHandle.MakeHandleToConst(ctx->type.dataType.IsReadOnly()); |
| 8341 | ImplicitConversion(ctx, toHandle, node, asIC_IMPLICIT_CONV, true, false); |
| 8342 | |
| 8343 | asASSERT( ctx->type.dataType.IsObjectHandle() ); |
| 8344 | } |
| 8345 | ctx->type.isExplicitHandle = true; |
| 8346 | } |
| 8347 | |
| 8348 | // TODO: This should really reuse the code from CompileConstructCall |
| 8349 | |
| 8350 | // Allocate the new object |
| 8351 | asCExprValue tempObj; |
| 8352 | tempObj.dataType = to; |
| 8353 | tempObj.dataType.MakeReference(false); |
| 8354 | tempObj.stackOffset = (short)AllocateVariable(tempObj.dataType, true); |
nothing calls this directly
no test coverage detected