浏览代码

Fix for Mantis #22428.

* pgenutil.pas, generate_specialization:
  * return a generrordef instead of Nil when returning because of an error
  * always check "genname" for a generic count string as a mode ObjFPC generic specialized in a mode Delphi unit will already contain a "$X" suffix and only symname will be set.
+ add (corrected) test

git-svn-id: trunk@22462 -
svenbarth 13 年之前
父节点
当前提交
54c1e638ad
共有 4 个文件被更改,包括 62 次插入5 次删除
  1. 2 0
      .gitattributes
  2. 26 5
      compiler/pgenutil.pas
  3. 14 0
      tests/webtbs/tw22428.pp
  4. 20 0
      tests/webtbs/uw22428.pp

+ 2 - 0
.gitattributes

@@ -12857,6 +12857,7 @@ tests/webtbs/tw22331.pp svneol=native#text/plain
 tests/webtbs/tw22344.pp svneol=native#text/plain
 tests/webtbs/tw22344.pp svneol=native#text/plain
 tests/webtbs/tw2242.pp svneol=native#text/plain
 tests/webtbs/tw2242.pp svneol=native#text/plain
 tests/webtbs/tw22427.pp svneol=native#text/pascal
 tests/webtbs/tw22427.pp svneol=native#text/pascal
+tests/webtbs/tw22428.pp svneol=native#text/pascal
 tests/webtbs/tw22490.pp svneol=native#text/plain
 tests/webtbs/tw22490.pp svneol=native#text/plain
 tests/webtbs/tw2250.pp svneol=native#text/plain
 tests/webtbs/tw2250.pp svneol=native#text/plain
 tests/webtbs/tw22502.pp svneol=native#text/plain
 tests/webtbs/tw22502.pp svneol=native#text/plain
@@ -13676,6 +13677,7 @@ tests/webtbs/uw22160b2.pp svneol=native#text/pascal
 tests/webtbs/uw22160b3.pp svneol=native#text/pascal
 tests/webtbs/uw22160b3.pp svneol=native#text/pascal
 tests/webtbs/uw22427a.pp svneol=native#text/pascal
 tests/webtbs/uw22427a.pp svneol=native#text/pascal
 tests/webtbs/uw22427b.pp svneol=native#text/pascal
 tests/webtbs/uw22427b.pp svneol=native#text/pascal
+tests/webtbs/uw22428.pp svneol=native#text/pascal
 tests/webtbs/uw2266a.inc svneol=native#text/plain
 tests/webtbs/uw2266a.inc svneol=native#text/plain
 tests/webtbs/uw2266b.pas svneol=native#text/plain
 tests/webtbs/uw2266b.pas svneol=native#text/plain
 tests/webtbs/uw2269.inc svneol=native#text/plain
 tests/webtbs/uw2269.inc svneol=native#text/plain

+ 26 - 5
compiler/pgenutil.pas

@@ -105,6 +105,7 @@ uses
         found,
         found,
         first,
         first,
         err : boolean;
         err : boolean;
+        errval,
         i,
         i,
         gencount : longint;
         gencount : longint;
         crc : cardinal;
         crc : cardinal;
@@ -198,6 +199,7 @@ uses
                           (srsym.typ<>typesym) then
                           (srsym.typ<>typesym) then
                         begin
                         begin
                           identifier_not_found(genname);
                           identifier_not_found(genname);
+                          tt:=generrordef;
                           exit;
                           exit;
                         end;
                         end;
                       tt:=ttypesym(srsym).typedef;
                       tt:=ttypesym(srsym).typedef;
@@ -224,18 +226,17 @@ uses
         if err then
         if err then
           begin
           begin
             try_to_consume(_RSHARPBRACKET);
             try_to_consume(_RSHARPBRACKET);
+            tt:=generrordef;
             exit;
             exit;
           end;
           end;
 
 
-        { search a generic with the given count of params }
-        countstr:='';
-        str(genericdeflist.Count,countstr);
         { use the name of the symbol as procvars return a user friendly version
         { use the name of the symbol as procvars return a user friendly version
           of the name }
           of the name }
         if symname='' then
         if symname='' then
           genname:=ttypesym(genericdef.typesym).realname
           genname:=ttypesym(genericdef.typesym).realname
         else
         else
           genname:=symname;
           genname:=symname;
+
         { in case of non-Delphi mode the type name could already be a generic
         { in case of non-Delphi mode the type name could already be a generic
           def (but maybe the wrong one) }
           def (but maybe the wrong one) }
         if assigned(genericdef) and
         if assigned(genericdef) and
@@ -257,7 +258,27 @@ uses
                     genname:=copy(genname,1,i-1);
                     genname:=copy(genname,1,i-1);
                     break;
                     break;
                   end;
                   end;
-          end;
+          end
+        else
+          { search for a potential suffix }
+          for i:=length(genname) downto 1 do
+            if genname[i]='$' then
+              begin
+                { if the part right of the $ is a number we assume that the left
+                  part is the name of the generic, otherwise we assume that the
+                  complete name is the name of the generic }
+                countstr:=copy(genname,i+1,length(genname)-i);
+                gencount:=0;
+                val(countstr,gencount,errval);
+                if errval=0 then
+                  genname:=copy(genname,1,i-1);
+                break;
+              end;
+
+        { search a generic with the given count of params }
+        countstr:='';
+        str(genericdeflist.Count,countstr);
+
         genname:=genname+'$'+countstr;
         genname:=genname+'$'+countstr;
         ugenname:=upper(genname);
         ugenname:=upper(genname);
 
 
@@ -276,6 +297,7 @@ uses
             identifier_not_found(genname);
             identifier_not_found(genname);
             genericdeflist.Free;
             genericdeflist.Free;
             generictypelist.Free;
             generictypelist.Free;
+            tt:=generrordef;
             exit;
             exit;
           end;
           end;
 
 
@@ -317,7 +339,6 @@ uses
               end;
               end;
           end;
           end;
 
 
-
         { Special case if we are referencing the current defined object }
         { Special case if we are referencing the current defined object }
         if assigned(current_structdef) and
         if assigned(current_structdef) and
            (current_structdef.objname^=ufinalspecializename) then
            (current_structdef.objname^=ufinalspecializename) then

+ 14 - 0
tests/webtbs/tw22428.pp

@@ -0,0 +1,14 @@
+unit tw22428;
+
+{$MODE DELPHI}
+
+interface
+
+uses uw22428;
+
+implementation
+
+initialization
+  TWrapper<Byte>.Test;
+
+end.

+ 20 - 0
tests/webtbs/uw22428.pp

@@ -0,0 +1,20 @@
+unit uw22428;
+
+{$MODE OBJFPC}
+{$modeswitch advancedrecords}
+
+interface
+
+type
+  generic TWrapper<T> = record
+    class procedure Test; static;
+  end;
+
+implementation
+
+class procedure TWrapper.Test;
+begin
+
+end;
+
+end.