mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 17:48:46 +02:00
compiler: record operators
- allow operator also if return type match the structure type (before at least one parameter had to match) - search both operands symbol tables for a suitable assignment operator - test based on patch of Blaise Thorn (issue #0018490) git-svn-id: trunk@16762 -
This commit is contained in:
parent
8a7b10586d
commit
0c9b40acb7
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9619,6 +9619,7 @@ tests/test/tobject8.pp svneol=native#text/plain
|
||||
tests/test/toperator1.pp svneol=native#text/plain
|
||||
tests/test/toperator10.pp svneol=native#text/pascal
|
||||
tests/test/toperator11.pp svneol=native#text/pascal
|
||||
tests/test/toperator12.pp svneol=native#text/pascal
|
||||
tests/test/toperator2.pp svneol=native#text/plain
|
||||
tests/test/toperator3.pp svneol=native#text/plain
|
||||
tests/test/toperator4.pp svneol=native#text/plain
|
||||
|
@ -29,7 +29,7 @@ interface
|
||||
cclasses,
|
||||
globtype,globals,
|
||||
node,
|
||||
symconst,symtype,symbase,symdef;
|
||||
symconst,symtype,symdef;
|
||||
|
||||
type
|
||||
{ if acp is cp_all the var const or nothing are considered equal }
|
||||
@ -1487,19 +1487,7 @@ implementation
|
||||
)
|
||||
) then
|
||||
begin
|
||||
{ search record/object symtable first for a sutable operator }
|
||||
if def_from.typ in [recorddef,objectdef] then
|
||||
symtablestack.push(tabstractrecorddef(def_from).symtable);
|
||||
{ if type conversion is explicit then search first for explicit
|
||||
operator overload and if not found then use implicit operator }
|
||||
if cdo_explicit in cdoptions then
|
||||
operatorpd:=search_assignment_operator(def_from,def_to,true)
|
||||
else
|
||||
operatorpd:=nil;
|
||||
if operatorpd=nil then
|
||||
operatorpd:=search_assignment_operator(def_from,def_to,false);
|
||||
if def_from.typ in [recorddef,objectdef] then
|
||||
symtablestack.pop(tabstractrecorddef(def_from).symtable);
|
||||
operatorpd:=search_assignment_operator(def_from,def_to,cdo_explicit in cdoptions);
|
||||
if assigned(operatorpd) then
|
||||
eq:=te_convert_operator;
|
||||
end;
|
||||
|
@ -1360,9 +1360,9 @@ parser_e_class_methods_only_static_in_records=03301_E_Class methods must be stat
|
||||
parser_e_no_constructor_in_records=03302_E_Constructors aren't allowed in records
|
||||
% Constructor declarations aren't allowed in records.
|
||||
% \end{description}
|
||||
parser_e_at_least_one_argument_must_be_of_type=03303_E_At least one argument must be of type "$1"
|
||||
% It is required that at least one argument be of type of structure where this method is defined.
|
||||
% For example class operators must contain at least one argument of the structure where they are defined.
|
||||
parser_e_at_least_one_argument_must_be_of_type=03303_E_Either the result or at least one parameter must be of type "$1"
|
||||
% It is required that either the result of the routine or at least one of its parameters be of the specified type.
|
||||
% For example class operators either take an instance of the structuted type in which they are defined, or they return one.
|
||||
parser_e_cant_use_type_parameters_here=03304_E_Type parameters may require initialization/finalization - can't be used in variant records
|
||||
% Type parameters may be specialized with types which (e.g. \var{ansistring}) need initialization/finalization
|
||||
% code which is implicitly generated by the compiler.
|
||||
|
@ -882,7 +882,7 @@ const
|
||||
option_info=11024;
|
||||
option_help_pages=11025;
|
||||
|
||||
MsgTxtSize = 58664;
|
||||
MsgTxtSize = 58686;
|
||||
|
||||
MsgIdxMax : array[1..20] of longint=(
|
||||
24,88,305,99,84,54,111,22,202,63,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1443,7 +1443,10 @@ implementation
|
||||
else
|
||||
begin
|
||||
read_returndef(pd);
|
||||
if (po_classmethod in pd.procoptions) then
|
||||
{ check that class operators have either return type of structure or }
|
||||
{ at least one argument of that type }
|
||||
if (po_classmethod in pd.procoptions) and
|
||||
(pd.returndef <> pd.struct) then
|
||||
begin
|
||||
found:=false;
|
||||
for i := 0 to pd.parast.SymList.Count - 1 do
|
||||
|
@ -2286,9 +2286,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function search_assignment_operator(from_def,to_def:Tdef;explicit:boolean):Tprocdef;
|
||||
const
|
||||
op_token:array[boolean] of ttoken=(_ASSIGNMENT,_OP_EXPLICIT);
|
||||
function search_specific_assignment_operator(assignment_type:ttoken;from_def,to_def:Tdef):Tprocdef;
|
||||
var
|
||||
sym : Tprocsym;
|
||||
hashedid : THashedIDString;
|
||||
@ -2298,7 +2296,7 @@ implementation
|
||||
bestpd : tprocdef;
|
||||
stackitem : psymtablestackitem;
|
||||
begin
|
||||
hashedid.id:=overloaded_names[op_token[explicit]];
|
||||
hashedid.id:=overloaded_names[assignment_type];
|
||||
besteq:=te_incompatible;
|
||||
bestpd:=nil;
|
||||
stackitem:=symtablestack.stack;
|
||||
@ -2326,6 +2324,31 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function search_assignment_operator(from_def,to_def:Tdef;explicit:boolean):Tprocdef;
|
||||
begin
|
||||
{ search record/object symtable first for a suitable operator }
|
||||
if from_def.typ in [recorddef,objectdef] then
|
||||
symtablestack.push(tabstractrecorddef(from_def).symtable);
|
||||
if to_def.typ in [recorddef,objectdef] then
|
||||
symtablestack.push(tabstractrecorddef(to_def).symtable);
|
||||
|
||||
{ if type conversion is explicit then search first for explicit
|
||||
operator overload and if not found then use implicit operator }
|
||||
if explicit then
|
||||
result:=search_specific_assignment_operator(_OP_EXPLICIT,from_def,to_def)
|
||||
else
|
||||
result:=nil;
|
||||
if result=nil then
|
||||
result:=search_specific_assignment_operator(_ASSIGNMENT,from_def,to_def);
|
||||
|
||||
{ restore symtable stack }
|
||||
if to_def.typ in [recorddef,objectdef] then
|
||||
symtablestack.pop(tabstractrecorddef(to_def).symtable);
|
||||
if from_def.typ in [recorddef,objectdef] then
|
||||
symtablestack.pop(tabstractrecorddef(from_def).symtable);
|
||||
end;
|
||||
|
||||
|
||||
function search_enumerator_operator(from_def,to_def:Tdef): Tprocdef;
|
||||
var
|
||||
sym : Tprocsym;
|
||||
|
24
tests/test/toperator12.pp
Normal file
24
tests/test/toperator12.pp
Normal file
@ -0,0 +1,24 @@
|
||||
program toperator12;
|
||||
|
||||
{$ifdef FPC}
|
||||
{$mode Delphi}
|
||||
{$endif}
|
||||
|
||||
type
|
||||
R = record
|
||||
F: Integer;
|
||||
class operator Implicit(const v: integer): R;
|
||||
end;
|
||||
|
||||
class operator R.Implicit(const v: integer): R;
|
||||
begin
|
||||
Result.F := v;
|
||||
end;
|
||||
|
||||
var
|
||||
x: R;
|
||||
begin
|
||||
x := 42;
|
||||
if x.F <> 42 then
|
||||
halt(1);
|
||||
end.
|
Loading…
Reference in New Issue
Block a user