mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-shader/hlsl: Pass a vkd3d_shader_location pointer to message reporting functions.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Giovanni Mascellani <gmascellani@codeweavers.com> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a33439f1a0
commit
943bd2fede
@ -22,40 +22,40 @@
|
||||
#include "hlsl.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_log_level level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vkd3d_shader_vnote(ctx->message_context, &loc, level, fmt, args);
|
||||
vkd3d_shader_vnote(ctx->message_context, loc, level, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_error error, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vkd3d_shader_verror(ctx->message_context, &loc, error, fmt, args);
|
||||
vkd3d_shader_verror(ctx->message_context, loc, error, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (!ctx->result)
|
||||
ctx->result = VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_error error, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vkd3d_shader_vwarning(ctx->message_context, &loc, error, fmt, args);
|
||||
vkd3d_shader_vwarning(ctx->message_context, loc, error, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, const char *fmt, ...)
|
||||
void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, const char *fmt, ...)
|
||||
{
|
||||
struct vkd3d_string_buffer *string;
|
||||
va_list args;
|
||||
@ -64,7 +64,7 @@ void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, co
|
||||
string = hlsl_get_string_buffer(ctx);
|
||||
vkd3d_string_buffer_printf(string, "Aborting due to not yet implemented feature: ");
|
||||
vkd3d_string_buffer_vprintf(string, fmt, args);
|
||||
vkd3d_shader_error(ctx->message_context, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "%s", string->buffer);
|
||||
vkd3d_shader_error(ctx->message_context, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "%s", string->buffer);
|
||||
hlsl_release_string_buffer(ctx, string);
|
||||
va_end(args);
|
||||
|
||||
@ -1960,7 +1960,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
|
||||
{
|
||||
const struct vkd3d_shader_location loc = {.source_name = compile_info->source_name};
|
||||
|
||||
hlsl_error(&ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED,
|
||||
hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED,
|
||||
"Entry point \"%s\" is not defined.", entry_point);
|
||||
hlsl_ctx_cleanup(&ctx);
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
|
@ -728,13 +728,13 @@ struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct
|
||||
struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var,
|
||||
const struct vkd3d_shader_location loc);
|
||||
|
||||
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
|
||||
void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
const char *fmt, ...) VKD3D_PRINTF_FUNC(3, 4);
|
||||
void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
|
||||
void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc,
|
||||
void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_log_level level, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
|
||||
|
||||
void hlsl_push_scope(struct hlsl_ctx *ctx);
|
||||
|
@ -65,7 +65,7 @@ ANY (.)
|
||||
{RESERVED4} {
|
||||
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
|
||||
|
||||
hlsl_error(ctx, *yylloc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
||||
hlsl_error(ctx, yylloc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
||||
"Reserved keyword \"%s\" used.", yytext);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -113,7 +113,7 @@ static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
else if (field->semantic.name)
|
||||
prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic);
|
||||
else
|
||||
hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
"Field '%s' is missing a semantic.", field->name);
|
||||
}
|
||||
}
|
||||
@ -184,7 +184,7 @@ static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
else if (field->semantic.name)
|
||||
append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic);
|
||||
else
|
||||
hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
"Field '%s' is missing a semantic.", field->name);
|
||||
}
|
||||
}
|
||||
@ -1365,7 +1365,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
|
||||
|
||||
if (!hlsl_sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx))
|
||||
{
|
||||
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
|
||||
"Invalid semantic '%s'.", var->semantic.name);
|
||||
return;
|
||||
}
|
||||
@ -1382,7 +1382,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
|
||||
|
||||
if (!hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage))
|
||||
{
|
||||
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
|
||||
"Invalid semantic '%s'.", var->semantic.name);
|
||||
return;
|
||||
}
|
||||
@ -1473,9 +1473,9 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
|
||||
|
||||
if (reserved_buffer && reserved_buffer != buffer)
|
||||
{
|
||||
hlsl_error(ctx, buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
|
||||
hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
|
||||
"Multiple buffers bound to cb%u.", buffer->reservation.index);
|
||||
hlsl_note(ctx, reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR,
|
||||
hlsl_note(ctx, &reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR,
|
||||
"Buffer %s is already bound to cb%u.", reserved_buffer->name, buffer->reservation.index);
|
||||
}
|
||||
|
||||
@ -1495,7 +1495,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
hlsl_error(ctx, buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
|
||||
hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
|
||||
"Constant buffers must be allocated to register type 'b'.");
|
||||
}
|
||||
}
|
||||
@ -1560,10 +1560,10 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_base_type type)
|
||||
|
||||
if (reserved_object && reserved_object != var)
|
||||
{
|
||||
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
|
||||
"Multiple objects bound to %c%u.", type_info->reg_name,
|
||||
var->reg_reservation.index);
|
||||
hlsl_note(ctx, reserved_object->loc, VKD3D_SHADER_LOG_ERROR,
|
||||
hlsl_note(ctx, &reserved_object->loc, VKD3D_SHADER_LOG_ERROR,
|
||||
"Object '%s' is already bound to %c%u.", reserved_object->name,
|
||||
type_info->reg_name, var->reg_reservation.index);
|
||||
}
|
||||
@ -1587,7 +1587,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_base_type type)
|
||||
struct vkd3d_string_buffer *type_string;
|
||||
|
||||
type_string = hlsl_type_to_string(ctx, var->data_type);
|
||||
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
|
||||
"Object of type '%s' must be bound to register type '%c'.",
|
||||
type_string->buffer, type_info->reg_name);
|
||||
hlsl_release_string_buffer(ctx, type_string);
|
||||
@ -1628,7 +1628,7 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl
|
||||
if (hlsl_offset_from_deref(deref, &offset))
|
||||
return offset;
|
||||
|
||||
hlsl_fixme(ctx, deref->offset.node->loc, "Dereference with non-constant offset of type %s.",
|
||||
hlsl_fixme(ctx, &deref->offset.node->loc, "Dereference with non-constant offset of type %s.",
|
||||
hlsl_node_type_to_string(deref->offset.node->type));
|
||||
|
||||
return 0;
|
||||
@ -1679,7 +1679,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
|
||||
else
|
||||
{
|
||||
if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name)
|
||||
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
"Parameter \"%s\" is missing a semantic.", var->name);
|
||||
|
||||
if (var->modifiers & HLSL_STORAGE_IN)
|
||||
@ -1691,7 +1691,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
|
||||
if (entry_func->return_var)
|
||||
{
|
||||
if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name)
|
||||
hlsl_error(ctx, entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
||||
"Entry point \"%s\" is missing a return value semantic.", entry_func->func->name);
|
||||
|
||||
append_output_var_copy(ctx, &body->instrs, entry_func->return_var);
|
||||
|
@ -617,7 +617,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
||||
if (instr->data_type->base_type != HLSL_TYPE_FLOAT)
|
||||
{
|
||||
/* These need to be lowered. */
|
||||
hlsl_fixme(ctx, instr->loc, "SM1 non-float expression.");
|
||||
hlsl_fixme(ctx, &instr->loc, "SM1 non-float expression.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -655,7 +655,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
||||
break;
|
||||
|
||||
default:
|
||||
hlsl_fixme(ctx, instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op));
|
||||
hlsl_fixme(ctx, &instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -785,12 +785,12 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
|
||||
if (instr->data_type->type == HLSL_CLASS_MATRIX)
|
||||
{
|
||||
/* These need to be lowered. */
|
||||
hlsl_fixme(ctx, instr->loc, "SM1 matrix expression.");
|
||||
hlsl_fixme(ctx, &instr->loc, "SM1 matrix expression.");
|
||||
continue;
|
||||
}
|
||||
else if (instr->data_type->type == HLSL_CLASS_OBJECT)
|
||||
{
|
||||
hlsl_fixme(ctx, instr->loc, "Object copy.\n");
|
||||
hlsl_fixme(ctx, &instr->loc, "Object copy.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
|
||||
|
||||
default:
|
||||
if ((string = hlsl_type_to_string(ctx, var->data_type)))
|
||||
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Invalid data type %s for semantic variable %s.", string->buffer, var->name);
|
||||
hlsl_release_string_buffer(ctx, string);
|
||||
put_u32(&buffer, D3D_REGISTER_COMPONENT_UNKNOWN);
|
||||
@ -1317,11 +1317,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_BOOL:
|
||||
hlsl_fixme(ctx, expr->node.loc, "Casts from bool to float are not implemented.\n");
|
||||
hlsl_fixme(ctx, &expr->node.loc, "Casts from bool to float are not implemented.\n");
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
hlsl_fixme(ctx, expr->node.loc, "Casts from double to float are not implemented.\n");
|
||||
hlsl_fixme(ctx, &expr->node.loc, "Casts from double to float are not implemented.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1373,7 +1373,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
break;
|
||||
|
||||
default:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 float \"%s\" expression.", debug_hlsl_expr_op(expr->op));
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 float \"%s\" expression.", debug_hlsl_expr_op(expr->op));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1403,11 +1403,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_BOOL:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 cast from bool to int.");
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from bool to int.");
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 cast from double to int.");
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to int.");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1417,7 +1417,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
}
|
||||
|
||||
default:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 int \"%s\" expression.", debug_hlsl_expr_op(expr->op));
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 int \"%s\" expression.", debug_hlsl_expr_op(expr->op));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1447,11 +1447,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_BOOL:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 cast from bool to uint.\n");
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from bool to uint.\n");
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 cast from double to uint.\n");
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to uint.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1461,7 +1461,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
}
|
||||
|
||||
default:
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 uint \"%s\" expression.\n", debug_hlsl_expr_op(expr->op));
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 uint \"%s\" expression.\n", debug_hlsl_expr_op(expr->op));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1472,7 +1472,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
|
||||
struct vkd3d_string_buffer *string;
|
||||
|
||||
if ((string = hlsl_type_to_string(ctx, expr->node.data_type)))
|
||||
hlsl_fixme(ctx, expr->node.loc, "SM4 %s expression.", string->buffer);
|
||||
hlsl_fixme(ctx, &expr->node.loc, "SM4 %s expression.", string->buffer);
|
||||
hlsl_release_string_buffer(ctx, string);
|
||||
break;
|
||||
}
|
||||
@ -1561,14 +1561,14 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
|
||||
|
||||
if (!load->sampler.var->is_uniform)
|
||||
{
|
||||
hlsl_fixme(ctx, load->node.loc, "Sample using non-uniform sampler variable.");
|
||||
hlsl_fixme(ctx, &load->node.loc, "Sample using non-uniform sampler variable.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!load->resource.var->is_uniform)
|
||||
{
|
||||
hlsl_fixme(ctx, load->node.loc, "Load from non-uniform resource variable.");
|
||||
hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1580,7 +1580,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
|
||||
|
||||
case HLSL_RESOURCE_SAMPLE:
|
||||
if (!load->sampler.var)
|
||||
hlsl_fixme(ctx, load->node.loc, "SM4 combined sample expression.");
|
||||
hlsl_fixme(ctx, &load->node.loc, "SM4 combined sample expression.");
|
||||
write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords);
|
||||
break;
|
||||
}
|
||||
@ -1595,7 +1595,7 @@ static void write_sm4_store(struct hlsl_ctx *ctx,
|
||||
|
||||
if (store->lhs.var->data_type->type == HLSL_CLASS_MATRIX)
|
||||
{
|
||||
hlsl_fixme(ctx, store->node.loc, "Store to a matrix variable.\n");
|
||||
hlsl_fixme(ctx, &store->node.loc, "Store to a matrix variable.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1649,7 +1649,7 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *
|
||||
}
|
||||
else if (instr->data_type->type == HLSL_CLASS_OBJECT)
|
||||
{
|
||||
hlsl_fixme(ctx, instr->loc, "Object copy.\n");
|
||||
hlsl_fixme(ctx, &instr->loc, "Object copy.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user