|
@@ -152,10 +152,22 @@ interface
|
|
function token2managementoperator(optoken:ttoken):tmanagementoperator;
|
|
function token2managementoperator(optoken:ttoken):tmanagementoperator;
|
|
|
|
|
|
{ check operator args and result type }
|
|
{ check operator args and result type }
|
|
|
|
+
|
|
|
|
+ type
|
|
|
|
+ toverload_check_flag = (
|
|
|
|
+ ocf_check_non_overloadable, { also check operators that are (currently) considered as
|
|
|
|
+ not overloadable (e.g. the "+" operator for dynamic arrays
|
|
|
|
+ if modeswitch arrayoperators is active) }
|
|
|
|
+ ocf_check_only { only check whether the operator is overloaded, but don't
|
|
|
|
+ modify the passed in node (return true if the operator is
|
|
|
|
+ overloaded, false otherwise) }
|
|
|
|
+ );
|
|
|
|
+ toverload_check_flags = set of toverload_check_flag;
|
|
|
|
+
|
|
function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
|
|
function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
|
|
function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
|
|
function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
|
|
- function isunaryoverloaded(var t : tnode) : boolean;
|
|
|
|
- function isbinaryoverloaded(var t : tnode) : boolean;
|
|
|
|
|
|
+ function isunaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
|
|
|
|
+ function isbinaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
|
|
|
|
|
|
{ Register Allocation }
|
|
{ Register Allocation }
|
|
procedure make_not_regable(p : tnode; how: tregableinfoflags);
|
|
procedure make_not_regable(p : tnode; how: tregableinfoflags);
|
|
@@ -706,7 +718,7 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- function isunaryoverloaded(var t : tnode) : boolean;
|
|
|
|
|
|
+ function isunaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
|
|
var
|
|
var
|
|
ld : tdef;
|
|
ld : tdef;
|
|
optoken : ttoken;
|
|
optoken : ttoken;
|
|
@@ -728,11 +740,11 @@ implementation
|
|
else
|
|
else
|
|
inlinenumber:=in_none;
|
|
inlinenumber:=in_none;
|
|
|
|
|
|
- if not isunaryoperatoroverloadable(t.nodetype,inlinenumber,ld) then
|
|
|
|
|
|
+ if not (ocf_check_non_overloadable in ocf) and not isunaryoperatoroverloadable(t.nodetype,inlinenumber,ld) then
|
|
exit;
|
|
exit;
|
|
|
|
|
|
{ operator overload is possible }
|
|
{ operator overload is possible }
|
|
- result:=true;
|
|
|
|
|
|
+ result:=not (ocf_check_only in ocf);
|
|
|
|
|
|
optoken:=NOTOKEN;
|
|
optoken:=NOTOKEN;
|
|
case t.nodetype of
|
|
case t.nodetype of
|
|
@@ -752,8 +764,11 @@ implementation
|
|
end;
|
|
end;
|
|
if (optoken=NOTOKEN) then
|
|
if (optoken=NOTOKEN) then
|
|
begin
|
|
begin
|
|
- CGMessage(parser_e_operator_not_overloaded);
|
|
|
|
- t:=cnothingnode.create;
|
|
|
|
|
|
+ if not (ocf_check_only in ocf) then
|
|
|
|
+ begin
|
|
|
|
+ CGMessage(parser_e_operator_not_overloaded);
|
|
|
|
+ t:=cnothingnode.create;
|
|
|
|
+ end;
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -771,10 +786,13 @@ implementation
|
|
{ stop when there are no operators found }
|
|
{ stop when there are no operators found }
|
|
if candidates.count=0 then
|
|
if candidates.count=0 then
|
|
begin
|
|
begin
|
|
- CGMessage2(parser_e_operator_not_overloaded_2,ld.typename,arraytokeninfo[optoken].str);
|
|
|
|
candidates.free;
|
|
candidates.free;
|
|
ppn.free;
|
|
ppn.free;
|
|
- t:=cnothingnode.create;
|
|
|
|
|
|
+ if not (ocf_check_only in ocf) then
|
|
|
|
+ begin
|
|
|
|
+ CGMessage2(parser_e_operator_not_overloaded_2,ld.typename,arraytokeninfo[optoken].str);
|
|
|
|
+ t:=cnothingnode.create;
|
|
|
|
+ end;
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -789,15 +807,18 @@ implementation
|
|
{ exit when no overloads are found }
|
|
{ exit when no overloads are found }
|
|
if cand_cnt=0 then
|
|
if cand_cnt=0 then
|
|
begin
|
|
begin
|
|
- CGMessage2(parser_e_operator_not_overloaded_2,ld.typename,arraytokeninfo[optoken].str);
|
|
|
|
candidates.free;
|
|
candidates.free;
|
|
ppn.free;
|
|
ppn.free;
|
|
- t:=cnothingnode.create;
|
|
|
|
|
|
+ if not (ocf_check_only in ocf) then
|
|
|
|
+ begin
|
|
|
|
+ CGMessage2(parser_e_operator_not_overloaded_2,ld.typename,arraytokeninfo[optoken].str);
|
|
|
|
+ t:=cnothingnode.create;
|
|
|
|
+ end;
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ Multiple candidates left? }
|
|
{ Multiple candidates left? }
|
|
- if cand_cnt>1 then
|
|
|
|
|
|
+ if (cand_cnt>1) and not (ocf_check_only in ocf) then
|
|
begin
|
|
begin
|
|
CGMessage(type_e_cant_choose_overload_function);
|
|
CGMessage(type_e_cant_choose_overload_function);
|
|
{$ifdef EXTDEBUG}
|
|
{$ifdef EXTDEBUG}
|
|
@@ -810,6 +831,13 @@ implementation
|
|
end;
|
|
end;
|
|
candidates.free;
|
|
candidates.free;
|
|
|
|
|
|
|
|
+ if ocf_check_only in ocf then
|
|
|
|
+ begin
|
|
|
|
+ ppn.free;
|
|
|
|
+ result:=true;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+
|
|
addsymref(operpd.procsym);
|
|
addsymref(operpd.procsym);
|
|
|
|
|
|
{ the nil as symtable signs firstcalln that this is
|
|
{ the nil as symtable signs firstcalln that this is
|
|
@@ -822,7 +850,7 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- function isbinaryoverloaded(var t : tnode) : boolean;
|
|
|
|
|
|
+ function isbinaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
|
|
var
|
|
var
|
|
rd,ld : tdef;
|
|
rd,ld : tdef;
|
|
optoken : ttoken;
|
|
optoken : ttoken;
|
|
@@ -915,11 +943,14 @@ implementation
|
|
{ load easier access variables }
|
|
{ load easier access variables }
|
|
ld:=tbinarynode(t).left.resultdef;
|
|
ld:=tbinarynode(t).left.resultdef;
|
|
rd:=tbinarynode(t).right.resultdef;
|
|
rd:=tbinarynode(t).right.resultdef;
|
|
- if not isbinaryoperatoroverloadable(t.nodetype,ld,tbinarynode(t).left.nodetype,rd,tbinarynode(t).right.nodetype) then
|
|
|
|
|
|
+ if not (ocf_check_non_overloadable in ocf) and
|
|
|
|
+ not isbinaryoperatoroverloadable(t.nodetype,ld,tbinarynode(t).left.nodetype,rd,tbinarynode(t).right.nodetype) then
|
|
exit;
|
|
exit;
|
|
|
|
|
|
{ operator overload is possible }
|
|
{ operator overload is possible }
|
|
- result:=true;
|
|
|
|
|
|
+ { if we only check for the existance of the overload, then we assume that
|
|
|
|
+ it is not overloaded }
|
|
|
|
+ result:=not (ocf_check_only in ocf);
|
|
|
|
|
|
case t.nodetype of
|
|
case t.nodetype of
|
|
equaln:
|
|
equaln:
|
|
@@ -964,16 +995,19 @@ implementation
|
|
optoken:=_OP_IN;
|
|
optoken:=_OP_IN;
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- CGMessage(parser_e_operator_not_overloaded);
|
|
|
|
- t:=cnothingnode.create;
|
|
|
|
|
|
+ if not (ocf_check_only in ocf) then
|
|
|
|
+ begin
|
|
|
|
+ CGMessage(parser_e_operator_not_overloaded);
|
|
|
|
+ t:=cnothingnode.create;
|
|
|
|
+ end;
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
- cand_cnt:=search_operator(optoken,optoken<>_NE);
|
|
|
|
|
|
+ cand_cnt:=search_operator(optoken,(optoken<>_NE) and not (ocf_check_only in ocf));
|
|
|
|
|
|
{ no operator found for "<>" then search for "=" operator }
|
|
{ no operator found for "<>" then search for "=" operator }
|
|
- if (cand_cnt=0) and (optoken=_NE) then
|
|
|
|
|
|
+ if (cand_cnt=0) and (optoken=_NE) and not (ocf_check_only in ocf) then
|
|
begin
|
|
begin
|
|
ppn.free;
|
|
ppn.free;
|
|
ppn:=nil;
|
|
ppn:=nil;
|
|
@@ -985,7 +1019,15 @@ implementation
|
|
if (cand_cnt=0) then
|
|
if (cand_cnt=0) then
|
|
begin
|
|
begin
|
|
ppn.free;
|
|
ppn.free;
|
|
- t:=cnothingnode.create;
|
|
|
|
|
|
+ if not (ocf_check_only in ocf) then
|
|
|
|
+ t:=cnothingnode.create;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if ocf_check_only in ocf then
|
|
|
|
+ begin
|
|
|
|
+ ppn.free;
|
|
|
|
+ result:=true;
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
|