mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 09:09:47 +01:00
* move conversions of winlinke widestring, variant and records/arrays-
with-init-info assignments into helper calls from
tassignmentnode.pass_typecheck to pass_1 so they can be optimised
in more cases (patch from Sergei Gorelkin)
git-svn-id: trunk@9410 -
This commit is contained in:
parent
f38e190892
commit
d46b433778
122
compiler/nld.pas
122
compiler/nld.pas
@ -582,64 +582,6 @@ implementation
|
||||
right:=nil;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
{ call helpers for variant, they can contain non ref. counted types like
|
||||
vararrays which must be really copied }
|
||||
else if left.resultdef.typ=variantdef then
|
||||
begin
|
||||
hp:=ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(right),voidpointertype),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(left),voidpointertype),
|
||||
nil));
|
||||
result:=ccallnode.createintern('fpc_variant_copy',hp);
|
||||
left:=nil;
|
||||
right:=nil;
|
||||
exit;
|
||||
end
|
||||
{ call helpers for composite types containing automated types }
|
||||
else if (left.resultdef.needs_inittable) and
|
||||
(left.resultdef.typ in [arraydef,objectdef,recorddef]) and
|
||||
not is_dynamic_array(left.resultdef) then
|
||||
begin
|
||||
hp:=ccallparanode.create(caddrnode.create_internal(
|
||||
crttinode.create(tstoreddef(left.resultdef),initrtti,rdt_normal)),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(left),voidpointertype),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(right),voidpointertype),
|
||||
nil)));
|
||||
result:=ccallnode.createintern('fpc_copy_proc',hp);
|
||||
left:=nil;
|
||||
right:=nil;
|
||||
exit;
|
||||
end
|
||||
{ call helpers for windows widestrings, they aren't ref. counted }
|
||||
else if (tf_winlikewidestring in target_info.flags) and is_widestring(left.resultdef) then
|
||||
begin
|
||||
{ The first argument of fpc_widestr_assign is a var parameter. Properties cannot }
|
||||
{ be passed to var or out parameters, because in that case setters/getters are not }
|
||||
{ used. Further, if we would allow it in case there are no getters or setters, you }
|
||||
{ would need source changes in case these are introduced later on, thus defeating }
|
||||
{ part of the transparency advantages of properties. In this particular case, }
|
||||
{ however: }
|
||||
{ a) if there is a setter, this code will not be used since then the assignment }
|
||||
{ will be converted to a procedure call }
|
||||
{ b) the getter is irrelevant, because fpc_widestr_assign must always decrease }
|
||||
{ the refcount of the field to which we are writing }
|
||||
{ c) source code changes are not required if a setter is added/removed, because }
|
||||
{ this transformation is handled at compile time }
|
||||
{ -> we can remove the nf_isproperty flag (if any) from left, so that in case it }
|
||||
{ is a property which refers to a field without a setter call, we will not get }
|
||||
{ an error about trying to pass a property as a var parameter }
|
||||
exclude(left.flags,nf_isproperty);
|
||||
hp:=ccallparanode.create(ctypeconvnode.create_internal(right,voidpointertype),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(left,voidpointertype),
|
||||
nil));
|
||||
result:=ccallnode.createintern('fpc_widestr_assign',hp);
|
||||
left:=nil;
|
||||
right:=nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ check if local proc/func is assigned to procvar }
|
||||
@ -699,7 +641,69 @@ implementation
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
{ call helpers for composite types containing automated types }
|
||||
else if (left.resultdef.needs_inittable) and
|
||||
(left.resultdef.typ in [arraydef,objectdef,recorddef]) and
|
||||
not is_interfacecom(left.resultdef) and
|
||||
not is_dynamic_array(left.resultdef) then
|
||||
begin
|
||||
hp:=ccallparanode.create(caddrnode.create_internal(
|
||||
crttinode.create(tstoreddef(left.resultdef),initrtti,rdt_normal)),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(left),voidpointertype),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(right),voidpointertype),
|
||||
nil)));
|
||||
result:=ccallnode.createintern('fpc_copy_proc',hp);
|
||||
firstpass(result);
|
||||
left:=nil;
|
||||
right:=nil;
|
||||
exit;
|
||||
end
|
||||
{ call helpers for variant, they can contain non ref. counted types like
|
||||
vararrays which must be really copied }
|
||||
else if left.resultdef.typ=variantdef then
|
||||
begin
|
||||
hp:=ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(right),voidpointertype),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(
|
||||
caddrnode.create_internal(left),voidpointertype),
|
||||
nil));
|
||||
result:=ccallnode.createintern('fpc_variant_copy',hp);
|
||||
firstpass(result);
|
||||
left:=nil;
|
||||
right:=nil;
|
||||
exit;
|
||||
end
|
||||
{ call helpers for windows widestrings, they aren't ref. counted }
|
||||
else if (tf_winlikewidestring in target_info.flags) and is_widestring(left.resultdef) then
|
||||
begin
|
||||
{ The first argument of fpc_widestr_assign is a var parameter. Properties cannot }
|
||||
{ be passed to var or out parameters, because in that case setters/getters are not }
|
||||
{ used. Further, if we would allow it in case there are no getters or setters, you }
|
||||
{ would need source changes in case these are introduced later on, thus defeating }
|
||||
{ part of the transparency advantages of properties. In this particular case, }
|
||||
{ however: }
|
||||
{ a) if there is a setter, this code will not be used since then the assignment }
|
||||
{ will be converted to a procedure call }
|
||||
{ b) the getter is irrelevant, because fpc_widestr_assign must always decrease }
|
||||
{ the refcount of the field to which we are writing }
|
||||
{ c) source code changes are not required if a setter is added/removed, because }
|
||||
{ this transformation is handled at compile time }
|
||||
{ -> we can remove the nf_isproperty flag (if any) from left, so that in case it }
|
||||
{ is a property which refers to a field without a setter call, we will not get }
|
||||
{ an error about trying to pass a property as a var parameter }
|
||||
exclude(left.flags,nf_isproperty);
|
||||
hp:=ccallparanode.create(ctypeconvnode.create_internal(right,voidpointertype),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(left,voidpointertype),
|
||||
nil));
|
||||
result:=ccallnode.createintern('fpc_widestr_assign',hp);
|
||||
firstpass(result);
|
||||
left:=nil;
|
||||
right:=nil;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user