mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-14 10:29:50 +02:00
* implement a type conversion from an array constructor to a dynamic array
git-svn-id: trunk@36095 -
This commit is contained in:
parent
6e31a7ac83
commit
df893b4a30
@ -103,7 +103,8 @@ interface
|
|||||||
tc_interface_2_variant,
|
tc_interface_2_variant,
|
||||||
tc_variant_2_interface,
|
tc_variant_2_interface,
|
||||||
tc_array_2_dynarray,
|
tc_array_2_dynarray,
|
||||||
tc_elem_2_openarray
|
tc_elem_2_openarray,
|
||||||
|
tc_arrayconstructor_2_dynarray
|
||||||
);
|
);
|
||||||
|
|
||||||
function compare_defs_ext(def_from,def_to : tdef;
|
function compare_defs_ext(def_from,def_to : tdef;
|
||||||
|
@ -100,6 +100,7 @@ interface
|
|||||||
function typecheck_interface_to_variant : tnode; virtual;
|
function typecheck_interface_to_variant : tnode; virtual;
|
||||||
function typecheck_array_2_dynarray : tnode; virtual;
|
function typecheck_array_2_dynarray : tnode; virtual;
|
||||||
function typecheck_elem_2_openarray : tnode; virtual;
|
function typecheck_elem_2_openarray : tnode; virtual;
|
||||||
|
function typecheck_arrayconstructor_to_dynarray : tnode; virtual;
|
||||||
private
|
private
|
||||||
function _typecheck_int_to_int : tnode;
|
function _typecheck_int_to_int : tnode;
|
||||||
function _typecheck_cord_to_pointer : tnode;
|
function _typecheck_cord_to_pointer : tnode;
|
||||||
@ -131,6 +132,7 @@ interface
|
|||||||
function _typecheck_interface_to_variant : tnode;
|
function _typecheck_interface_to_variant : tnode;
|
||||||
function _typecheck_array_2_dynarray : tnode;
|
function _typecheck_array_2_dynarray : tnode;
|
||||||
function _typecheck_elem_2_openarray : tnode;
|
function _typecheck_elem_2_openarray : tnode;
|
||||||
|
function _typecheck_arrayconstructor_to_dynarray: tnode;
|
||||||
protected
|
protected
|
||||||
function first_int_to_int : tnode;virtual;
|
function first_int_to_int : tnode;virtual;
|
||||||
function first_cstring_to_pchar : tnode;virtual;
|
function first_cstring_to_pchar : tnode;virtual;
|
||||||
@ -385,7 +387,6 @@ implementation
|
|||||||
p:=arrayconstructor_to_set(p,true);
|
p:=arrayconstructor_to_set(p,true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function arrayconstructor_to_set(p:tnode;freep:boolean):tnode;
|
function arrayconstructor_to_set(p:tnode;freep:boolean):tnode;
|
||||||
var
|
var
|
||||||
constp : tsetconstnode;
|
constp : tsetconstnode;
|
||||||
@ -1010,7 +1011,8 @@ implementation
|
|||||||
'tc_interface_2_variant',
|
'tc_interface_2_variant',
|
||||||
'tc_variant_2_interface',
|
'tc_variant_2_interface',
|
||||||
'tc_array_2_dynarray',
|
'tc_array_2_dynarray',
|
||||||
'tc_elem_2_openarray'
|
'tc_elem_2_openarray',
|
||||||
|
'tc_arrayconstructor_2_dynarray'
|
||||||
);
|
);
|
||||||
begin
|
begin
|
||||||
inherited printnodeinfo(t);
|
inherited printnodeinfo(t);
|
||||||
@ -1886,6 +1888,93 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.typecheck_arrayconstructor_to_dynarray : tnode;
|
||||||
|
var
|
||||||
|
newstatement,assstatement:tstatementnode;
|
||||||
|
arrnode:ttempcreatenode;
|
||||||
|
temp2:ttempcreatenode;
|
||||||
|
assnode:tnode;
|
||||||
|
paracount:integer;
|
||||||
|
elemnode:tarrayconstructornode;
|
||||||
|
begin
|
||||||
|
{ assignment of []? }
|
||||||
|
if (left.nodetype=arrayconstructorn) and not assigned(tarrayconstructornode(left).left) then
|
||||||
|
begin
|
||||||
|
result:=cnilnode.create;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if resultdef.typ<>arraydef then
|
||||||
|
internalerror(2017050102);
|
||||||
|
|
||||||
|
tarrayconstructornode(left).force_type(tarraydef(resultdef).elementdef);
|
||||||
|
|
||||||
|
result:=internalstatements(newstatement);
|
||||||
|
{ create temp for result }
|
||||||
|
arrnode:=ctempcreatenode.create(totypedef,totypedef.size,tt_persistent,true);
|
||||||
|
addstatement(newstatement,arrnode);
|
||||||
|
|
||||||
|
paracount:=0;
|
||||||
|
|
||||||
|
{ create an assignment call for each element }
|
||||||
|
assnode:=internalstatements(assstatement);
|
||||||
|
if left.nodetype=arrayconstructorrangen then
|
||||||
|
internalerror(2016021902);
|
||||||
|
elemnode:=tarrayconstructornode(left);
|
||||||
|
while assigned(elemnode) do
|
||||||
|
begin
|
||||||
|
{ arr[i] := param_i }
|
||||||
|
if not assigned(elemnode.left) then
|
||||||
|
internalerror(2017050101);
|
||||||
|
addstatement(assstatement,
|
||||||
|
cassignmentnode.create(
|
||||||
|
cvecnode.create(
|
||||||
|
ctemprefnode.create(arrnode),
|
||||||
|
cordconstnode.create(paracount,tarraydef(totypedef).rangedef,false)),
|
||||||
|
elemnode.left));
|
||||||
|
elemnode.left:=nil;
|
||||||
|
inc(paracount);
|
||||||
|
elemnode:=tarrayconstructornode(elemnode.right);
|
||||||
|
if assigned(elemnode) and (elemnode.nodetype<>arrayconstructorn) then
|
||||||
|
internalerror(2016021903);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ get temp for array of lengths }
|
||||||
|
temp2:=ctempcreatenode.create(sinttype,sinttype.size,tt_persistent,false);
|
||||||
|
addstatement(newstatement,temp2);
|
||||||
|
|
||||||
|
{ one dimensional }
|
||||||
|
addstatement(newstatement,cassignmentnode.create(
|
||||||
|
ctemprefnode.create(temp2),
|
||||||
|
cordconstnode.create
|
||||||
|
(paracount,s32inttype,true)));
|
||||||
|
{ create call to fpc_dynarr_setlength }
|
||||||
|
addstatement(newstatement,ccallnode.createintern('fpc_dynarray_setlength',
|
||||||
|
ccallparanode.create(caddrnode.create_internal
|
||||||
|
(ctemprefnode.create(temp2)),
|
||||||
|
ccallparanode.create(cordconstnode.create
|
||||||
|
(1,s32inttype,true),
|
||||||
|
ccallparanode.create(caddrnode.create_internal
|
||||||
|
(crttinode.create(tstoreddef(totypedef),initrtti,rdt_normal)),
|
||||||
|
ccallparanode.create(
|
||||||
|
ctypeconvnode.create_internal(
|
||||||
|
ctemprefnode.create(arrnode),voidpointertype),
|
||||||
|
nil))))
|
||||||
|
|
||||||
|
));
|
||||||
|
{ add assignment statememnts }
|
||||||
|
addstatement(newstatement,ctempdeletenode.create(temp2));
|
||||||
|
if assigned(assnode) then
|
||||||
|
addstatement(newstatement,assnode);
|
||||||
|
{ the last statement should return the value as
|
||||||
|
location and type, this is done be referencing the
|
||||||
|
temp and converting it first from a persistent temp to
|
||||||
|
normal temp }
|
||||||
|
addstatement(newstatement,ctempdeletenode.create_normal_temp(arrnode));
|
||||||
|
addstatement(newstatement,ctemprefnode.create(arrnode));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode._typecheck_int_to_int : tnode;
|
function ttypeconvnode._typecheck_int_to_int : tnode;
|
||||||
begin
|
begin
|
||||||
result := typecheck_int_to_int;
|
result := typecheck_int_to_int;
|
||||||
@ -2066,6 +2155,12 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode._typecheck_arrayconstructor_to_dynarray : tnode;
|
||||||
|
begin
|
||||||
|
result:=typecheck_arrayconstructor_to_dynarray;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.target_specific_general_typeconv: boolean;
|
function ttypeconvnode.target_specific_general_typeconv: boolean;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
@ -2189,7 +2284,8 @@ implementation
|
|||||||
{ variant_2_interface} @ttypeconvnode._typecheck_interface_to_variant,
|
{ variant_2_interface} @ttypeconvnode._typecheck_interface_to_variant,
|
||||||
{ interface_2_variant} @ttypeconvnode._typecheck_variant_to_interface,
|
{ interface_2_variant} @ttypeconvnode._typecheck_variant_to_interface,
|
||||||
{ array_2_dynarray} @ttypeconvnode._typecheck_array_2_dynarray,
|
{ array_2_dynarray} @ttypeconvnode._typecheck_array_2_dynarray,
|
||||||
{ elem_2_openarray } @ttypeconvnode._typecheck_elem_2_openarray
|
{ elem_2_openarray } @ttypeconvnode._typecheck_elem_2_openarray,
|
||||||
|
{ arrayconstructor_2_dynarray } @ttypeconvnode._typecheck_arrayconstructor_to_dynarray
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
tprocedureofobject = function : tnode of object;
|
tprocedureofobject = function : tnode of object;
|
||||||
@ -3716,6 +3812,7 @@ implementation
|
|||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
@ttypeconvnode._first_nothing,
|
||||||
@ttypeconvnode._first_nothing
|
@ttypeconvnode._first_nothing
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
@ -3993,7 +4090,8 @@ implementation
|
|||||||
@ttypeconvnode._second_nothing, { variant_2_interface }
|
@ttypeconvnode._second_nothing, { variant_2_interface }
|
||||||
@ttypeconvnode._second_nothing, { interface_2_variant }
|
@ttypeconvnode._second_nothing, { interface_2_variant }
|
||||||
@ttypeconvnode._second_nothing, { array_2_dynarray }
|
@ttypeconvnode._second_nothing, { array_2_dynarray }
|
||||||
@ttypeconvnode._second_elem_to_openarray { elem_2_openarray }
|
@ttypeconvnode._second_elem_to_openarray, { elem_2_openarray }
|
||||||
|
@ttypeconvnode._second_nothing { arrayconstructor_2_dynarray }
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
tprocedureofobject = procedure of object;
|
tprocedureofobject = procedure of object;
|
||||||
|
Loading…
Reference in New Issue
Block a user