|
@@ -1205,6 +1205,72 @@ implementation
|
|
inserttypeconv(n,adef);
|
|
inserttypeconv(n,adef);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ function maybe_convert_to_insert:tnode;
|
|
|
|
+
|
|
|
|
+ function element_count(arrconstr: tarrayconstructornode):asizeint;
|
|
|
|
+ begin
|
|
|
|
+ result:=0;
|
|
|
|
+ while assigned(arrconstr) do
|
|
|
|
+ begin
|
|
|
|
+ if arrconstr.nodetype=arrayconstructorrangen then
|
|
|
|
+ internalerror(2018052501);
|
|
|
|
+ inc(result);
|
|
|
|
+ arrconstr:=tarrayconstructornode(tarrayconstructornode(arrconstr).right);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ var
|
|
|
|
+ elem : tnode;
|
|
|
|
+ para : tcallparanode;
|
|
|
|
+ isarrconstrl,
|
|
|
|
+ isarrconstrr : boolean;
|
|
|
|
+ index : asizeint;
|
|
|
|
+ begin
|
|
|
|
+ result:=nil;
|
|
|
|
+
|
|
|
|
+ isarrconstrl:=left.nodetype=arrayconstructorn;
|
|
|
|
+ isarrconstrr:=right.nodetype=arrayconstructorn;
|
|
|
|
+
|
|
|
|
+ if not assigned(aktassignmentnode) or
|
|
|
|
+ (aktassignmentnode.right<>self) or
|
|
|
|
+ not(
|
|
|
|
+ isarrconstrl or
|
|
|
|
+ isarrconstrr
|
|
|
|
+ ) or
|
|
|
|
+ not(
|
|
|
|
+ left.isequal(aktassignmentnode.left) or
|
|
|
|
+ right.isequal(aktassignmentnode.left)
|
|
|
|
+ ) or
|
|
|
|
+ not valid_for_var(aktassignmentnode.left,false) or
|
|
|
|
+ (isarrconstrl and (element_count(tarrayconstructornode(left))>1)) or
|
|
|
|
+ (isarrconstrr and (element_count(tarrayconstructornode(right))>1)) then
|
|
|
|
+ exit;
|
|
|
|
+
|
|
|
|
+ if isarrconstrl then
|
|
|
|
+ begin
|
|
|
|
+ index:=0;
|
|
|
|
+ elem:=tarrayconstructornode(left).left;
|
|
|
|
+ tarrayconstructornode(left).left:=nil;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ index:=high(asizeint);
|
|
|
|
+ elem:=tarrayconstructornode(right).left;
|
|
|
|
+ tarrayconstructornode(right).left:=nil;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { we use the fact that insert() caps the index to avoid a copy }
|
|
|
|
+ para:=ccallparanode.create(
|
|
|
|
+ cordconstnode.create(index,sizesinttype,false),
|
|
|
|
+ ccallparanode.create(
|
|
|
|
+ aktassignmentnode.left.getcopy,
|
|
|
|
+ ccallparanode.create(
|
|
|
|
+ elem,nil)));
|
|
|
|
+
|
|
|
|
+ result:=cinlinenode.create(in_insert_x_y_z,false,para);
|
|
|
|
+ include(aktassignmentnode.flags,nf_assign_done_in_right);
|
|
|
|
+ end;
|
|
|
|
+
|
|
begin
|
|
begin
|
|
result:=nil;
|
|
result:=nil;
|
|
rlow:=0;
|
|
rlow:=0;
|
|
@@ -2124,6 +2190,9 @@ implementation
|
|
{ <dyn. array>+<dyn. array> ? }
|
|
{ <dyn. array>+<dyn. array> ? }
|
|
else if (nodetype=addn) and (is_dynamic_array(ld) or is_dynamic_array(rd)) then
|
|
else if (nodetype=addn) and (is_dynamic_array(ld) or is_dynamic_array(rd)) then
|
|
begin
|
|
begin
|
|
|
|
+ result:=maybe_convert_to_insert;
|
|
|
|
+ if assigned(result) then
|
|
|
|
+ exit;
|
|
if not(is_dynamic_array(ld)) then
|
|
if not(is_dynamic_array(ld)) then
|
|
inserttypeconv(left,rd);
|
|
inserttypeconv(left,rd);
|
|
if not(is_dynamic_array(rd)) then
|
|
if not(is_dynamic_array(rd)) then
|