* Delphi does not allow a generic method to be overloaded by a non generic type of the same name (unlike for generic types and non generic routines); this is probably done to simplify the implementation of implicit specializations of generic methods so we do this as well. For this we change the dummy symbol for generic routines from a typesym to a procsym

+ added tests

Note: what Delphi /does/ allow however is to overload a generic routine with a generic type... go figure. :/ We currently don't allow that

git-svn-id: trunk@48002 -
This commit is contained in:
svenbarth 2021-01-02 23:23:39 +00:00
parent 7343e9c4a2
commit c96029ebd5
6 changed files with 114 additions and 3 deletions

4
.gitattributes vendored
View File

@ -15181,6 +15181,10 @@ tests/test/tgenfunc20.pp svneol=native#text/pascal
tests/test/tgenfunc21.pp svneol=native#text/pascal
tests/test/tgenfunc22.pp svneol=native#text/pascal
tests/test/tgenfunc23.pp svneol=native#text/pascal
tests/test/tgenfunc24.pp svneol=native#text/pascal
tests/test/tgenfunc25.pp svneol=native#text/pascal
tests/test/tgenfunc26.pp svneol=native#text/pascal
tests/test/tgenfunc27.pp svneol=native#text/pascal
tests/test/tgenfunc3.pp svneol=native#text/pascal
tests/test/tgenfunc4.pp svneol=native#text/pascal
tests/test/tgenfunc5.pp svneol=native#text/pascal

View File

@ -1066,7 +1066,8 @@ implementation
end
else if (srsym.typ=typesym) and
(sp_generic_dummy in srsym.symoptions) and
(ttypesym(srsym).typedef.typ=undefineddef) then
(ttypesym(srsym).typedef.typ=undefineddef) and
not assigned(genericparams) then
begin
{ this is a generic dummy symbol that has not yet
been used; so we rename the dummy symbol and continue
@ -1162,12 +1163,21 @@ implementation
end;
if not assigned(dummysym) then
begin
dummysym:=ctypesym.create(orgspnongen,cundefineddef.create(true));
{ overloading generic routines with non-generic types is not
allowed, so we create a procsym as dummy }
dummysym:=cprocsym.create(orgspnongen);
if assigned(astruct) then
astruct.symtable.insert(dummysym)
else
symtablestack.top.insert(dummysym);
end;
end
else if (dummysym.typ<>procsym) and
(
{ show error only for the declaration, not also the implementation }
not assigned(astruct) or
(symtablestack.top.symtablelevel<>main_program_level)
) then
Message1(sym_e_duplicate_id,dummysym.realname);
if not (sp_generic_dummy in dummysym.symoptions) then
begin
include(dummysym.symoptions,sp_generic_dummy);

25
tests/test/tgenfunc24.pp Normal file
View File

@ -0,0 +1,25 @@
{ %FAIL }
program tgenfunc24;
{$mode delphi}
type
TTest = class
public type
Test = class
end;
public
procedure Test<T>;
end;
procedure TTest.Test<T>;
begin
end;
begin
end.

24
tests/test/tgenfunc25.pp Normal file
View File

@ -0,0 +1,24 @@
{ %FAIL }
program tgenfunc25;
{$mode delphi}
type
TTest = class
public
procedure Test<T>;
public type
Test = class
end;
end;
procedure TTest.Test<T>;
begin
end;
begin
end.

24
tests/test/tgenfunc26.pp Normal file
View File

@ -0,0 +1,24 @@
{ %FAIL }
unit tgenfunc26;
{$mode objfpc}{$H+}
interface
generic procedure Test<T>;
type
Test = record
end;
implementation
generic procedure Test<T>;
begin
end;
end.

24
tests/test/tgenfunc27.pp Normal file
View File

@ -0,0 +1,24 @@
{ %FAIL }
unit tgenfunc27;
{$mode objfpc}{$H+}
interface
type
Test = record
end;
generic procedure Test<T>;
implementation
generic procedure Test<T>;
begin
end;
end.