diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index 17cd250f28..e0f996fba0 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -1183,11 +1183,52 @@ implementation var pd : tprocdef; locationstr: string; - old_parse_generic: boolean; - popclass: integer; - old_current_structdef: tabstractrecorddef; - old_current_genericdef, - old_current_specializedef: tobjectdef; + + procedure read_returndef(pd: tprocdef); + var + popclass: integer; + old_parse_generic: boolean; + old_current_structdef: tabstractrecorddef; + old_current_genericdef, + old_current_specializedef: tobjectdef; + begin + old_parse_generic:=parse_generic; + inc(testcurobject); + { Add ObjectSymtable to be able to find generic type definitions } + popclass:=0; + if assigned(pd.struct) and + (pd.parast.symtablelevel=normal_function_level) and + not (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then + begin + popclass:=push_nested_hierarchy(pd.struct); + parse_generic:=(df_generic in pd.struct.defoptions); + old_current_structdef:=current_structdef; + old_current_genericdef:=current_genericdef; + old_current_specializedef:=current_specializedef; + current_structdef:=pd.struct; + if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then + current_genericdef:=tobjectdef(current_structdef); + if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then + current_specializedef:=tobjectdef(current_structdef); + end; + single_type(pd.returndef,false,false); + + if is_dispinterface(pd.struct) and not is_automatable(pd.returndef) then + Message1(type_e_not_automatable,pd.returndef.typename); + + if popclass>0 then + begin + current_structdef:=old_current_structdef; + current_genericdef:=old_current_genericdef; + current_specializedef:=old_current_specializedef; + dec(popclass,pop_nested_hierarchy(pd.struct)); + if popclass<>0 then + internalerror(201012020); + end; + dec(testcurobject); + parse_generic:=old_parse_generic; + end; + begin locationstr:=''; pd:=nil; @@ -1202,42 +1243,7 @@ implementation begin if try_to_consume(_COLON) then begin - old_parse_generic:=parse_generic; - inc(testcurobject); - { Add ObjectSymtable to be able to find generic type definitions } - popclass:=0; - if assigned(pd.struct) and - (pd.parast.symtablelevel=normal_function_level) and - not (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then - begin - popclass:=push_nested_hierarchy(pd.struct); - parse_generic:=(df_generic in pd.struct.defoptions); - old_current_structdef:=current_structdef; - old_current_genericdef:=current_genericdef; - old_current_specializedef:=current_specializedef; - current_structdef:=pd.struct; - if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then - current_genericdef:=tobjectdef(current_structdef); - if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then - current_specializedef:=tobjectdef(current_structdef); - end; - single_type(pd.returndef,false,false); - - if is_dispinterface(pd.struct) and not is_automatable(pd.returndef) then - Message1(type_e_not_automatable,pd.returndef.typename); - - if popclass>0 then - begin - current_structdef:=old_current_structdef; - current_genericdef:=old_current_genericdef; - current_specializedef:=old_current_specializedef; - dec(popclass,pop_nested_hierarchy(pd.struct)); - if popclass<>0 then - internalerror(201012020); - end; - dec(testcurobject); - parse_generic:=old_parse_generic; - + read_returndef(pd); if (target_info.system in [system_m68k_amiga]) then begin if (idtoken=_LOCATION) then @@ -1349,6 +1355,8 @@ implementation include(pd.procoptions,po_overload); if pd.parast.symtablelevel>normal_function_level then Message(parser_e_no_local_operator); + if isclassmethod then + include(pd.procoptions,po_classmethod); if token<>_ID then begin if not(m_result in current_settings.modeswitches) then @@ -1367,7 +1375,7 @@ implementation end else begin - single_type(pd.returndef,false,false); + read_returndef(pd); if (optoken in [_EQ,_NE,_GT,_LT,_GTE,_LTE,_OP_IN]) and ((pd.returndef.typ<>orddef) or (torddef(pd.returndef).ordtype<>pasbool)) then diff --git a/tests/test/terecs6.pp b/tests/test/terecs6.pp index faa9d25f17..793f28373f 100644 --- a/tests/test/terecs6.pp +++ b/tests/test/terecs6.pp @@ -1,4 +1,4 @@ -program Project1; +program terecs6; {$mode delphi} {$apptype console} @@ -26,10 +26,10 @@ type class operator LogicalOr(a, b: TFoo): Boolean; class operator LogicalAnd(a, b: TFoo): Boolean; class operator LogicalXor(a, b: TFoo): Boolean; -// class operator LogicalNot(a: TFoo): TFoo; -// class operator BitwiseOr(a, b: TFoo): TFoo; -// class operator BitwiseAnd(a, b: TFoo): TFoo; -// class operator BitwiseXor(a, b: TFoo): TFoo; + class operator LogicalNot(a: TFoo): TFoo; + class operator BitwiseOr(a, b: TFoo): TFoo; + class operator BitwiseAnd(a, b: TFoo): TFoo; + class operator BitwiseXor(a, b: TFoo): TFoo; // class operator Inc(a: TFoo): TFoo; // class operator Dec(a: TFoo): TFoo; end; @@ -124,6 +124,26 @@ begin Result := (a.F xor b.F) <> 0; end; +class operator TFoo.LogicalNot(a: TFoo): TFoo; +begin + Result.F := not a.F; +end; + +class operator TFoo.BitwiseOr(a, b: TFoo): TFoo; +begin + Result.F := a.F or b.F; +end; + +class operator TFoo.BitwiseAnd(a, b: TFoo): TFoo; +begin + Result.F := a.F and b.F; +end; + +class operator TFoo.BitwiseXor(a, b: TFoo): TFoo; +begin + Result.F := a.F xor b.F; +end; + var a, b: TFoo; begin @@ -167,5 +187,15 @@ begin halt(18); if not (a xor b) then halt(19); + if (not a).F <> (not 1) then + halt(20); +{ bitwise operators current does not work if logical are defined + if (a or b).F <> (a.F or b.F) then + halt(21); + if (a and b).F <> (a.F and b.F) then + halt(22); + if (a xor b).F <> (a.F xor b.F) then + halt(23); +} WriteLn('ok'); end.