Browse Source

*type symbol overloads are only allowed in mode Delphi
*a check for overloads with the same count of arguments is not yet in place
*in non-Delphi modes overloads need to be checked for non-generics as well, e.g. "TTest<T>" is already defined and now a "TTest" is declared
*when a generic is encountered and the symbol does not yet exist, a new symbol with an undefineddef is added and the generic def is added as an overload; if the symbol already exists, the generic is just added
*if a non-generic is parsed and the symbol is already defined (but the typedef is still an undefineddef) then the typedef is updated
*the symtable tree (up to the unit symtable (global or local)) gets the "sto_has_generic" flag which will be used when searching generics with the same name, but different parameter counts in different units

State of generics:
broken, because the generic defs are not yet searched/found

git-svn-id: branches/svenbarth/generics@17393 -

svenbarth 14 years ago
parent
commit
80100734c5
2 changed files with 51 additions and 6 deletions
  1. 48 5
      compiler/pdecl.pas
  2. 3 1
      compiler/symconst.pas

+ 48 - 5
compiler/pdecl.pas

@@ -408,6 +408,7 @@ implementation
          generictypelist : TFPObjectList;
          generictokenbuf : tdynamicarray;
          vmtbuilder : TVMTBuilder;
+         i : integer;
       begin
          old_block_type:=block_type;
          { save unit container of forward declarations -
@@ -471,6 +472,18 @@ implementation
             begin
               if (sym.typ=typesym) then
                begin
+                 if isgeneric then
+                   begin
+                     { overloading types is only allowed in mode Delphi }
+                     if not (m_delphi in current_settings.modeswitches) then
+                       Message1(sym_e_duplicate_id,orgtypename);
+                     for i:=0 to ttypesym(sym).gendeflist.Count-1 do
+                       { TODO : check whether the count of one of the defs is
+                                the same as that of the current declaration and
+                                print an error if so }
+                       ;
+                   end
+                 else
                  if ((token=_CLASS) or
                      (token=_INTERFACE) or
                      (token=_DISPINTERFACE) or
@@ -506,7 +519,12 @@ implementation
                     hdef:=newtype.typedef;
                   end
                  else
-                  message1(parser_h_type_redef,orgtypename);
+                 if not (m_delphi in current_settings.modeswitches) and
+                     (ttypesym(sym).typedef.typ=undefineddef) and
+                     (ttypesym(sym).gendeflist.Count>0) then
+                   message1(sym_e_duplicate_id,orgtypename)
+                 else
+                   message1(parser_h_type_redef,orgtypename);
                end;
             end;
            { no old type reused ? Then insert this new type }
@@ -517,9 +535,30 @@ implementation
                 will give an error (PFV) }
               hdef:=generrordef;
               storetokenpos:=current_tokenpos;
-              newtype:=ttypesym.create(orgtypename,hdef);
-              newtype.visibility:=symtablestack.top.currentvisibility;
-              symtablestack.top.insert(newtype);
+              if isgeneric then
+                begin
+                  if assigned(sym) then
+                    newtype:=ttypesym(sym)
+                  else
+                    begin
+                      { add the symbol with a undefineddef, so typesym can point
+                        to this symbol }
+                      newtype:=ttypesym.create(orgtypename,tundefineddef.create);
+                      newtype.typedef.typesym:=newtype;
+                      newtype.visibility:=symtablestack.top.currentvisibility;
+                      symtablestack.top.insert(newtype);
+                      newtype.typedef.owner:=newtype.owner;
+                    end;
+                end
+              else
+                if assigned(sym) then
+                  newtype:=ttypesym(sym)
+                else
+                  begin
+                    newtype:=ttypesym.create(orgtypename,hdef);
+                    newtype.visibility:=symtablestack.top.currentvisibility;
+                    symtablestack.top.insert(newtype);
+                  end;
               current_tokenpos:=defpos;
               current_tokenpos:=storetokenpos;
               { read the type definition }
@@ -554,7 +593,11 @@ implementation
                   if not assigned(hdef.typesym) then
                     hdef.typesym:=newtype;
                 end;
-              newtype.typedef:=hdef;
+              if isgeneric then begin
+                newtype.Owner.includeoption(sto_has_generic);
+                newtype.gendeflist.Add(hdef)
+              end else
+                newtype.typedef:=hdef;
               { KAZ: handle TGUID declaration in system unit }
               if (cs_compilesystem in current_settings.moduleswitches) and not assigned(rec_tguid) and
                  (typename='TGUID') and { name: TGUID and size=16 bytes that is 128 bits }

+ 3 - 1
compiler/symconst.pas

@@ -466,7 +466,9 @@ type
 
   { options for symtables }
   tsymtableoption = (
-    sto_has_helper         { contains at least one helper symbol }
+    sto_has_helper,        { contains at least one helper symbol }
+    sto_has_generic        { contains at least one symbol that is overloaded
+                             with generic defs }
   );
   tsymtableoptions = set of tsymtableoption;