Преглед изворни кода

* 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 -

svenbarth пре 4 година
родитељ
комит
c96029ebd5
6 измењених фајлова са 114 додато и 3 уклоњено
  1. 4 0
      .gitattributes
  2. 13 3
      compiler/pdecsub.pas
  3. 25 0
      tests/test/tgenfunc24.pp
  4. 24 0
      tests/test/tgenfunc25.pp
  5. 24 0
      tests/test/tgenfunc26.pp
  6. 24 0
      tests/test/tgenfunc27.pp

+ 4 - 0
.gitattributes

@@ -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

+ 13 - 3
compiler/pdecsub.pas

@@ -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 - 0
tests/test/tgenfunc24.pp

@@ -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 - 0
tests/test/tgenfunc25.pp

@@ -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 - 0
tests/test/tgenfunc26.pp

@@ -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 - 0
tests/test/tgenfunc27.pp

@@ -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.
+