mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 16:29:27 +02:00
* synchronized with trunk
git-svn-id: branches/wasm@46956 -
This commit is contained in:
commit
ca239b4e21
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -12308,7 +12308,6 @@ rtl/z80/stringss.inc svneol=native#text/plain
|
||||
rtl/z80/z80.inc svneol=native#text/plain
|
||||
rtl/zxspectrum/Makefile svneol=native#text/plain
|
||||
rtl/zxspectrum/Makefile.fpc svneol=native#text/plain
|
||||
rtl/zxspectrum/prt0.asm svneol=native#text/plain
|
||||
rtl/zxspectrum/rtldefs.inc svneol=native#text/plain
|
||||
rtl/zxspectrum/si_prc.pp svneol=native#text/plain
|
||||
rtl/zxspectrum/sysdir.inc svneol=native#text/plain
|
||||
@ -13391,6 +13390,7 @@ tests/tbs/tb0674.pp svneol=native#text/pascal
|
||||
tests/tbs/tb0675.pp svneol=native#text/pascal
|
||||
tests/tbs/tb0676.pp svneol=native#text/pascal
|
||||
tests/tbs/tb0676a.pp svneol=native#text/plain
|
||||
tests/tbs/tb0677.pp svneol=native#text/pascal
|
||||
tests/tbs/ub0060.pp svneol=native#text/plain
|
||||
tests/tbs/ub0069.pp svneol=native#text/plain
|
||||
tests/tbs/ub0119.pp svneol=native#text/plain
|
||||
@ -18516,6 +18516,7 @@ tests/webtbs/tw37779.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw3778.pp svneol=native#text/plain
|
||||
tests/webtbs/tw37780.pp svneol=native#text/plain
|
||||
tests/webtbs/tw3780.pp svneol=native#text/plain
|
||||
tests/webtbs/tw37806.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw3782.pp svneol=native#text/plain
|
||||
tests/webtbs/tw3796.pp svneol=native#text/plain
|
||||
tests/webtbs/tw3805.pp svneol=native#text/plain
|
||||
|
@ -5138,6 +5138,7 @@ implementation
|
||||
begin
|
||||
list:=TAsmList(arg);
|
||||
if (tsym(p).typ=paravarsym) and
|
||||
(tparavarsym(p).is_used) and
|
||||
((vo_has_local_copy in tparavarsym(p).varoptions) or
|
||||
(not(target_info.system in systems_caller_copy_addr_value_para) and
|
||||
(is_open_array(tparavarsym(p).vardef) or
|
||||
|
@ -139,6 +139,8 @@ unit aoptcpu;
|
||||
case taicpu(p).opcode Of
|
||||
A_AND:
|
||||
Result:=OptPass1And(p);
|
||||
A_IMUL:
|
||||
Result:=OptPass1Imul(p);
|
||||
A_CMP:
|
||||
Result:=OptPass1Cmp(p);
|
||||
A_VPXOR:
|
||||
|
@ -3477,7 +3477,7 @@ implementation
|
||||
inserttypeconv(tcallparanode(tcallparanode(left).right).left,
|
||||
tsetdef(left.resultdef).elementdef);
|
||||
end
|
||||
else
|
||||
else if left.resultdef.typ<>undefineddef then
|
||||
CGMessage(type_e_mismatch);
|
||||
end;
|
||||
in_pack_x_y_z,
|
||||
|
@ -138,6 +138,7 @@ unit aoptx86;
|
||||
function OptPass1Cmp(var p : tai) : boolean;
|
||||
function OptPass1PXor(var p : tai) : boolean;
|
||||
function OptPass1VPXor(var p: tai): boolean;
|
||||
function OptPass1Imul(var p : tai) : boolean;
|
||||
|
||||
function OptPass2MOV(var p : tai) : boolean;
|
||||
function OptPass2Imul(var p : tai) : boolean;
|
||||
@ -4194,6 +4195,38 @@ unit aoptx86;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TX86AsmOptimizer.OptPass1Imul(var p: tai): boolean;
|
||||
var
|
||||
hp1 : tai;
|
||||
begin
|
||||
result:=false;
|
||||
{ replace
|
||||
IMul const,%mreg1,%mreg2
|
||||
Mov %reg2,%mreg3
|
||||
dealloc %mreg3
|
||||
|
||||
by
|
||||
Imul const,%mreg1,%mreg23
|
||||
}
|
||||
if (taicpu(p).ops=3) and
|
||||
GetNextInstruction(p,hp1) and
|
||||
MatchInstruction(hp1,A_MOV,[taicpu(p).opsize]) and
|
||||
MatchOperand(taicpu(p).oper[2]^,taicpu(hp1).oper[0]^) and
|
||||
(taicpu(hp1).oper[1]^.typ=top_reg) then
|
||||
begin
|
||||
TransferUsedRegs(TmpUsedRegs);
|
||||
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
|
||||
if not(RegUsedAfterInstruction(taicpu(hp1).oper[0]^.reg,hp1,TmpUsedRegs)) then
|
||||
begin
|
||||
taicpu(p).loadoper(2,taicpu(hp1).oper[1]^);
|
||||
DebugMsg(SPeepholeOptimization + 'ImulMov2Imul done',p);
|
||||
RemoveInstruction(hp1);
|
||||
result:=true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean;
|
||||
|
||||
|
@ -73,6 +73,8 @@ uses
|
||||
case taicpu(p).opcode of
|
||||
A_AND:
|
||||
Result:=OptPass1AND(p);
|
||||
A_IMUL:
|
||||
Result:=OptPass1Imul(p);
|
||||
A_MOV:
|
||||
Result:=OptPass1MOV(p);
|
||||
A_MOVSX,
|
||||
@ -88,6 +90,8 @@ uses
|
||||
A_VMOVUPS,
|
||||
A_VMOVUPD:
|
||||
result:=OptPass1_V_MOVAP(p);
|
||||
A_VSQRTSD,
|
||||
A_VSQRTSS,
|
||||
A_VDIVSD,
|
||||
A_VDIVSS,
|
||||
A_VSUBSD,
|
||||
|
@ -672,6 +672,7 @@ type
|
||||
pbivnMessageInt,
|
||||
pbivnMessageStr,
|
||||
pbivnLocalModuleRef,
|
||||
pbivnLocalProcRef,
|
||||
pbivnLocalTypeRef,
|
||||
pbivnLoop,
|
||||
pbivnLoopEnd,
|
||||
@ -854,6 +855,7 @@ const
|
||||
'$msgint', // pbivnMessageInt
|
||||
'$msgstr', // pbivnMessageStr
|
||||
'$lm', // pbivnLocalModuleRef
|
||||
'$lp', // pbivnLocalProcRef
|
||||
'$lt', // pbivnLocalTypeRef
|
||||
'$l', // pbivnLoop
|
||||
'$end', // pbivnLoopEnd
|
||||
@ -2003,6 +2005,8 @@ type
|
||||
Function CreateReferencePathExpr(El: TPasElement; AContext : TConvertContext;
|
||||
Full: boolean = false; Ref: TResolvedReference = nil): TJSElement; virtual;
|
||||
Function CreateGlobalTypePath(El: TPasType; AContext : TConvertContext): string; virtual;
|
||||
Function CreateStaticProcPath(El: TPasProcedure; AContext : TConvertContext): string; virtual;
|
||||
Function CreateGlobalElPath(El: TPasElement; AContext : TConvertContext): string; virtual;
|
||||
// section
|
||||
Function CreateImplementationSection(El: TPasModule; IntfContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement; virtual;
|
||||
Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
||||
@ -3676,7 +3680,6 @@ procedure TPas2JSResolver.RenameSpecialized(SpecializedItem: TPRSpecializedItem
|
||||
var
|
||||
GenScope: TPasGenericScope;
|
||||
NewName: String;
|
||||
ProcScope: TPas2JSProcedureScope;
|
||||
begin
|
||||
if SpecializedItem=nil then exit;
|
||||
NewName:=SpecializedItem.GenericEl.Name+'$G'+IntToStr(SpecializedItem.Index+1);
|
||||
@ -3690,19 +3693,11 @@ begin
|
||||
else if GenScope is TPas2JSProcTypeScope then
|
||||
TPas2JSProcTypeScope(GenScope).JSName:=NewName
|
||||
else if GenScope is TPas2JSProcedureScope then
|
||||
begin
|
||||
ProcScope:=TPas2JSProcedureScope(GenScope);
|
||||
if ProcScope.OverloadName<>'' then
|
||||
NewName:=ProcScope.OverloadName
|
||||
else
|
||||
NewName:=SpecializedItem.GenericEl.Name;
|
||||
NewName:=LastDottedIdentifier(NewName);
|
||||
ProcScope.JSName:=NewName+'$G'+IntToStr(SpecializedItem.Index+1);
|
||||
end
|
||||
// handled in GetOverloadName
|
||||
else
|
||||
RaiseNotYetImplemented(20200906203342,SpecializedItem.SpecializedEl,GetObjName(GenScope));
|
||||
{$IFDEF VerbosePas2JS}
|
||||
//writeln('TPas2JSResolver.RenameSpecialized GenericEl=',GetObjPath(SpecializedItem.GenericEl),' Spec=',GetObjPath(SpecializedItem.SpecializedEl),' JSName="',NewName,'"');
|
||||
writeln('TPas2JSResolver.RenameSpecialized GenericEl=',GetObjPath(SpecializedItem.GenericEl),' Spec=',GetObjPath(SpecializedItem.SpecializedEl),' JSName="',NewName,'"');
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -6824,13 +6819,13 @@ begin
|
||||
ProcScope:=TPas2JSProcedureScope(Data);
|
||||
if ProcScope.SpecializedFromItem<>nil then
|
||||
begin
|
||||
// specialized proc -> generic name + 's' + index
|
||||
// specialized proc -> generic name + '$G' + index
|
||||
GenEl:=ProcScope.SpecializedFromItem.GenericEl;
|
||||
GenScope:=TPas2JSProcedureScope(GenEl.CustomData);
|
||||
Result:=GenScope.OverloadName;
|
||||
if Result='' then
|
||||
Result:=GenEl.Name+'$';
|
||||
Result:=Result+'s'+IntToStr(ProcScope.SpecializedFromItem.Index);
|
||||
Result:=Result+'G'+IntToStr(ProcScope.SpecializedFromItem.Index+1);
|
||||
end
|
||||
else
|
||||
Result:=ProcScope.OverloadName;
|
||||
@ -23752,6 +23747,15 @@ var
|
||||
and not TPasProcedure(Proc).IsStatic;
|
||||
end;
|
||||
|
||||
function ProcHasNoSelf(Proc: TPasProcedure): boolean;
|
||||
begin
|
||||
if Proc=nil then exit(false);
|
||||
if not (Proc.Parent is TPasMembersType) then
|
||||
exit(true);
|
||||
if Proc.IsStatic then exit(true);
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
procedure Append_GetClass(Member: TPasElement);
|
||||
var
|
||||
P: TPasElement;
|
||||
@ -23928,10 +23932,18 @@ begin
|
||||
if El.Parent=nil then
|
||||
RaiseNotSupported(El,AContext,20170201172141,GetObjName(El));
|
||||
|
||||
if (coShortRefGlobals in Options) and (El is TPasType) and (Kind=rpkPathAndName) then
|
||||
if (coShortRefGlobals in Options) and (Kind=rpkPathAndName) then
|
||||
begin
|
||||
Result:=CreateGlobalTypePath(TPasType(El),AContext);
|
||||
exit;
|
||||
if (El is TPasType) then
|
||||
begin
|
||||
Result:=CreateGlobalTypePath(TPasType(El),AContext);
|
||||
exit;
|
||||
end
|
||||
else if (El is TPasProcedure) and ProcHasNoSelf(TPasProcedure(El)) then
|
||||
begin
|
||||
Result:=CreateStaticProcPath(TPasProcedure(El),AContext);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
El:=ImplToDecl(El);
|
||||
@ -24126,12 +24138,27 @@ function TPasToJSConverter.CreateGlobalTypePath(El: TPasType;
|
||||
AContext: TConvertContext): string;
|
||||
var
|
||||
aType: TPasType;
|
||||
Parent: TPasElement;
|
||||
CurModule: TPasModule;
|
||||
ShortRefGlobals: Boolean;
|
||||
begin
|
||||
aType:=AContext.Resolver.ResolveAliasType(El);
|
||||
Result:=AContext.GetLocalName(aType,[cvkGlobal]);
|
||||
Result:=CreateGlobalElPath(aType,AContext);
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.CreateStaticProcPath(El: TPasProcedure;
|
||||
AContext: TConvertContext): string;
|
||||
begin
|
||||
if (not El.IsStatic) and (El.Parent is TPasMembersType) then
|
||||
RaiseNotSupported(El,AContext,20200925104007);
|
||||
Result:=CreateGlobalElPath(El,AContext);
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.CreateGlobalElPath(El: TPasElement;
|
||||
AContext: TConvertContext): string;
|
||||
var
|
||||
ShortRefGlobals: Boolean;
|
||||
Parent: TPasElement;
|
||||
CurModule: TPasModule;
|
||||
begin
|
||||
Result:=AContext.GetLocalName(El,[cvkGlobal]);
|
||||
if Result<>'' then
|
||||
exit; // already exists
|
||||
ShortRefGlobals:=coShortRefGlobals in Options;
|
||||
@ -24157,8 +24184,8 @@ begin
|
||||
else if Parent is TPasModule then
|
||||
Result:=TransformModuleName(TPasModule(Parent),true,AContext)
|
||||
else
|
||||
RaiseNotSupported(El,AContext,20200609230526,GetObjName(aType));
|
||||
Result:=Result+'.'+TransformElToJSName(aType,AContext);
|
||||
RaiseNotSupported(El,AContext,20200609230526,GetObjPath(El));
|
||||
Result:=Result+'.'+TransformElToJSName(El,AContext);
|
||||
if ShortRefGlobals then
|
||||
Result:=CreateGlobalAlias(El,Result,AContext);
|
||||
end;
|
||||
@ -25947,12 +25974,13 @@ begin
|
||||
Result:=GetBIName(pbivnLocalModuleRef)
|
||||
else if El is TPasType then
|
||||
Result:=GetBIName(pbivnLocalTypeRef)
|
||||
else if El is TPasProcedure then
|
||||
Result:=GetBIName(pbivnLocalProcRef)
|
||||
else
|
||||
RaiseNotSupported(El,AContext,20200608160225);
|
||||
Result:=FuncContext.CreateLocalIdentifier(Result);
|
||||
SectionContext.AddLocalVar(Result,El,cvkGlobal,false);
|
||||
|
||||
// ToDo: check if from a unit used by impl uses section
|
||||
if aResolver.ImplementationUsesUnit(ElModule) then
|
||||
begin
|
||||
// insert var $lm = null;
|
||||
|
@ -1720,7 +1720,7 @@ begin
|
||||
CheckSource('TestGenProc_Function_ObjFPC',
|
||||
LinesToStr([ // statements
|
||||
'this.w = 0;',
|
||||
'this.Run$s0 = function (a) {',
|
||||
'this.Run$G1 = function (a) {',
|
||||
' var Result = 0;',
|
||||
' var i = 0;',
|
||||
' a = i;',
|
||||
@ -1729,7 +1729,7 @@ begin
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.w = $mod.Run$s0(3);',
|
||||
'$mod.w = $mod.Run$G1(3);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1752,7 +1752,7 @@ begin
|
||||
CheckSource('TestGenProc_Function_Delphi',
|
||||
LinesToStr([ // statements
|
||||
'this.w = 0;',
|
||||
'this.Run$s0 = function (a) {',
|
||||
'this.Run$G1 = function (a) {',
|
||||
' var Result = 0;',
|
||||
' var i = 0;',
|
||||
' a = i;',
|
||||
@ -1761,7 +1761,7 @@ begin
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.w = $mod.Run$s0(3);',
|
||||
'$mod.w = $mod.Run$G1(3);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1784,20 +1784,20 @@ begin
|
||||
ConvertProgram;
|
||||
CheckSource('TestGenProc_Overload',
|
||||
LinesToStr([ // statements
|
||||
'this.DoIt$s0 = function (a, w) {',
|
||||
'this.DoIt$G1 = function (a, w) {',
|
||||
'};',
|
||||
'this.DoIt$s1 = function (a, w) {',
|
||||
'this.DoIt$G2 = function (a, w) {',
|
||||
'};',
|
||||
'this.DoIt$1s0 = function (a, b) {',
|
||||
'this.DoIt$1G1 = function (a, b) {',
|
||||
'};',
|
||||
'this.DoIt$1s1 = function (a, b) {',
|
||||
'this.DoIt$1G2 = function (a, b) {',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.DoIt$s0(3, 4);',
|
||||
'$mod.DoIt$s1(false, 5);',
|
||||
'$mod.DoIt$1s0(6, true);',
|
||||
'$mod.DoIt$1s1(7.3, true);',
|
||||
'$mod.DoIt$G1(3, 4);',
|
||||
'$mod.DoIt$G2(false, 5);',
|
||||
'$mod.DoIt$1G1(6, true);',
|
||||
'$mod.DoIt$1G2(7.3, true);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1817,15 +1817,15 @@ begin
|
||||
ConvertProgram;
|
||||
CheckSource('TestGenProc_infer_OverloadForward',
|
||||
LinesToStr([ // statements
|
||||
'this.Run$s0 = function (a, b) {',
|
||||
' $mod.Run$s0(1, true);',
|
||||
'this.Run$G1 = function (a, b) {',
|
||||
' $mod.Run$G1(1, true);',
|
||||
'};',
|
||||
'this.Run$s1 = function (a, b) {',
|
||||
' $mod.Run$s0(1, true);',
|
||||
'this.Run$G2 = function (a, b) {',
|
||||
' $mod.Run$G1(1, true);',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.Run$s1(1.3, true);',
|
||||
'$mod.Run$G2(1.3, true);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1857,20 +1857,20 @@ begin
|
||||
ConvertProgram;
|
||||
CheckSource('TestGenProc_infer_OverloadForward',
|
||||
LinesToStr([ // statements
|
||||
'this.Run$s0 = function (a, b) {',
|
||||
' $mod.Run$s0(1, true);',
|
||||
' $mod.Run$1s0(2, 3);',
|
||||
' $mod.Run$2s0("foo", "bar");',
|
||||
'this.Run$G1 = function (a, b) {',
|
||||
' $mod.Run$G1(1, true);',
|
||||
' $mod.Run$1G1(2, 3);',
|
||||
' $mod.Run$2G1("foo", "bar");',
|
||||
'};',
|
||||
'this.Run$1s0 = function (a, w) {',
|
||||
'this.Run$1G1 = function (a, w) {',
|
||||
'};',
|
||||
'this.Run$2s0 = function (a, b) {',
|
||||
'this.Run$2G1 = function (a, b) {',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.Run$s0(1, true);',
|
||||
'$mod.Run$1s0(2, 3);',
|
||||
'$mod.Run$2s0("foo", "bar");',
|
||||
'$mod.Run$G1(1, true);',
|
||||
'$mod.Run$1G1(2, 3);',
|
||||
'$mod.Run$2G1("foo", "bar");',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1894,20 +1894,20 @@ begin
|
||||
ConvertProgram;
|
||||
CheckSource('TestGenProc_TypeInfo',
|
||||
LinesToStr([ // statements
|
||||
'this.Run$s0 = function (a) {',
|
||||
'this.Run$G1 = function (a) {',
|
||||
' var p = null;',
|
||||
' p = rtl.word;',
|
||||
' p = rtl.word;',
|
||||
'};',
|
||||
'this.Run$s1 = function (a) {',
|
||||
'this.Run$G2 = function (a) {',
|
||||
' var p = null;',
|
||||
' p = rtl.string;',
|
||||
' p = rtl.string;',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.Run$s0(3);',
|
||||
'$mod.Run$s1("foo");',
|
||||
'$mod.Run$G1(3);',
|
||||
'$mod.Run$G2("foo");',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1931,21 +1931,21 @@ begin
|
||||
ConvertProgram;
|
||||
CheckSource('TestGenProc_Infer_Widen',
|
||||
LinesToStr([ // statements
|
||||
'this.Run$s0 = function (a, b) {',
|
||||
'this.Run$G1 = function (a, b) {',
|
||||
'};',
|
||||
'this.Run$s1 = function (a, b) {',
|
||||
'this.Run$G2 = function (a, b) {',
|
||||
'};',
|
||||
'this.Run$s2 = function (a, b) {',
|
||||
'this.Run$G3 = function (a, b) {',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.Run$s0(1, 2);',
|
||||
'$mod.Run$s0(2, 2);',
|
||||
'$mod.Run$s1(3, 2);',
|
||||
'$mod.Run$s1(4, 2);',
|
||||
'$mod.Run$s1(5, 2);',
|
||||
'$mod.Run$s2("a", "foo");',
|
||||
'$mod.Run$s2("bar", "c");',
|
||||
'$mod.Run$G1(1, 2);',
|
||||
'$mod.Run$G1(2, 2);',
|
||||
'$mod.Run$G2(3, 2);',
|
||||
'$mod.Run$G2(4, 2);',
|
||||
'$mod.Run$G2(5, 2);',
|
||||
'$mod.Run$G3("a", "foo");',
|
||||
'$mod.Run$G3("bar", "c");',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -1967,17 +1967,17 @@ begin
|
||||
ConvertProgram;
|
||||
CheckSource('TestGenProc_Infer_PassAsArg',
|
||||
LinesToStr([ // statements
|
||||
'this.Run$s0 = function (a) {',
|
||||
'this.Run$G1 = function (a) {',
|
||||
' var Result = 0;',
|
||||
' var b = 0;',
|
||||
' $mod.Run$s0($mod.Run$s0(3));',
|
||||
' $mod.Run$s0($mod.Run$s0(4));',
|
||||
' $mod.Run$G1($mod.Run$G1(3));',
|
||||
' $mod.Run$G1($mod.Run$G1(4));',
|
||||
' return Result;',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.Run$s0($mod.Run$s0(5));',
|
||||
'$mod.Run$s0($mod.Run$s0(6));',
|
||||
'$mod.Run$G1($mod.Run$G1(5));',
|
||||
'$mod.Run$G1($mod.Run$G1(6));',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -2019,22 +2019,22 @@ begin
|
||||
' };',
|
||||
' this.$final = function () {',
|
||||
' };',
|
||||
' this.Run$s0 = function (a, b) {',
|
||||
' this.Run$s0(1, true);',
|
||||
' this.Run$1s0(2, 3);',
|
||||
' this.Run$2s0("foo", "bar");',
|
||||
' this.Run$G1 = function (a, b) {',
|
||||
' this.Run$G1(1, true);',
|
||||
' this.Run$1G1(2, 3);',
|
||||
' this.Run$2G1("foo", "bar");',
|
||||
' };',
|
||||
' this.Run$1s0 = function (a, w) {',
|
||||
' this.Run$1G1 = function (a, w) {',
|
||||
' };',
|
||||
' this.Run$2s0 = function (a, b) {',
|
||||
' this.Run$2G1 = function (a, b) {',
|
||||
' };',
|
||||
'});',
|
||||
'this.o = null;',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
'$mod.o.Run$s0(1, true);',
|
||||
'$mod.o.Run$1s0(2, 3);',
|
||||
'$mod.o.Run$2s0("foo", "bar");',
|
||||
'$mod.o.Run$G1(1, true);',
|
||||
'$mod.o.Run$1G1(2, 3);',
|
||||
'$mod.o.Run$2G1("foo", "bar");',
|
||||
'']));
|
||||
end;
|
||||
|
||||
|
@ -60,6 +60,7 @@ type
|
||||
procedure TestOptShortRefGlobals_Program;
|
||||
procedure TestOptShortRefGlobals_Unit_FromIntfImpl_ToIntfImpl;
|
||||
procedure TestOptShortRefGlobals_Property;
|
||||
procedure TestOptShortRefGlobals_GenericFunction;
|
||||
|
||||
// Whole Program Optimization
|
||||
procedure TestWPO_OmitLocalVar;
|
||||
@ -444,6 +445,51 @@ begin
|
||||
'']));
|
||||
end;
|
||||
|
||||
procedure TTestOptimizations.TestOptShortRefGlobals_GenericFunction;
|
||||
begin
|
||||
AddModuleWithIntfImplSrc('UnitA.pas',
|
||||
LinesToStr([
|
||||
'generic function Run<T>(a: T): T;',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'generic function Run<T>(a: T): T;',
|
||||
'begin',
|
||||
'end;',
|
||||
'']));
|
||||
StartUnit(true,[supTObject]);
|
||||
Add([
|
||||
'{$optimization JSShortRefGlobals}',
|
||||
'interface',
|
||||
'uses unita;',
|
||||
'type',
|
||||
' TEagle = class',
|
||||
' end;',
|
||||
'procedure Fly;',
|
||||
'implementation',
|
||||
'procedure Fly;',
|
||||
'begin',
|
||||
' specialize Run<TEagle>(nil);',
|
||||
'end;',
|
||||
'']);
|
||||
ConvertUnit;
|
||||
CheckSource('TestOptShortRefGlobals_GenericFunction',
|
||||
LinesToStr([
|
||||
'var $lm = pas.system;',
|
||||
'var $lt = $lm.TObject;',
|
||||
'var $lm1 = pas.UnitA;',
|
||||
'var $lp = $lm1.Run$G1;',
|
||||
'rtl.createClass(this, "TEagle", $lt, function () {',
|
||||
'});',
|
||||
'this.Fly = function () {',
|
||||
' $lp(null);',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'']),
|
||||
LinesToStr([
|
||||
'']));
|
||||
end;
|
||||
|
||||
procedure TTestOptimizations.TestWPO_OmitLocalVar;
|
||||
begin
|
||||
StartProgram(false);
|
||||
|
@ -960,7 +960,7 @@ begin
|
||||
if (I>LS) then
|
||||
I:=LS;
|
||||
I:=I-L+1;
|
||||
M:=AStartIndex-ACount+1; // 1 based
|
||||
M:=AStartIndex-ACount+2; // 1 based
|
||||
if M<1 then
|
||||
M:=1;
|
||||
while (Result=-1) and (I>=M) do
|
||||
|
@ -673,315 +673,6 @@ endif
|
||||
ifeq ($(FULL_TARGET),z80-amstradcpc)
|
||||
override TARGET_UNITS+=system si_prc
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-go32v2)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-win32)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-os2)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-freebsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-beos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-haiku)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-netbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-solaris)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-netware)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-openbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-wdosx)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-darwin)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-emx)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-watcom)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-netwlibc)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-wince)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-symbian)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-nativent)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-iphonesim)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-android)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i386-aros)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-netbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-amiga)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-atari)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-palmos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-macosclassic)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),m68k-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-netbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-amiga)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-macosclassic)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-darwin)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-morphos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-wii)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc-aix)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),sparc-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),sparc-netbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),sparc-solaris)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),sparc-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-freebsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-haiku)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-netbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-solaris)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-openbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-darwin)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-win64)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-iphonesim)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-android)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-aros)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),x86_64-dragonfly)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-netbsd)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-palmos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-wince)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-gba)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-nds)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-symbian)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-android)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-aros)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-freertos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),arm-ios)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc64-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc64-darwin)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc64-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),powerpc64-aix)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),avr-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),armeb-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),armeb-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),mips-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),mipsel-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),mipsel-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),mipsel-android)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),mips64el-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),jvm-java)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),jvm-android)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i8086-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i8086-msdos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),i8086-win16)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),aarch64-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),aarch64-darwin)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),aarch64-win64)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),aarch64-android)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),aarch64-ios)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),wasm-wasm)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),sparc64-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),riscv32-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),riscv32-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),riscv64-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),riscv64-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),xtensa-linux)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),xtensa-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),xtensa-freertos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),z80-embedded)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),z80-zxspectrum)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),z80-msxdos)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
ifeq ($(FULL_TARGET),z80-amstradcpc)
|
||||
override TARGET_LOADERS+=prt0
|
||||
endif
|
||||
override INSTALL_FPCPACKAGE=y
|
||||
ifeq ($(FULL_TARGET),i386-linux)
|
||||
override COMPILER_INCLUDEDIR+=$(INC) $(PROCINC)
|
||||
@ -2521,33 +2212,6 @@ else
|
||||
EXECPPAS:=@$(PPAS)
|
||||
endif
|
||||
endif
|
||||
.PHONY: fpc_loaders
|
||||
ifneq ($(TARGET_LOADERS),)
|
||||
override ALLTARGET+=fpc_loaders
|
||||
override CLEANTARGET+=fpc_loaders_clean
|
||||
override INSTALLTARGET+=fpc_loaders_install
|
||||
override LOADEROFILES:=$(addsuffix $(OEXT),$(TARGET_LOADERS))
|
||||
endif
|
||||
%$(OEXT): %$(LOADEREXT)
|
||||
ifdef COMPILER_UNITTARGETDIR
|
||||
$(AS) -o $(COMPILER_UNITTARGETDIR)/$*$(OEXT) $<
|
||||
else
|
||||
$(AS) -o $*$(OEXT) $<
|
||||
endif
|
||||
fpc_loaders: $(COMPILER_UNITTARGETDIR) $(LOADEROFILES)
|
||||
fpc_loaders_clean:
|
||||
ifdef COMPILER_UNITTARGETDIR
|
||||
-$(DEL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES))
|
||||
else
|
||||
-$(DEL) $(LOADEROFILES)
|
||||
endif
|
||||
fpc_loaders_install:
|
||||
$(MKDIR) $(INSTALL_UNITDIR)
|
||||
ifdef COMPILER_UNITTARGETDIR
|
||||
$(INSTALL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES)) $(INSTALL_UNITDIR)
|
||||
else
|
||||
$(INSTALL) $(LOADEROFILES) $(INSTALL_UNITDIR)
|
||||
endif
|
||||
.PHONY: fpc_units
|
||||
ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)
|
||||
override ALLTARGET+=fpc_units
|
||||
@ -2931,9 +2595,6 @@ SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
|
||||
include $(PROCINC)/makefile.cpu
|
||||
SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
|
||||
SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
|
||||
prt0$(OEXT) : prt0.asm
|
||||
$(MAKE) $(COMPILER_UNITTARGETDIR)
|
||||
sdasz80 -o $(UNITTARGETDIRPREFIX)prt0$(OEXT) prt0.asm
|
||||
system$(PPUEXT) : system.pp $(SYSDEPS)
|
||||
$(COMPILER) $(FPC_SYSTEM_OPT) -Us -Sg system.pp
|
||||
$(EXECPPAS)
|
||||
|
@ -4,7 +4,7 @@
|
||||
[package]
|
||||
main=rtl
|
||||
[target]
|
||||
loaders=prt0
|
||||
loaders=
|
||||
units=system si_prc
|
||||
|
||||
[require]
|
||||
@ -49,13 +49,7 @@ include $(PROCINC)/makefile.cpu
|
||||
SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
|
||||
# Put system unit dependencies together.
|
||||
SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
|
||||
#
|
||||
# Loaders
|
||||
#
|
||||
|
||||
prt0$(OEXT) : prt0.asm
|
||||
$(MAKE) $(COMPILER_UNITTARGETDIR)
|
||||
sdasz80 -o $(UNITTARGETDIRPREFIX)prt0$(OEXT) prt0.asm
|
||||
#
|
||||
# System Units (System, Objpas, Strings)
|
||||
#
|
||||
|
@ -1,10 +0,0 @@
|
||||
.area _CODE
|
||||
.globl PASCALMAIN
|
||||
.globl FPC_SAVE_IY
|
||||
.globl __fpc_stackarea_start
|
||||
.globl __fpc_stackarea_end
|
||||
|
||||
start::
|
||||
ld sp, #__fpc_stackarea_end
|
||||
ld (FPC_SAVE_IY), iy
|
||||
jp PASCALMAIN
|
40
tests/tbs/tb0677.pp
Normal file
40
tests/tbs/tb0677.pp
Normal file
@ -0,0 +1,40 @@
|
||||
{ %NORUN }
|
||||
|
||||
program tb0677;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
type
|
||||
TEnum = (eOne, eTwo, eThree, eFour);
|
||||
TSet = set of TEnum;
|
||||
|
||||
generic TTest<SetType, EnumType> = class
|
||||
procedure Test;
|
||||
end;
|
||||
|
||||
procedure TTest.Test;
|
||||
var
|
||||
s1: TSet;
|
||||
s2: SetType;
|
||||
e1: TEnum;
|
||||
e2: EnumType;
|
||||
begin
|
||||
Include(s1, e1);
|
||||
Exclude(s1, e1);
|
||||
|
||||
Include(s2, e1);
|
||||
Exclude(s2, e1);
|
||||
|
||||
Include(s2, e2);
|
||||
Exclude(s2, e2);
|
||||
|
||||
Include(s2, e1);
|
||||
Exclude(s2, e2);
|
||||
end;
|
||||
|
||||
type
|
||||
TTestTypes = specialize TTest<TSet, TEnum>;
|
||||
|
||||
begin
|
||||
|
||||
end.
|
26
tests/webtbs/tw37806.pp
Normal file
26
tests/webtbs/tw37806.pp
Normal file
@ -0,0 +1,26 @@
|
||||
program tw37806;
|
||||
|
||||
{$mode delphi}
|
||||
|
||||
procedure TurnSetElem<TSet, TElem>(var aSet: TSet; aElem: TElem; aOn: Boolean);
|
||||
begin
|
||||
if aOn then
|
||||
Include(aSet, aElem)
|
||||
else
|
||||
Exclude(aSet, aElem);
|
||||
end;
|
||||
|
||||
type
|
||||
TElem = (One, Two, Three, Four, Five);
|
||||
TSet = set of TElem;
|
||||
|
||||
var
|
||||
s: TSet = [];
|
||||
|
||||
begin
|
||||
TurnSetElem<TSet, TElem>(s, Two, True);
|
||||
TurnSetElem<TSet, TElem>(s, Five, True);
|
||||
if not((Two in s) and (Five in s)) then
|
||||
Halt(1);
|
||||
//WriteLn('does not work');
|
||||
end.
|
Loading…
Reference in New Issue
Block a user